mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-14 20:22:00 +00:00
Merge mozilla-central and b2g-inbound
This commit is contained in:
commit
d791ee02f0
@ -19,11 +19,11 @@
|
||||
<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="857129928b6e56a809cee9d5445effb8fa9f1c2c"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="637213e32deb42b051acf6e47755518a8baad34c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8e4420c0c5c8e8c8e58a000278a7129403769f96"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9100fa82fc355f5201e23e400fc6b40e875304ed"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="a819a94a572c7b32556435491ed8eaab841a95ff"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89812422efe8df364ddf364b4740030496181277"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="857129928b6e56a809cee9d5445effb8fa9f1c2c"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="637213e32deb42b051acf6e47755518a8baad34c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89812422efe8df364ddf364b4740030496181277"/>
|
||||
@ -126,11 +126,11 @@
|
||||
<!-- Emulator specific things -->
|
||||
<project name="android-development" path="development" remote="b2g" revision="dab55669da8f48b6e57df95d5af9f16b4a87b0b1"/>
|
||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
|
||||
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="c3ee0c875393607430086f942950d1b3f496ab0e"/>
|
||||
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="0e31f35a2a77301e91baa8a237aa9e9fa4076084"/>
|
||||
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="0a2b7e94dce4989a3740fea6f6e3152978216c88"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="cba8ebe395652e62a911d885cd6ac1bb4ad3ed57"/>
|
||||
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="dd94b2e17a146cb782d71933d25dcaa9c060e6ce"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="832f4acaf481a19031e479a40b03d9ce5370ddee"/>
|
||||
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d0aa65b140a45016975ed0ecf35f280dd336e1d3"/>
|
||||
<project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
|
||||
</manifest>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="857129928b6e56a809cee9d5445effb8fa9f1c2c"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="637213e32deb42b051acf6e47755518a8baad34c"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -19,11 +19,11 @@
|
||||
<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="857129928b6e56a809cee9d5445effb8fa9f1c2c"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="637213e32deb42b051acf6e47755518a8baad34c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="8e4420c0c5c8e8c8e58a000278a7129403769f96"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="9100fa82fc355f5201e23e400fc6b40e875304ed"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="a819a94a572c7b32556435491ed8eaab841a95ff"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89812422efe8df364ddf364b4740030496181277"/>
|
||||
<!-- Stock Android things -->
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="857129928b6e56a809cee9d5445effb8fa9f1c2c"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="637213e32deb42b051acf6e47755518a8baad34c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89812422efe8df364ddf364b4740030496181277"/>
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "e32dee285e41ff8be7779ab4adb3db81a5b36570",
|
||||
"revision": "b8a669ee022fc969ec2e2fd8fc10575d14364bcb",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="857129928b6e56a809cee9d5445effb8fa9f1c2c"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="637213e32deb42b051acf6e47755518a8baad34c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="857129928b6e56a809cee9d5445effb8fa9f1c2c"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="637213e32deb42b051acf6e47755518a8baad34c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="857129928b6e56a809cee9d5445effb8fa9f1c2c"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="637213e32deb42b051acf6e47755518a8baad34c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="89812422efe8df364ddf364b4740030496181277"/>
|
||||
|
@ -17,7 +17,7 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="857129928b6e56a809cee9d5445effb8fa9f1c2c"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="637213e32deb42b051acf6e47755518a8baad34c"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="531cf670e485649c69746e46d567929fcd54cbc5"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -3436,14 +3436,13 @@ BluetoothDBusService::ToggleCalls(BluetoothReplyRunnable* aRunnable)
|
||||
class OnUpdateSdpRecordsRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
OnUpdateSdpRecordsRunnable(const nsAString& aObjectPath,
|
||||
OnUpdateSdpRecordsRunnable(const nsAString& aDeviceAddress,
|
||||
BluetoothProfileManagerBase* aManager)
|
||||
: mManager(aManager)
|
||||
: mDeviceAddress(aDeviceAddress)
|
||||
, mManager(aManager)
|
||||
{
|
||||
MOZ_ASSERT(!aObjectPath.IsEmpty());
|
||||
MOZ_ASSERT(!aDeviceAddress.IsEmpty());
|
||||
MOZ_ASSERT(aManager);
|
||||
|
||||
mDeviceAddress = GetAddressFromObjectPath(aObjectPath);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -3456,6 +3455,12 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GetDeviceAddress(nsAString& aRetDeviceAddress)
|
||||
{
|
||||
aRetDeviceAddress = mDeviceAddress;
|
||||
}
|
||||
|
||||
private:
|
||||
nsString mDeviceAddress;
|
||||
BluetoothProfileManagerBase* mManager;
|
||||
@ -3641,31 +3646,74 @@ public:
|
||||
MOZ_ASSERT(sDBusConnection);
|
||||
MOZ_ASSERT(!sAdapterPath.IsEmpty());
|
||||
|
||||
const nsString objectPath =
|
||||
GetObjectPathFromAddress(sAdapterPath, mDeviceAddress);
|
||||
// We first guess that the device doesn't exist at all. So we use BlueZ
|
||||
// API "CreateDevice" to create an object path for the BluetoothDevice
|
||||
// object. "CreateDevice" will connect to the remote device and retrieve
|
||||
// SDP records of the target.
|
||||
NS_ConvertUTF16toUTF8 address(mDeviceAddress);
|
||||
const char* cAddress = address.get();
|
||||
|
||||
// I choose to use raw pointer here because this is going to be passed as an
|
||||
// argument into SendWithReply() at once.
|
||||
OnUpdateSdpRecordsRunnable* callbackRunnable =
|
||||
new OnUpdateSdpRecordsRunnable(objectPath, mBluetoothProfileManager);
|
||||
new OnUpdateSdpRecordsRunnable(mDeviceAddress, mBluetoothProfileManager);
|
||||
|
||||
sDBusConnection->SendWithReply(DiscoverServicesCallback,
|
||||
(void*)callbackRunnable, -1,
|
||||
BLUEZ_DBUS_BASE_IFC,
|
||||
NS_ConvertUTF16toUTF8(objectPath).get(),
|
||||
DBUS_DEVICE_IFACE,
|
||||
"DiscoverServices",
|
||||
DBUS_TYPE_STRING, &EmptyCString(),
|
||||
DBUS_TYPE_INVALID);
|
||||
sDBusConnection->SendWithReply(
|
||||
CreateDeviceCallback, callbackRunnable, -1,
|
||||
BLUEZ_DBUS_BASE_IFC,
|
||||
NS_ConvertUTF16toUTF8(sAdapterPath).get(),
|
||||
DBUS_ADAPTER_IFACE,
|
||||
"CreateDevice",
|
||||
DBUS_TYPE_STRING, &cAddress,
|
||||
DBUS_TYPE_INVALID);
|
||||
}
|
||||
|
||||
protected:
|
||||
static void CreateDeviceCallback(DBusMessage* aMsg, void* aData)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
|
||||
|
||||
nsAutoString errorString;
|
||||
OnUpdateSdpRecordsRunnable* r =
|
||||
static_cast<OnUpdateSdpRecordsRunnable*>(aData);
|
||||
|
||||
if (IsDBusMessageError(aMsg, nullptr, errorString)) {
|
||||
// If the device already exists it comes here. If we want to refresh its
|
||||
// SDP records then we have to do "DiscoverServices"
|
||||
BT_LOGR("%s", NS_ConvertUTF16toUTF8(errorString).get());
|
||||
|
||||
nsString deviceAddress;
|
||||
r->GetDeviceAddress(deviceAddress);
|
||||
|
||||
const nsString objectPath =
|
||||
GetObjectPathFromAddress(sAdapterPath, deviceAddress);
|
||||
|
||||
sDBusConnection->SendWithReply(DiscoverServicesCallback,
|
||||
aData, -1,
|
||||
BLUEZ_DBUS_BASE_IFC,
|
||||
NS_ConvertUTF16toUTF8(objectPath).get(),
|
||||
DBUS_DEVICE_IFACE,
|
||||
"DiscoverServices",
|
||||
DBUS_TYPE_STRING, &EmptyCString(),
|
||||
DBUS_TYPE_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
static void DiscoverServicesCallback(DBusMessage* aMsg, void* aData)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
|
||||
|
||||
nsRefPtr<OnUpdateSdpRecordsRunnable> r(
|
||||
static_cast<OnUpdateSdpRecordsRunnable*>(aData));
|
||||
nsAutoString errorStr;
|
||||
|
||||
if (IsDBusMessageError(aMsg, nullptr, errorStr)) {
|
||||
BT_LOGR("%s", NS_ConvertUTF16toUTF8(errorStr).get());
|
||||
}
|
||||
|
||||
OnUpdateSdpRecordsRunnable* r =
|
||||
static_cast<OnUpdateSdpRecordsRunnable*>(aData);
|
||||
NS_DispatchToMainThread(r);
|
||||
}
|
||||
|
||||
@ -3680,8 +3728,7 @@ BluetoothDBusService::UpdateSdpRecords(const nsAString& aDeviceAddress,
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
Task* task = new UpdateSdpRecordsTask(aDeviceAddress, aManager);
|
||||
DispatchToDBusThread(task);
|
||||
DispatchToDBusThread(new UpdateSdpRecordsTask(aDeviceAddress, aManager));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 et filetype=javascript
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* 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/. */
|
||||
|
||||
@ -36,7 +34,14 @@ const BDADDR_ALL = "ff:ff:ff:ff:ff:ff";
|
||||
const BDADDR_LOCAL = "ff:ff:ff:00:00:00";
|
||||
|
||||
// A user friendly name for remote BT device.
|
||||
const REMOTE_DEVICE_NAME = "Remote BT Device";
|
||||
const REMOTE_DEVICE_NAME = "Remote_BT_Device";
|
||||
|
||||
// A system message signature of pairing request event
|
||||
const BT_PAIRING_REQ = "bluetooth-pairing-request";
|
||||
|
||||
// Passkey and pincode used to reply pairing requst
|
||||
const BT_PAIRING_PASSKEY = 123456;
|
||||
const BT_PAIRING_PINCODE = "ABCDEFG";
|
||||
|
||||
let Promise =
|
||||
SpecialPowers.Cu.import("resource://gre/modules/Promise.jsm").Promise;
|
||||
@ -80,6 +85,33 @@ function runEmulatorCmdSafe(aCommand) {
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap DOMRequest onsuccess/onerror events to Promise resolve/reject.
|
||||
*
|
||||
* Fulfill params: A DOMEvent.
|
||||
* Reject params: A DOMEvent.
|
||||
*
|
||||
* @param aRequest
|
||||
* A DOMRequest instance.
|
||||
*
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function wrapDomRequestAsPromise(aRequest) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
ok(aRequest instanceof DOMRequest,
|
||||
"aRequest is instanceof " + aRequest.constructor);
|
||||
|
||||
aRequest.onsuccess = function(aEvent) {
|
||||
deferred.resolve(aEvent);
|
||||
};
|
||||
aRequest.onerror = function(aEvent) {
|
||||
deferred.reject(aEvent);
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Bluetooth remote device to scatternet and set its properties.
|
||||
*
|
||||
@ -188,13 +220,11 @@ function setEmulatorDeviceProperty(aAddress, aPropertyName, aValue) {
|
||||
function getEmulatorDeviceProperty(aAddress, aPropertyName) {
|
||||
let cmd = "bt property " + aAddress + " " + aPropertyName;
|
||||
return runEmulatorCmdSafe(cmd)
|
||||
.then(function(aResults) {
|
||||
return aResults[0];
|
||||
});
|
||||
.then(aResults => aResults[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start dicovering Bluetooth devices.
|
||||
* Start discovering Bluetooth devices.
|
||||
*
|
||||
* Allows the device's adapter to start seeking for remote devices.
|
||||
*
|
||||
@ -202,32 +232,28 @@ function getEmulatorDeviceProperty(aAddress, aPropertyName) {
|
||||
* Reject params: a DOMError
|
||||
*
|
||||
* @param aAdapter
|
||||
* A BluetoothAdapter which is used to interact with local BT dev
|
||||
* A BluetoothAdapter which is used to interact with local BT device.
|
||||
*
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function startDiscovery(aAdapter) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let request = aAdapter.startDiscovery();
|
||||
request.onsuccess = function () {
|
||||
log(" Start discovery - Success");
|
||||
// TODO (bug 892207): Make Bluetooth APIs available for 3rd party apps.
|
||||
// Currently, discovering state wouldn't change immediately here.
|
||||
// We would turn on this check when the redesigned API are landed.
|
||||
// is(aAdapter.discovering, true, "BluetoothAdapter.discovering");
|
||||
deferred.resolve();
|
||||
}
|
||||
request.onerror = function (aEvent) {
|
||||
ok(false, "Start discovery - Fail");
|
||||
deferred.reject(aEvent.target.error);
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
return wrapDomRequestAsPromise(request)
|
||||
.then(function resolve() {
|
||||
// TODO (bug 892207): Make Bluetooth APIs available for 3rd party apps.
|
||||
// Currently, discovering state wouldn't change immediately here.
|
||||
// We would turn on this check when the redesigned API are landed.
|
||||
// is(aAdapter.discovering, false, "BluetoothAdapter.discovering");
|
||||
log(" Start discovery - Success");
|
||||
}, function reject(aEvent) {
|
||||
ok(false, "Start discovery - Fail");
|
||||
throw aEvent.target.error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop dicovering Bluetooth devices.
|
||||
* Stop discovering Bluetooth devices.
|
||||
*
|
||||
* Allows the device's adapter to stop seeking for remote devices.
|
||||
*
|
||||
@ -240,24 +266,184 @@ function startDiscovery(aAdapter) {
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function stopDiscovery(aAdapter) {
|
||||
let request = aAdapter.stopDiscovery();
|
||||
|
||||
return wrapDomRequestAsPromise(request)
|
||||
.then(function resolve() {
|
||||
// TODO (bug 892207): Make Bluetooth APIs available for 3rd party apps.
|
||||
// Currently, discovering state wouldn't change immediately here.
|
||||
// We would turn on this check when the redesigned API are landed.
|
||||
// is(aAdapter.discovering, false, "BluetoothAdapter.discovering");
|
||||
log(" Stop discovery - Success");
|
||||
}, function reject(aEvent) {
|
||||
ok(false, "Stop discovery - Fail");
|
||||
throw aEvent.target.error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for 'devicefound' event of specified devices.
|
||||
*
|
||||
* Resolve if that every specified devices has been found. Never reject.
|
||||
*
|
||||
* Fulfill params: an array which contains addresses of remote devices.
|
||||
*
|
||||
* @param aAdapter
|
||||
* A BluetoothAdapter which is used to interact with local BT device.
|
||||
* @param aRemoteAddresses
|
||||
* An array which contains addresses of remote devices.
|
||||
*
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function waitForDevicesFound(aAdapter, aRemoteAddresses) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let request = aAdapter.stopDiscovery();
|
||||
request.onsuccess = function () {
|
||||
log(" Stop discovery - Success");
|
||||
// TODO (bug 892207): Make Bluetooth APIs available for 3rd party apps.
|
||||
// Currently, discovering state wouldn't change immediately here.
|
||||
// We would turn on this check when the redesigned API are landed.
|
||||
// is(aAdapter.discovering, false, "BluetoothAdapter.discovering");
|
||||
deferred.resolve();
|
||||
}
|
||||
request.onerror = function (aEvent) {
|
||||
ok(false, "Stop discovery - Fail");
|
||||
deferred.reject(aEvent.target.error);
|
||||
}
|
||||
var addrArray = [];
|
||||
aAdapter.addEventListener("devicefound", function onevent(aEvent) {
|
||||
if(aRemoteAddresses.indexOf(aEvent.device.address) != -1) {
|
||||
addrArray.push(aEvent.device.address);
|
||||
}
|
||||
if(addrArray.length == aRemoteAddresses.length) {
|
||||
aAdapter.removeEventListener("devicefound", onevent);
|
||||
ok(true, "BluetoothAdapter has found all remote devices.");
|
||||
|
||||
deferred.resolve(addrArray);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start discovering Bluetooth devices and wait for 'devicefound' events.
|
||||
*
|
||||
* Allows the device's adapter to start seeking for remote devices and wait for
|
||||
* the 'devicefound' events of specified devices.
|
||||
*
|
||||
* Fulfill params: an array of addresses of found devices.
|
||||
*
|
||||
* @param aAdapter
|
||||
* A BluetoothAdapter which is used to interact with local BT device.
|
||||
* @param aRemoteAddresses
|
||||
* An array which contains addresses of remote devices.
|
||||
*
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function startDiscoveryAndWaitDevicesFound(aAdapter, aRemoteAddresses) {
|
||||
let promises = [];
|
||||
|
||||
promises.push(waitForDevicesFound(aAdapter, aRemoteAddresses));
|
||||
promises.push(startDiscovery(aAdapter));
|
||||
return Promise.all(promises)
|
||||
.then(aResults => aResults[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start pairing a remote device.
|
||||
*
|
||||
* Start pairing a remote device with the device's adapter.
|
||||
*
|
||||
* Fulfill params: (none)
|
||||
* Reject params: a DOMError
|
||||
*
|
||||
* @param aAdapter
|
||||
* A BluetoothAdapter which is used to interact with local BT device.
|
||||
* @param aDeviceAddress
|
||||
* The string of remote Bluetooth address with format xx:xx:xx:xx:xx:xx.
|
||||
*
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function pair(aAdapter, aDeviceAddress) {
|
||||
let request = aAdapter.pair(aDeviceAddress);
|
||||
|
||||
return wrapDomRequestAsPromise(request)
|
||||
.then(function resolve() {
|
||||
log(" Pair - Success");
|
||||
}, function reject(aEvent) {
|
||||
ok(false, "Pair - Fail");
|
||||
throw aEvent.target.error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the paired device from the paired device list.
|
||||
*
|
||||
* Remove the paired device from the paired device list of the device's adapter.
|
||||
*
|
||||
* Fulfill params: (none)
|
||||
* Reject params: a DOMError
|
||||
*
|
||||
* @param aAdapter
|
||||
* A BluetoothAdapter which is used to interact with local BT device.
|
||||
* @param aDeviceAddress
|
||||
* The string of remote Bluetooth address with format xx:xx:xx:xx:xx:xx.
|
||||
*
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function unpair(aAdapter, aDeviceAddress) {
|
||||
let request = aAdapter.unpair(aDeviceAddress);
|
||||
|
||||
return wrapDomRequestAsPromise(request)
|
||||
.then(function resolve() {
|
||||
log(" Unpair - Success");
|
||||
}, function reject(aEvent) {
|
||||
ok(false, "Unpair - Fail");
|
||||
throw aEvent.target.error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Start pairing a remote device and wait for "pairedstatuschanged" event.
|
||||
*
|
||||
* Start pairing a remote device with the device's adapter and wait for
|
||||
* "pairedstatuschanged" event.
|
||||
*
|
||||
* Fulfill params: an array of promise results contains the fulfilled params of
|
||||
* 'waitForAdapterEvent' and 'pair'.
|
||||
*
|
||||
* @param aAdapter
|
||||
* A BluetoothAdapter which is used to interact with local BT device.
|
||||
* @param aDeviceAddress
|
||||
* The string of remote Bluetooth address with format xx:xx:xx:xx:xx:xx.
|
||||
*
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function pairDeviceAndWait(aAdapter, aDeviceAddress) {
|
||||
let promises = [];
|
||||
promises.push(waitForAdapterEvent(aAdapter, "pairedstatuschanged"));
|
||||
promises.push(pair(aAdapter, aDeviceAddress));
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get paried Bluetooth devices.
|
||||
*
|
||||
* The getPairedDevices method is used to retrieve the full list of all devices
|
||||
* paired with the device's adapter.
|
||||
*
|
||||
* Fulfill params: a shallow copy of the Array of paired BluetoothDevice
|
||||
* objects.
|
||||
* Reject params: a DOMError
|
||||
*
|
||||
* @param aAdapter
|
||||
* A BluetoothAdapter which is used to interact with local BT device.
|
||||
*
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function getPairedDevices(aAdapter) {
|
||||
let request = aAdapter.getPairedDevices();
|
||||
|
||||
return wrapDomRequestAsPromise(request)
|
||||
.then(function resolve() {
|
||||
log(" getPairedDevices - Success");
|
||||
let pairedDevices = request.result.slice();
|
||||
return pairedDevices;
|
||||
}, function reject(aEvent) {
|
||||
ok(false, "getPairedDevices - Fail");
|
||||
throw aEvent.target.error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mozSettings value specified by @aKey.
|
||||
*
|
||||
@ -274,19 +460,16 @@ function stopDiscovery(aAdapter) {
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function getSettings(aKey) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let request = navigator.mozSettings.createLock().get(aKey);
|
||||
request.addEventListener("success", function(aEvent) {
|
||||
ok(true, "getSettings(" + aKey + ")");
|
||||
deferred.resolve(aEvent.target.result[aKey]);
|
||||
});
|
||||
request.addEventListener("error", function() {
|
||||
ok(false, "getSettings(" + aKey + ")");
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
return wrapDomRequestAsPromise(request)
|
||||
.then(function resolve(aEvent) {
|
||||
ok(true, "getSettings(" + aKey + ")");
|
||||
return aEvent.target.result[aKey];
|
||||
}, function reject(aEvent) {
|
||||
ok(false, "getSettings(" + aKey + ")");
|
||||
throw aEvent.target.error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -303,19 +486,15 @@ function getSettings(aKey) {
|
||||
* @return A deferred promise.
|
||||
*/
|
||||
function setSettings(aSettings) {
|
||||
let deferred = Promise.defer();
|
||||
|
||||
let request = navigator.mozSettings.createLock().set(aSettings);
|
||||
request.addEventListener("success", function() {
|
||||
ok(true, "setSettings(" + JSON.stringify(aSettings) + ")");
|
||||
deferred.resolve();
|
||||
});
|
||||
request.addEventListener("error", function() {
|
||||
ok(false, "setSettings(" + JSON.stringify(aSettings) + ")");
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
return wrapDomRequestAsPromise(request)
|
||||
.then(function resolve() {
|
||||
ok(true, "setSettings(" + JSON.stringify(aSettings) + ")");
|
||||
}, function reject(aEvent) {
|
||||
ok(false, "setSettings(" + JSON.stringify(aSettings) + ")");
|
||||
throw aEvent.target.error;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -438,7 +617,7 @@ function waitForManagerEvent(aEventName) {
|
||||
* Fulfill params: the DOMEvent passed.
|
||||
*
|
||||
* @param aAdapter
|
||||
* The BluetoothAdapter you want to use.
|
||||
* A BluetoothAdapter which is used to interact with local BT device.
|
||||
* @param aEventName
|
||||
* The name of the EventHandler.
|
||||
*
|
||||
@ -463,7 +642,8 @@ function waitForAdapterEvent(aAdapter, aEventName) {
|
||||
*
|
||||
* Resolve if that named event occurs. Reject if we can't set settings.
|
||||
*
|
||||
* Fulfill params: the DOMEvent passed.
|
||||
* Fulfill params: an array of promise results contains the fulfill params of
|
||||
* 'waitForManagerEvent' and 'setBluetoothEnabled'.
|
||||
* Reject params: (none)
|
||||
*
|
||||
* @return A deferred promise.
|
||||
|
@ -3,8 +3,10 @@ b2g = true
|
||||
browser = false
|
||||
qemu = true
|
||||
|
||||
[test_navigate_to_default_url.py]
|
||||
[test_dom_BluetoothManager_enabled.js]
|
||||
[test_dom_BluetoothManager_adapteradded.js]
|
||||
[test_dom_BluetoothAdapter_setters.js]
|
||||
[test_dom_BluetoothAdapter_getters.js]
|
||||
[test_dom_BluetoothAdapter_discovery.js]
|
||||
[test_dom_BluetoothAdapter_pair.js]
|
||||
|
@ -1,13 +1,11 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 et filetype=javascript
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Test Purpose:
|
||||
// To verify that discovery process of BluetoothAdapter is correct.
|
||||
// Use B2G emulator commands to add/remote remote devices to simulate
|
||||
// Use B2G emulator commands to add/remove remote devices to simulate
|
||||
// discovering behavior.
|
||||
//
|
||||
// Test Coverage:
|
||||
@ -24,15 +22,9 @@ MARIONETTE_HEAD_JS = 'head.js';
|
||||
startBluetoothTest(true, function testCaseMain(aAdapter) {
|
||||
log("Testing the discovery process of BluetoothAdapter ...");
|
||||
|
||||
// The properties of remote device.
|
||||
let theProperties = {
|
||||
"name": REMOTE_DEVICE_NAME,
|
||||
"discoverable": true
|
||||
};
|
||||
|
||||
return Promise.resolve()
|
||||
.then(() => removeEmulatorRemoteDevice(BDADDR_ALL))
|
||||
.then(() => addEmulatorRemoteDevice(/*theProperties*/ null))
|
||||
.then(() => addEmulatorRemoteDevice(null))
|
||||
.then(function(aRemoteAddress) {
|
||||
let promises = [];
|
||||
promises.push(waitForAdapterEvent(aAdapter, "devicefound"));
|
||||
|
@ -1,6 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 et filetype=javascript
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* 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/. */
|
||||
|
||||
|
@ -0,0 +1,66 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Test Purpose:
|
||||
// To verify that pairing process of BluetoothAdapter is correct.
|
||||
// Use B2G emulator commands to add/remove remote devices to simulate
|
||||
// discovering behavior. With current emulator implemation, the pair method
|
||||
// between adapter and remote device would be 'confirmation'.
|
||||
//
|
||||
// Test Coverage:
|
||||
// - BluetoothAdapter.startDiscovery()
|
||||
// - BluetoothAdapter.stopDiscovery()
|
||||
// - BluetoothAdapter.pair()
|
||||
// - BluetoothAdapter.unpair()
|
||||
// - BluetoothAdapter.onpairedstatuschanged()
|
||||
// - BluetoothAdapter.setPairingConfirmation()
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
function replyPairingReq(aAdapter, aPairingEvent) {
|
||||
switch (aPairingEvent.method) {
|
||||
case 'confirmation':
|
||||
log("The pairing passkey is " + aPairingEvent.passkey);
|
||||
aAdapter.setPairingConfirmation(aPairingEvent.address, true);
|
||||
break;
|
||||
case 'pincode':
|
||||
let pincode = BT_PAIRING_PINCODE;
|
||||
aAdapter.setPinCode(aPairingEvent.address, pincode);
|
||||
break;
|
||||
case 'passkey':
|
||||
let passkey = BT_PAIRING_PASSKEY;
|
||||
aAdapter.setPasskey(aPairingEvent.address, passkey);
|
||||
break;
|
||||
default:
|
||||
ok(false, "Unsupported pairing method. [" + aPairingEvent.method + "]");
|
||||
}
|
||||
}
|
||||
|
||||
startBluetoothTest(true, function testCaseMain(aAdapter) {
|
||||
log("Testing the pairing process of BluetoothAdapter ...");
|
||||
|
||||
// listens to the system message BT_PAIRING_REQ
|
||||
navigator.mozSetMessageHandler(BT_PAIRING_REQ,
|
||||
(evt) => replyPairingReq(aAdapter, evt));
|
||||
|
||||
return Promise.resolve()
|
||||
.then(() => removeEmulatorRemoteDevice(BDADDR_ALL))
|
||||
.then(() => addEmulatorRemoteDevice())
|
||||
.then((aRemoteAddress) =>
|
||||
startDiscoveryAndWaitDevicesFound(aAdapter, [aRemoteAddress]))
|
||||
.then((aRemoteAddresses) =>
|
||||
stopDiscovery(aAdapter).then(() => aRemoteAddresses))
|
||||
// 'aRemoteAddresses' is an arrary which contains addresses of discovered
|
||||
// remote devices.
|
||||
// Pairs with the first device in 'aRemoteAddresses' to test the functionality
|
||||
// of BluetoothAdapter.pair and BluetoothAdapter.onpairedstatuschanged.
|
||||
.then((aRemoteAddresses) => pairDeviceAndWait(aAdapter, aRemoteAddresses.pop()))
|
||||
.then(() => getPairedDevices(aAdapter))
|
||||
.then((aPairedDevices) => unpair(aAdapter, aPairedDevices.pop().address))
|
||||
.then(() => removeEmulatorRemoteDevice(BDADDR_ALL));
|
||||
});
|
@ -1,6 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 et filetype=javascript
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* 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/. */
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 et filetype=javascript
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* 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/. */
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 et filetype=javascript
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* 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/. */
|
||||
|
||||
|
@ -0,0 +1,12 @@
|
||||
# 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/.
|
||||
|
||||
from marionette_test import MarionetteTestCase
|
||||
|
||||
class testNavigateToDefault(MarionetteTestCase):
|
||||
def test_navigate_to_default_url(self):
|
||||
try:
|
||||
self.marionette.navigate("app://system.gaiamobile.org/index.html")
|
||||
except:
|
||||
self.assertTrue(Flase, "Can not navigate to system app.")
|
@ -1,15 +0,0 @@
|
||||
[DEFAULT]
|
||||
; true if the test requires an emulator, otherwise false
|
||||
qemu = false
|
||||
|
||||
; true if the test is compatible with the browser, otherwise false
|
||||
browser = true
|
||||
|
||||
; true if the test is compatible with b2g, otherwise false
|
||||
b2g = true
|
||||
|
||||
; true if the test should be skipped
|
||||
skip = false
|
||||
|
||||
[test_touchcaret.py]
|
||||
b2g = false ; Bug 1020261
|
@ -1,339 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# 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/.
|
||||
|
||||
import string
|
||||
|
||||
from by import By
|
||||
from marionette import Actions
|
||||
from marionette_test import MarionetteTestCase
|
||||
|
||||
|
||||
class TouchCaretTest(MarionetteTestCase):
|
||||
_input_selector = (By.ID, 'input')
|
||||
_textarea_selector = (By.ID, 'textarea')
|
||||
_contenteditable_selector = (By.ID, 'contenteditable')
|
||||
|
||||
def setUp(self):
|
||||
# Code to execute before a tests are run.
|
||||
MarionetteTestCase.setUp(self)
|
||||
self.actions = Actions(self.marionette)
|
||||
|
||||
def openTestHtml(self, enabled=True):
|
||||
'''Open html for testing and locate elements, and enable/disable touch
|
||||
caret.'''
|
||||
self.marionette.execute_script(
|
||||
'SpecialPowers.setBoolPref("touchcaret.enabled", %s);' %
|
||||
('true' if enabled else 'false'))
|
||||
|
||||
test_html = self.marionette.absolute_url('test_touchcaret.html')
|
||||
self.marionette.navigate(test_html)
|
||||
|
||||
self._input = self.marionette.find_element(*self._input_selector)
|
||||
self._textarea = self.marionette.find_element(*self._textarea_selector)
|
||||
self._contenteditable = self.marionette.find_element(*self._contenteditable_selector)
|
||||
|
||||
def is_input_or_textarea(self, element):
|
||||
'''Return True if element is either <input> or <textarea>'''
|
||||
return element.tag_name in ('input', 'textarea')
|
||||
|
||||
def get_js_selection_cmd(self, element):
|
||||
'''Return a command snippet to get selection object.
|
||||
|
||||
If the element is <input> or <textarea>, return the selection object
|
||||
associated with it. Otherwise, return the current selection object.
|
||||
|
||||
Note: "element" must be provided as the first argument to
|
||||
execute_script().
|
||||
|
||||
'''
|
||||
if self.is_input_or_textarea(element):
|
||||
# We must unwrap sel so that DOMRect could be returned to Python
|
||||
# side.
|
||||
return '''var sel = SpecialPowers.wrap(arguments[0]).editor.selection;
|
||||
sel = SpecialPowers.unwrap(sel);'''
|
||||
else:
|
||||
return '''var sel = window.getSelection();'''
|
||||
|
||||
def caret_rect(self, element):
|
||||
'''Return the caret's DOMRect object.
|
||||
|
||||
If the element is either <input> or <textarea>, return the caret's
|
||||
DOMRect within the element. Otherwise, return the DOMRect of the
|
||||
current selected caret.
|
||||
|
||||
'''
|
||||
cmd = self.get_js_selection_cmd(element) +\
|
||||
'''return sel.getRangeAt(0).getClientRects()[0];'''
|
||||
return self.marionette.execute_script(cmd, script_args=[element])
|
||||
|
||||
def caret_location(self, element):
|
||||
'''Return caret's center location by the number of characters offset
|
||||
within the given element.
|
||||
|
||||
Return (x, y) coordinates of the caret's center by the number of
|
||||
characters offset relative to the top left-hand corner of the given
|
||||
element.
|
||||
|
||||
'''
|
||||
rect = self.caret_rect(element)
|
||||
x = rect['left'] + rect['width'] / 2.0 - element.location['x']
|
||||
y = rect['top'] + rect['height'] / 2.0 - element.location['y']
|
||||
return x, y
|
||||
|
||||
def touch_caret_location(self, element):
|
||||
'''Return touch caret's location (based on current caret location).
|
||||
|
||||
Return (x, y) coordinates of the touch caret's tip relative to the top
|
||||
left-hand corner of the given element.
|
||||
|
||||
'''
|
||||
rect = self.caret_rect(element)
|
||||
x = rect['left'] - element.location['x']
|
||||
|
||||
# Touch caret's tip is below the bottom of the caret. Add 5px to y
|
||||
# should be sufficient to locate it.
|
||||
y = rect['bottom'] + 5 - element.location['y']
|
||||
|
||||
return x, y
|
||||
|
||||
def move_caret_by_offset(self, element, offset, backward=False):
|
||||
'''Move caret in the element by offset.'''
|
||||
cmd = self.get_js_selection_cmd(element) +\
|
||||
'''sel.modify("move", arguments[1], "character");'''
|
||||
direction = 'backward' if backward else 'forward'
|
||||
|
||||
for i in range(offset):
|
||||
self.marionette.execute_script(
|
||||
cmd, script_args=[element, direction])
|
||||
|
||||
def move_caret_to_front(self, element):
|
||||
if self.is_input_or_textarea(element):
|
||||
cmd = '''arguments[0].setSelectionRange(0, 0);'''
|
||||
else:
|
||||
cmd = '''var sel = window.getSelection();
|
||||
sel.collapse(arguments[0].firstChild, 0);'''
|
||||
|
||||
self.marionette.execute_script(cmd, script_args=[element])
|
||||
|
||||
def move_caret_to_end(self, element):
|
||||
if self.is_input_or_textarea(element):
|
||||
cmd = '''var len = arguments[0].value.length;
|
||||
arguments[0].setSelectionRange(len, len);'''
|
||||
else:
|
||||
cmd = '''var sel = window.getSelection();
|
||||
sel.collapse(arguments[0].lastChild, arguments[0].lastChild.length);'''
|
||||
|
||||
self.marionette.execute_script(cmd, script_args=[element])
|
||||
|
||||
def get_content(self, element):
|
||||
'''Return the content of the element.'''
|
||||
if self.is_input_or_textarea(element):
|
||||
return element.get_attribute('value')
|
||||
else:
|
||||
return element.text
|
||||
|
||||
def _test_move_caret_to_the_right_by_one_character(self, el, assertFunc):
|
||||
content_to_add = '!'
|
||||
target_content = self.get_content(el)
|
||||
target_content = target_content[:1] + content_to_add + target_content[1:]
|
||||
|
||||
# Get touch caret (x, y) at position 1 and 2.
|
||||
self.move_caret_to_front(el)
|
||||
caret0_x, caret0_y = self.caret_location(el)
|
||||
touch_caret0_x, touch_caret0_y = self.touch_caret_location(el)
|
||||
self.move_caret_by_offset(el, 1)
|
||||
touch_caret1_x, touch_caret1_y = self.touch_caret_location(el)
|
||||
|
||||
# Tap the front of the input to make touch caret appear.
|
||||
el.tap(caret0_x, caret0_y)
|
||||
|
||||
# Move touch caret
|
||||
self.actions.flick(el, touch_caret0_x, touch_caret0_y,
|
||||
touch_caret1_x, touch_caret1_y).perform()
|
||||
|
||||
el.send_keys(content_to_add)
|
||||
assertFunc(target_content, self.get_content(el))
|
||||
|
||||
def _test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self, el, assertFunc):
|
||||
content_to_add = '!'
|
||||
target_content = self.get_content(el) + content_to_add
|
||||
|
||||
# Tap the front of the input to make touch caret appear.
|
||||
self.move_caret_to_front(el)
|
||||
el.tap(*self.caret_location(el))
|
||||
|
||||
# Move touch caret to the bottom-right corner of the element.
|
||||
src_x, src_y = self.touch_caret_location(el)
|
||||
dest_x, dest_y = el.size['width'], el.size['height']
|
||||
self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform()
|
||||
|
||||
el.send_keys(content_to_add)
|
||||
assertFunc(target_content, self.get_content(el))
|
||||
|
||||
def _test_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self, el, assertFunc):
|
||||
content_to_add = '!'
|
||||
target_content = content_to_add + self.get_content(el)
|
||||
|
||||
# Tap to make touch caret appear. Note: it's strange that when the caret
|
||||
# is at the end, the rect of the caret in <textarea> cannot be obtained.
|
||||
# A bug perhaps.
|
||||
self.move_caret_to_end(el)
|
||||
self.move_caret_by_offset(el, 1, backward=True)
|
||||
el.tap(*self.caret_location(el))
|
||||
|
||||
# Move touch caret to the top-left corner of the input box.
|
||||
src_x, src_y = self.touch_caret_location(el)
|
||||
dest_x, dest_y = 0, 0
|
||||
self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform()
|
||||
|
||||
el.send_keys(content_to_add)
|
||||
assertFunc(target_content, self.get_content(el))
|
||||
|
||||
def _test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self, el, assertFunc):
|
||||
content_to_add = '!'
|
||||
non_target_content = content_to_add + self.get_content(el)
|
||||
|
||||
# Get touch caret timeout in millisecond, and convert it to second.
|
||||
timeout = self.marionette.execute_script(
|
||||
'return SpecialPowers.getIntPref("touchcaret.expiration.time");')
|
||||
timeout /= 1000.0
|
||||
|
||||
# Tap to make touch caret appear. Note: it's strange that when the caret
|
||||
# is at the end, the rect of the caret in <textarea> cannot be obtained.
|
||||
# A bug perhaps.
|
||||
self.move_caret_to_end(el)
|
||||
self.move_caret_by_offset(el, 1, backward=True)
|
||||
el.tap(*self.caret_location(el))
|
||||
|
||||
# Wait until touch caret disappears, then pretend to move it to the
|
||||
# top-left corner of the input box.
|
||||
src_x, src_y = self.touch_caret_location(el)
|
||||
dest_x, dest_y = 0, 0
|
||||
self.actions.wait(timeout).flick(el, src_x, src_y, dest_x, dest_y).perform()
|
||||
|
||||
el.send_keys(content_to_add)
|
||||
assertFunc(non_target_content, self.get_content(el))
|
||||
|
||||
def _test_scroll_by_dragging_touch_caret_to_bottom_right_corner(self, el, assertFunc):
|
||||
content_to_add = '!'
|
||||
target_content = string.ascii_letters + content_to_add
|
||||
|
||||
# Insert a long string to test horizontal scrolling.
|
||||
el.clear()
|
||||
el.send_keys(string.ascii_letters)
|
||||
|
||||
# Tap to make touch caret appear.
|
||||
el.tap()
|
||||
|
||||
# Move touch caret to 100px right to the bottom-right corner of the input
|
||||
# box so that it could scroll faster.
|
||||
src_x, src_y = self.touch_caret_location(el)
|
||||
dest_x, dest_y = el.size['width'] + 100, el.size['height']
|
||||
self.actions.flick(el, src_x, src_y, dest_x, dest_y).perform()
|
||||
|
||||
el.send_keys(content_to_add)
|
||||
assertFunc(target_content, self.get_content(el))
|
||||
|
||||
########################################################################
|
||||
# <input> test cases with touch caret enabled
|
||||
########################################################################
|
||||
def test_input_move_caret_to_the_right_by_one_character(self):
|
||||
self.openTestHtml(enabled=True)
|
||||
self._test_move_caret_to_the_right_by_one_character(self._input, self.assertEqual)
|
||||
|
||||
def test_input_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self):
|
||||
self.openTestHtml(enabled=True)
|
||||
self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self._input, self.assertEqual)
|
||||
|
||||
def test_input_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self):
|
||||
self.openTestHtml(enabled=True)
|
||||
self._test_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self._input, self.assertEqual)
|
||||
|
||||
def test_input_touch_caret_timeout(self):
|
||||
self.openTestHtml(enabled=True)
|
||||
self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self._input, self.assertNotEqual)
|
||||
|
||||
def test_input_scroll_by_dragging_touch_caret_to_bottom_right_corner(self):
|
||||
self.openTestHtml(enabled=True)
|
||||
self._test_scroll_by_dragging_touch_caret_to_bottom_right_corner(self._input, self.assertEqual)
|
||||
|
||||
########################################################################
|
||||
# <input> test cases with touch caret disabled
|
||||
########################################################################
|
||||
def test_input_move_caret_to_the_right_by_one_character_disabled(self):
|
||||
self.openTestHtml(enabled=False)
|
||||
self._test_move_caret_to_the_right_by_one_character(self._input, self.assertNotEqual)
|
||||
|
||||
def test_input_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled(self):
|
||||
self.openTestHtml(enabled=False)
|
||||
self._test_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self._input, self.assertNotEqual)
|
||||
|
||||
########################################################################
|
||||
# <textarea> test cases with touch caret enabled
|
||||
########################################################################
|
||||
def test_textarea_move_caret_to_the_right_by_one_character(self):
|
||||
self.openTestHtml(enabled=True)
|
||||
self._test_move_caret_to_the_right_by_one_character(self._textarea, self.assertEqual)
|
||||
|
||||
def test_textarea_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self):
|
||||
self.openTestHtml(enabled=True)
|
||||
self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self._textarea, self.assertEqual)
|
||||
|
||||
def test_textarea_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self):
|
||||
self.openTestHtml(enabled=True)
|
||||
self._test_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self._textarea, self.assertEqual)
|
||||
|
||||
def test_textarea_touch_caret_timeout(self):
|
||||
self.openTestHtml(enabled=True)
|
||||
self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self._textarea, self.assertNotEqual)
|
||||
|
||||
def test_textarea_scroll_by_dragging_touch_caret_to_bottom_right_corner(self):
|
||||
self.openTestHtml(enabled=True)
|
||||
self._test_scroll_by_dragging_touch_caret_to_bottom_right_corner(self._textarea, self.assertEqual)
|
||||
|
||||
########################################################################
|
||||
# <textarea> test cases with touch caret disabled
|
||||
########################################################################
|
||||
def test_textarea_move_caret_to_the_right_by_one_character_disabled(self):
|
||||
self.openTestHtml(enabled=False)
|
||||
self._test_move_caret_to_the_right_by_one_character(self._textarea, self.assertNotEqual)
|
||||
|
||||
def test_textarea_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled(self):
|
||||
self.openTestHtml(enabled=False)
|
||||
self._test_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self._textarea, self.assertNotEqual)
|
||||
|
||||
########################################################################
|
||||
# <div> contenteditable test cases with touch caret enabled
|
||||
########################################################################
|
||||
def test_contenteditable_move_caret_to_the_right_by_one_character(self):
|
||||
self.openTestHtml(enabled=True)
|
||||
self._test_move_caret_to_the_right_by_one_character(self._contenteditable, self.assertEqual)
|
||||
|
||||
def test_contenteditable_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self):
|
||||
self.openTestHtml(enabled=True)
|
||||
self._test_move_caret_to_end_by_dragging_touch_caret_to_bottom_right_corner(self._contenteditable, self.assertEqual)
|
||||
|
||||
def test_contenteditable_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self):
|
||||
self.openTestHtml(enabled=True)
|
||||
self._test_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self._contenteditable, self.assertEqual)
|
||||
|
||||
def test_contenteditable_touch_caret_timeout(self):
|
||||
self.openTestHtml(enabled=True)
|
||||
self._test_touch_caret_timeout_by_dragging_it_to_top_left_corner_after_timout(self._contenteditable, self.assertNotEqual)
|
||||
|
||||
def test_contenteditable_scroll_by_dragging_touch_caret_to_bottom_right_corner(self):
|
||||
self.openTestHtml(enabled=True)
|
||||
self._test_scroll_by_dragging_touch_caret_to_bottom_right_corner(self._contenteditable, self.assertEqual)
|
||||
|
||||
########################################################################
|
||||
# <div> contenteditable test cases with touch caret disabled
|
||||
########################################################################
|
||||
def test_contenteditable_move_caret_to_the_right_by_one_character_disabled(self):
|
||||
self.openTestHtml(enabled=False)
|
||||
self._test_move_caret_to_the_right_by_one_character(self._contenteditable, self.assertNotEqual)
|
||||
|
||||
def test_contenteditable_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner_disabled(self):
|
||||
self.openTestHtml(enabled=False)
|
||||
self._test_move_caret_to_front_by_dragging_touch_caret_to_top_left_corner(self._contenteditable, self.assertNotEqual)
|
@ -3946,8 +3946,12 @@ pref("profiler.enabled", false);
|
||||
pref("profiler.interval", 10);
|
||||
pref("profiler.entries", 100000);
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_ANDROID)
|
||||
// Network Information API
|
||||
pref("dom.netinfo.enabled", true);
|
||||
#else
|
||||
pref("dom.netinfo.enabled", false);
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
// On 32-bit Windows, fire a low-memory notification if we have less than this
|
||||
|
@ -27,6 +27,3 @@ skip = false
|
||||
[include:../../../../../dom/nfc/tests/marionette/manifest.ini]
|
||||
[include:../../../../../dom/events/test/marionette/manifest.ini]
|
||||
[include:../../../../../dom/wifi/test/marionette/manifest.ini]
|
||||
|
||||
; layout tests
|
||||
[include:../../../../../layout/base/tests/marionette/manifest.ini]
|
||||
|
@ -1,17 +0,0 @@
|
||||
<!-- 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/. -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html id="html">
|
||||
<head>
|
||||
<title>Bug 960897: Marionette tests for touch caret</title>
|
||||
</head>
|
||||
<body>
|
||||
<div><input id="input" value="ABCDEFGHI"></input></div>
|
||||
<br />
|
||||
<div><textarea name="textarea" id="textarea" rows="4" cols="6">ABCDEFGHI</textarea></div>
|
||||
<br />
|
||||
<div style="width: 10em; height: 2em; word-wrap: break-word; overflow: auto;" contenteditable="true" id="contenteditable">ABCDEFGHI</div>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user