mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to f-t
This commit is contained in:
commit
757831e55e
7
CLOBBER
7
CLOBBER
@ -22,4 +22,9 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Merge day clobber
|
||||
Bug 1105308 - Cleanup BluetoothUtils.{cpp,h}
|
||||
|
||||
This patch set moves some files around and requires a rebuild
|
||||
of the build system's dependency information.
|
||||
|
||||
Merge day clobber
|
||||
|
@ -681,6 +681,7 @@ static const EStateRule sWAIUnivStateMap[] = {
|
||||
eARIAExpanded, // Currently under spec review but precedent exists
|
||||
eARIAHasPopup, // Note this is technically a "property"
|
||||
eARIAInvalid,
|
||||
eARIAModal,
|
||||
eARIARequired, // XXX not global, Bug 553117
|
||||
eARIANone
|
||||
};
|
||||
@ -716,6 +717,7 @@ static const AttrCharacteristics gWAIUnivAttrMap[] = {
|
||||
{&nsGkAtoms::aria_labelledby, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_level, ATTR_BYPASSOBJ }, /* handled via groupPosition */
|
||||
{&nsGkAtoms::aria_live, ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_modal, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_multiline, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{&nsGkAtoms::aria_multiselectable, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{&nsGkAtoms::aria_owns, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
|
@ -228,15 +228,15 @@ uint64_t UniversalStatesFor(mozilla::dom::Element* aElement);
|
||||
uint8_t AttrCharacteristicsFor(nsIAtom* aAtom);
|
||||
|
||||
/**
|
||||
* Represents a simple enumerator for iterating through ARIA attributes
|
||||
* exposed as object attributes on a given accessible.
|
||||
* Represents a simple enumerator for iterating through ARIA attributes
|
||||
* exposed as object attributes on a given accessible.
|
||||
*/
|
||||
class AttrIterator
|
||||
{
|
||||
public:
|
||||
explicit AttrIterator(nsIContent* aContent) :
|
||||
mContent(aContent), mAttrIdx(0)
|
||||
{
|
||||
explicit AttrIterator(nsIContent* aContent) :
|
||||
mContent(aContent), mAttrIdx(0)
|
||||
{
|
||||
mAttrCount = mContent->GetAttrCount();
|
||||
}
|
||||
|
||||
|
@ -185,6 +185,16 @@ aria::MapToState(EStateRule aRule, dom::Element* aElement, uint64_t* aState)
|
||||
return true;
|
||||
}
|
||||
|
||||
case eARIAModal:
|
||||
{
|
||||
static const TokenTypeData data(
|
||||
nsGkAtoms::aria_modal, eBoolType,
|
||||
0, states::MODAL);
|
||||
|
||||
MapTokenType(aElement, aState, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
case eARIAMultiline:
|
||||
{
|
||||
static const TokenTypeData data(
|
||||
|
@ -33,6 +33,7 @@ enum EStateRule
|
||||
eARIAExpanded,
|
||||
eARIAHasPopup,
|
||||
eARIAInvalid,
|
||||
eARIAModal,
|
||||
eARIAMultiline,
|
||||
eARIAMultiSelectable,
|
||||
eARIAOrientation,
|
||||
|
@ -28,16 +28,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
|
||||
testAbsentAttrs(getNode("atomic_false").firstChild, {"container-atomic" : "false"});
|
||||
|
||||
testAttrs("autocomplete", {"autocomplete" : "true"}, true);
|
||||
testAttrs("checkbox", {"checkable" : "true"}, true);
|
||||
testAttrs("checkedCheckbox", {"checkable" : "true"}, true);
|
||||
testAttrs("checkedMenuitem", {"checkable" : "true"}, true);
|
||||
testAttrs("checkedOption", {"checkable" : "true"}, true);
|
||||
testAttrs("checkedRadio", {"checkable" : "true"}, true);
|
||||
testAttrs("checkedTreeitem", {"checkable" : "true"}, true);
|
||||
testAttrs("checkbox", {"checkable" : "true"}, true);
|
||||
testAttrs("checkedCheckbox", {"checkable" : "true"}, true);
|
||||
testAttrs("checkedMenuitem", {"checkable" : "true"}, true);
|
||||
testAttrs("checkedOption", {"checkable" : "true"}, true);
|
||||
testAttrs("checkedRadio", {"checkable" : "true"}, true);
|
||||
testAttrs("checkedTreeitem", {"checkable" : "true"}, true);
|
||||
testAttrs("dropeffect", {"dropeffect" : "copy"}, true);
|
||||
testAttrs("grabbed", {"grabbed" : "true"}, true);
|
||||
testAbsentAttrs("haspopup", { "haspopup": "false" });
|
||||
testAttrs("hidden", {"hidden" : "true"}, true);
|
||||
testAbsentAttrs("hidden_false", { "hidden": "false" });
|
||||
testAbsentAttrs("modal", {"modal" : "true"});
|
||||
testAttrs("sortAscending", {"sort" : "ascending"}, true);
|
||||
testAttrs("sortDescending", {"sort" : "descending"}, true);
|
||||
testAttrs("sortNone", {"sort" : "none"}, true);
|
||||
@ -198,8 +200,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
|
||||
<div id="checkedTreeitem" role="treeitem" aria-checked="true"></div>
|
||||
<div id="dropeffect" aria-dropeffect="copy"></div>
|
||||
<div id="grabbed" aria-grabbed="true"></div>
|
||||
<div id="haspopup" aria-haspopup="true"></div>
|
||||
<div id="hidden" aria-hidden="true"></div>
|
||||
<div id="hidden_false" aria-hidden="false"></div>
|
||||
<div id="modal" aria-modal="true"></div>
|
||||
<div id="sortAscending" role="columnheader" aria-sort="ascending"></div>
|
||||
<div id="sortDescending" role="columnheader" aria-sort="descending"></div>
|
||||
<div id="sortNone" role="columnheader" aria-sort="none"></div>
|
||||
|
@ -42,6 +42,7 @@ const EXT_STATE_EDITABLE = nsIAccessibleStates.EXT_STATE_EDITABLE;
|
||||
const EXT_STATE_ENABLED = nsIAccessibleStates.EXT_STATE_ENABLED;
|
||||
const EXT_STATE_EXPANDABLE = nsIAccessibleStates.EXT_STATE_EXPANDABLE;
|
||||
const EXT_STATE_HORIZONTAL = nsIAccessibleStates.EXT_STATE_HORIZONTAL;
|
||||
const EXT_STATE_MODAL = nsIAccessibleStates.EXT_STATE_MODAL;
|
||||
const EXT_STATE_MULTI_LINE = nsIAccessibleStates.EXT_STATE_MULTI_LINE;
|
||||
const EXT_STATE_PINNED = nsIAccessibleStates.EXT_STATE_PINNED;
|
||||
const EXT_STATE_SENSITIVE = nsIAccessibleStates.EXT_STATE_SENSITIVE;
|
||||
|
@ -97,6 +97,10 @@
|
||||
// disabled, too. See bug 429285.
|
||||
testAriaDisabledTree("group");
|
||||
|
||||
// aria-modal
|
||||
testStates("aria_modal", 0, EXT_STATE_MODAL);
|
||||
testStates("aria_modal_false", 0, 0, 0, EXT_STATE_MODAL);
|
||||
|
||||
// aria-multiline
|
||||
testStates("aria_multiline_textbox", 0, EXT_STATE_MULTI_LINE);
|
||||
|
||||
@ -379,6 +383,8 @@
|
||||
<div id="aria_mixed_checkbox" role="checkbox" aria-checked="mixed">
|
||||
I might agree
|
||||
</div>
|
||||
<div id="aria_modal" aria-modal="true">modal stuff</div>
|
||||
<div id="aria_modal_false" aria-modal="false">non modal stuff</div>div>
|
||||
<div id="aria_multiline_textbox" role="textbox" aria-multiline="true"></div>
|
||||
<div id="aria_multiselectable_listbox" role="listbox" aria-multiselectable="true"></div>
|
||||
<div id="aria_pressed_button" role="button" aria-pressed="true">Button</div>
|
||||
|
@ -36,10 +36,42 @@ let principal = Cc["@mozilla.org/scriptsecuritymanager;1"].
|
||||
getService(Ci.nsIScriptSecurityManager).
|
||||
getCodebasePrincipal(principaluri);
|
||||
|
||||
function toArray(args) {
|
||||
return Array.prototype.slice.call(args);
|
||||
}
|
||||
|
||||
function openInternal(args, forPrincipal, deleting) {
|
||||
if (forPrincipal) {
|
||||
args = toArray(args);
|
||||
} else {
|
||||
args = [principal].concat(toArray(args));
|
||||
}
|
||||
if (args.length == 2) {
|
||||
args.push({ storage: "persistent" });
|
||||
} else if (!deleting && args.length >= 3 && typeof args[2] === "number") {
|
||||
args[2] = { version: args[2], storage: "persistent" };
|
||||
}
|
||||
|
||||
if (deleting) {
|
||||
return indexedDB.deleteForPrincipal.apply(indexedDB, args);
|
||||
}
|
||||
|
||||
return indexedDB.openForPrincipal.apply(indexedDB, args);
|
||||
}
|
||||
|
||||
exports.indexedDB = Object.freeze({
|
||||
open: indexedDB.openForPrincipal.bind(indexedDB, principal),
|
||||
openForPrincipal: indexedDB.openForPrincipal.bind(indexedDB),
|
||||
deleteDatabase: indexedDB.deleteForPrincipal.bind(indexedDB, principal),
|
||||
open: function () {
|
||||
return openInternal(arguments, false, false);
|
||||
},
|
||||
deleteDatabase: function () {
|
||||
return openInternal(arguments, false, true);
|
||||
},
|
||||
openForPrincipal: function () {
|
||||
return openInternal(arguments, true, false);
|
||||
},
|
||||
deleteForPrincipal: function () {
|
||||
return openInternal(arguments, true, true);
|
||||
},
|
||||
cmp: indexedDB.cmp.bind(indexedDB)
|
||||
});
|
||||
|
||||
|
@ -28,16 +28,82 @@ exports["test db variables"] = function(assert) {
|
||||
}
|
||||
|
||||
exports["test open"] = function(assert, done) {
|
||||
let request = indexedDB.open("MyTestDatabase");
|
||||
testOpen(0, assert, done);
|
||||
}
|
||||
|
||||
function testOpen(step, assert, done) {
|
||||
const dbName = "MyTestDatabase";
|
||||
const openParams = [
|
||||
{ dbName: "MyTestDatabase", dbVersion: 10 },
|
||||
{ dbName: "MyTestDatabase" },
|
||||
{ dbName: "MyTestDatabase", dbOptions: { storage: "temporary" } },
|
||||
{ dbName: "MyTestDatabase", dbOptions: { version: 20, storage: "default" } }
|
||||
];
|
||||
|
||||
let params = openParams[step];
|
||||
|
||||
let request;
|
||||
let expectedStorage;
|
||||
let expectedVersion;
|
||||
let upgradeNeededCalled = false;
|
||||
if ("dbVersion" in params) {
|
||||
request = indexedDB.open(params.dbName, params.dbVersion);
|
||||
expectedVersion = params.dbVersion;
|
||||
expectedStorage = "persistent";
|
||||
} else if ("dbOptions" in params) {
|
||||
request = indexedDB.open(params.dbName, params.dbOptions);
|
||||
if ("version" in params.dbOptions) {
|
||||
expectedVersion = params.dbOptions.version;
|
||||
} else {
|
||||
expectedVersion = 1;
|
||||
}
|
||||
if ("storage" in params.dbOptions) {
|
||||
expectedStorage = params.dbOptions.storage;
|
||||
} else {
|
||||
expectedStorage = "persistent";
|
||||
}
|
||||
} else {
|
||||
request = indexedDB.open(params.dbName);
|
||||
expectedVersion = 1;
|
||||
expectedStorage = "persistent";
|
||||
}
|
||||
request.onerror = function(event) {
|
||||
assert.fail("Failed to open indexedDB")
|
||||
done();
|
||||
};
|
||||
}
|
||||
request.onupgradeneeded = function(event) {
|
||||
upgradeNeededCalled = true;
|
||||
assert.equal(event.oldVersion, 0, "Correct old version");
|
||||
}
|
||||
request.onsuccess = function(event) {
|
||||
assert.pass("IndexedDB was open");
|
||||
done();
|
||||
};
|
||||
};
|
||||
assert.equal(upgradeNeededCalled, true, "Upgrade needed called");
|
||||
let db = request.result;
|
||||
assert.equal(db.storage, expectedStorage, "Storage is correct");
|
||||
db.onversionchange = function(event) {
|
||||
assert.equal(event.oldVersion, expectedVersion, "Old version is correct");
|
||||
db.close();
|
||||
}
|
||||
if ("dbOptions" in params) {
|
||||
request = indexedDB.deleteDatabase(params.dbName, params.dbOptions);
|
||||
} else {
|
||||
request = indexedDB.deleteDatabase(params.dbName);
|
||||
}
|
||||
request.onerror = function(event) {
|
||||
assert.fail("Failed to delete indexedDB")
|
||||
done();
|
||||
}
|
||||
request.onsuccess = function(event) {
|
||||
assert.pass("IndexedDB was deleted");
|
||||
|
||||
if (++step == openParams.length) {
|
||||
done();
|
||||
} else {
|
||||
testOpen(step, assert, done);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports["test dbname is unprefixed"] = function(assert, done) {
|
||||
// verify fixes in https://bugzilla.mozilla.org/show_bug.cgi?id=786688
|
||||
|
@ -329,7 +329,7 @@ var shell = {
|
||||
window.addEventListener('sizemodechange', this);
|
||||
window.addEventListener('unload', this);
|
||||
this.contentBrowser.addEventListener('mozbrowserloadstart', this, true);
|
||||
this.contentBrowser.addEventListener('mozbrowserselectionchange', this, true);
|
||||
this.contentBrowser.addEventListener('mozbrowserselectionstatechanged', this, true);
|
||||
this.contentBrowser.addEventListener('mozbrowserscrollviewchange', this, true);
|
||||
this.contentBrowser.addEventListener('mozbrowsertouchcarettap', this, true);
|
||||
|
||||
@ -357,7 +357,7 @@ var shell = {
|
||||
window.removeEventListener('mozfullscreenchange', this);
|
||||
window.removeEventListener('sizemodechange', this);
|
||||
this.contentBrowser.removeEventListener('mozbrowserloadstart', this, true);
|
||||
this.contentBrowser.removeEventListener('mozbrowserselectionchange', this, true);
|
||||
this.contentBrowser.removeEventListener('mozbrowserselectionstatechanged', this, true);
|
||||
this.contentBrowser.removeEventListener('mozbrowserscrollviewchange', this, true);
|
||||
this.contentBrowser.removeEventListener('mozbrowsertouchcarettap', this, true);
|
||||
ppmm.removeMessageListener("content-handler", this);
|
||||
@ -505,8 +505,8 @@ var shell = {
|
||||
detail: evt.detail,
|
||||
});
|
||||
break;
|
||||
case 'mozbrowserselectionchange':
|
||||
// The mozbrowserselectionchange event, may have crossed the chrome-content boundary.
|
||||
case 'mozbrowserselectionstatechanged':
|
||||
// The mozbrowserselectionstatechanged event, may have crossed the chrome-content boundary.
|
||||
// This event always dispatch to shell.js. But the offset we got from this event is
|
||||
// based on tab's coordinate. So get the actual offsets between shell and evt.target.
|
||||
let elt = evt.target;
|
||||
@ -524,7 +524,7 @@ var shell = {
|
||||
|
||||
DoCommandHelper.setEvent(evt);
|
||||
shell.sendChromeEvent({
|
||||
type: 'selectionchange',
|
||||
type: 'selectionstatechanged',
|
||||
detail: data,
|
||||
});
|
||||
break;
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="7cc460af0f6f491d1afa6b6043cdea5025f0e15f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="47111fd2bbe8b0055c8a596959d701391d2a9953"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -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="7cc460af0f6f491d1afa6b6043cdea5025f0e15f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="47111fd2bbe8b0055c8a596959d701391d2a9953"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||
@ -97,7 +97,7 @@
|
||||
<project name="platform/system/netd" path="system/netd" revision="3d298fde142bee3fc4f07f63f16f2d8ce42339c0"/>
|
||||
<project name="platform/system/vold" path="system/vold" revision="919829940468066a32f403980b43f6ebfee5d314"/>
|
||||
<!-- Emulator specific things -->
|
||||
<project name="android-development" path="development" remote="b2g" revision="c99e41d49f0b98eade30814e52c1de9e818def68"/>
|
||||
<project name="android-development" path="development" remote="b2g" revision="2bdf22305b523af644e1891b4ddfd9229336d0ce"/>
|
||||
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="0d5c43228006bae775c4cb57a6d3908484d41718"/>
|
||||
<project name="platform/external/iproute2" path="external/iproute2" revision="c66c5716d5335e450f7a7b71ccc6a604fb2f41d2"/>
|
||||
<project name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="d2685281e2e54ca14d1df304867aa82c37b27162"/>
|
||||
|
@ -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="7cc460af0f6f491d1afa6b6043cdea5025f0e15f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="47111fd2bbe8b0055c8a596959d701391d2a9953"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="6499615ecece69e726657dc5caaeefa05fbb66bf"/>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="7cc460af0f6f491d1afa6b6043cdea5025f0e15f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="47111fd2bbe8b0055c8a596959d701391d2a9953"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -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="7cc460af0f6f491d1afa6b6043cdea5025f0e15f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="47111fd2bbe8b0055c8a596959d701391d2a9953"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="d5d3f93914558b6f168447b805cd799c8233e300"/>
|
||||
@ -97,7 +97,7 @@
|
||||
<project name="platform/system/netd" path="system/netd" revision="3d298fde142bee3fc4f07f63f16f2d8ce42339c0"/>
|
||||
<project name="platform/system/vold" path="system/vold" revision="919829940468066a32f403980b43f6ebfee5d314"/>
|
||||
<!-- Emulator specific things -->
|
||||
<project name="android-development" path="development" remote="b2g" revision="c99e41d49f0b98eade30814e52c1de9e818def68"/>
|
||||
<project name="android-development" path="development" remote="b2g" revision="2bdf22305b523af644e1891b4ddfd9229336d0ce"/>
|
||||
<project name="device_generic_goldfish" path="device/generic/goldfish" remote="b2g" revision="0d5c43228006bae775c4cb57a6d3908484d41718"/>
|
||||
<project name="platform/external/iproute2" path="external/iproute2" revision="c66c5716d5335e450f7a7b71ccc6a604fb2f41d2"/>
|
||||
<project name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="d2685281e2e54ca14d1df304867aa82c37b27162"/>
|
||||
|
@ -18,6 +18,7 @@
|
||||
],
|
||||
"zip_files": [
|
||||
["{workdir}/out/target/product/flame/*.img", "out/target/product/flame/"],
|
||||
["{workdir}/out/target/product/flame/bootloader", "out/target/product/flame/"],
|
||||
["{workdir}/boot.img", "out/target/product/flame/"],
|
||||
"{workdir}/flash.sh",
|
||||
"{workdir}/load-config.sh",
|
||||
|
@ -15,7 +15,7 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="3ab0d9c70f0b2e1ededc679112c392303f037361">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="7cc460af0f6f491d1afa6b6043cdea5025f0e15f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="47111fd2bbe8b0055c8a596959d701391d2a9953"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -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="7cc460af0f6f491d1afa6b6043cdea5025f0e15f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="47111fd2bbe8b0055c8a596959d701391d2a9953"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="6499615ecece69e726657dc5caaeefa05fbb66bf"/>
|
||||
|
@ -4,6 +4,6 @@
|
||||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "eb65c4355e0a16dc5cd203c5c007fd7e3bf0e4b2",
|
||||
"revision": "c65e0f2f00a05a78a57eecb1185c6420b7984d36",
|
||||
"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="7cc460af0f6f491d1afa6b6043cdea5025f0e15f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="47111fd2bbe8b0055c8a596959d701391d2a9953"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
|
@ -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="7cc460af0f6f491d1afa6b6043cdea5025f0e15f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="47111fd2bbe8b0055c8a596959d701391d2a9953"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<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="7cc460af0f6f491d1afa6b6043cdea5025f0e15f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="47111fd2bbe8b0055c8a596959d701391d2a9953"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="6499615ecece69e726657dc5caaeefa05fbb66bf"/>
|
||||
|
@ -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="7cc460af0f6f491d1afa6b6043cdea5025f0e15f"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="47111fd2bbe8b0055c8a596959d701391d2a9953"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="50ad16a280fe9cfa0716f8c6ba16afdf7f266b49"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
@ -151,6 +151,7 @@ const SNIPPETS_UPDATE_INTERVAL_MS = 86400000; // 1 Day.
|
||||
// IndexedDB storage constants.
|
||||
const DATABASE_NAME = "abouthome";
|
||||
const DATABASE_VERSION = 1;
|
||||
const DATABASE_STORAGE = "persistent";
|
||||
const SNIPPETS_OBJECTSTORE_NAME = "snippets";
|
||||
|
||||
// This global tracks if the page has been set up before, to prevent double inits
|
||||
@ -224,7 +225,8 @@ function ensureSnippetsMapThen(aCallback)
|
||||
gSnippetsMapCallbacks.length = 0;
|
||||
}
|
||||
|
||||
let openRequest = indexedDB.open(DATABASE_NAME, DATABASE_VERSION);
|
||||
let openRequest = indexedDB.open(DATABASE_NAME, {version: DATABASE_VERSION,
|
||||
storage: DATABASE_STORAGE});
|
||||
|
||||
openRequest.onerror = function (event) {
|
||||
// Try to delete the old database so that we can start this process over
|
||||
|
@ -152,6 +152,9 @@ function onCheckboxClick(aPartId)
|
||||
var checkbox = document.getElementById(aPartId + "Def");
|
||||
if (checkbox.checked) {
|
||||
SitePermissions.remove(gPermURI, aPartId);
|
||||
if (aPartId == "indexedDB") {
|
||||
SitePermissions.remove(gPermURI, "indexedDB-unlimited");
|
||||
}
|
||||
command.setAttribute("disabled", "true");
|
||||
var perm = SitePermissions.getDefault(aPartId);
|
||||
setRadioState(aPartId, perm);
|
||||
@ -206,6 +209,7 @@ function onIndexedDBClear()
|
||||
.getService(nsIQuotaManager)
|
||||
.clearStoragesForURI(gPermURI);
|
||||
|
||||
SitePermissions.remove(gPermURI, "indexedDB");
|
||||
SitePermissions.remove(gPermURI, "indexedDB-unlimited");
|
||||
initIndexedDBRow();
|
||||
}
|
||||
|
@ -717,6 +717,24 @@ function injectLoopAPI(targetWindow) {
|
||||
|
||||
request.send();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Associates a session-id and a call-id with a window for debugging.
|
||||
*
|
||||
* @param {string} windowId The window id.
|
||||
* @param {string} sessionId OT session id.
|
||||
* @param {string} callId The callId on the server.
|
||||
*/
|
||||
addConversationContext: {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function(windowId, sessionId, callid) {
|
||||
MozLoopService.addConversationContext(windowId, {
|
||||
sessionId: sessionId,
|
||||
callId: callid
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -120,6 +120,8 @@ let gConversationWindowData = new Map();
|
||||
* and register with the Loop server.
|
||||
*/
|
||||
let MozLoopServiceInternal = {
|
||||
conversationContexts: new Map(),
|
||||
|
||||
mocks: {
|
||||
pushHandler: undefined,
|
||||
webSocket: undefined,
|
||||
@ -817,6 +819,22 @@ let MozLoopServiceInternal = {
|
||||
if (winID != ourID) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Chat Window Id, this is different that the internal winId
|
||||
let windowId = window.location.hash.slice(1);
|
||||
var context = this.conversationContexts.get(windowId);
|
||||
var exists = pc.id.match(/session=(\S+)/);
|
||||
if (context && !exists) {
|
||||
// Not ideal but insert our data amidst existing data like this:
|
||||
// - 000 (id=00 url=http)
|
||||
// + 000 (session=000 call=000 id=00 url=http)
|
||||
var pair = pc.id.split("("); //)
|
||||
if (pair.length == 2) {
|
||||
pc.id = pair[0] + "(session=" + context.sessionId +
|
||||
(context.callId? " call=" + context.callId : "") + " " + pair[1]; //)
|
||||
}
|
||||
}
|
||||
|
||||
if (type == "iceconnectionstatechange") {
|
||||
switch(pc.iceConnectionState) {
|
||||
case "failed":
|
||||
@ -1485,5 +1503,13 @@ this.MozLoopService = {
|
||||
|
||||
log.error("Window data was already fetched before. Possible race condition!");
|
||||
return null;
|
||||
},
|
||||
|
||||
getConversationContext: function(winId) {
|
||||
return MozLoopServiceInternal.conversationContexts.get(winId);
|
||||
},
|
||||
|
||||
addConversationContext: function(windowId, context) {
|
||||
MozLoopServiceInternal.conversationContexts.set(windowId, context);
|
||||
}
|
||||
};
|
||||
|
@ -675,10 +675,10 @@ loop.conversation = (function(mozL10n) {
|
||||
|
||||
// XXX Old class creation for the incoming conversation view, whilst
|
||||
// we transition across (bug 1072323).
|
||||
var conversation = new sharedModels.ConversationModel(
|
||||
{}, // Model attributes
|
||||
{sdk: window.OT} // Model dependencies
|
||||
);
|
||||
var conversation = new sharedModels.ConversationModel({}, {
|
||||
sdk: window.OT,
|
||||
mozLoop: navigator.mozLoop
|
||||
});
|
||||
|
||||
// Obtain the windowId and pass it through
|
||||
var helper = new loop.shared.utils.Helper();
|
||||
|
@ -675,10 +675,10 @@ loop.conversation = (function(mozL10n) {
|
||||
|
||||
// XXX Old class creation for the incoming conversation view, whilst
|
||||
// we transition across (bug 1072323).
|
||||
var conversation = new sharedModels.ConversationModel(
|
||||
{}, // Model attributes
|
||||
{sdk: window.OT} // Model dependencies
|
||||
);
|
||||
var conversation = new sharedModels.ConversationModel({}, {
|
||||
sdk: window.OT,
|
||||
mozLoop: navigator.mozLoop
|
||||
});
|
||||
|
||||
// Obtain the windowId and pass it through
|
||||
var helper = new loop.shared.utils.Helper();
|
||||
|
@ -161,7 +161,8 @@ loop.store.ActiveRoomStore = (function() {
|
||||
this._registerPostSetupActions();
|
||||
|
||||
this.setStoreState({
|
||||
roomState: ROOM_STATES.GATHER
|
||||
roomState: ROOM_STATES.GATHER,
|
||||
windowId: actionData.windowId
|
||||
});
|
||||
|
||||
// Get the window data from the mozLoop api.
|
||||
@ -307,6 +308,9 @@ loop.store.ActiveRoomStore = (function() {
|
||||
this._setRefreshTimeout(actionData.expires);
|
||||
this._sdkDriver.connectSession(actionData);
|
||||
|
||||
this._mozLoop.addConversationContext(this._storeState.windowId,
|
||||
actionData.sessionId, "");
|
||||
|
||||
// If we haven't got a room name yet, go and get one. We typically
|
||||
// need to do this in the case of the standalone window.
|
||||
// XXX When bug 1103331 lands this can be moved to earlier.
|
||||
|
@ -170,6 +170,9 @@ loop.store.ConversationStore = (function() {
|
||||
sessionId: this.get("sessionId"),
|
||||
sessionToken: this.get("sessionToken")
|
||||
});
|
||||
navigator.mozLoop.addConversationContext(this.get("windowId"),
|
||||
this.get("sessionId"),
|
||||
this.get("callId"));
|
||||
this.set({callState: CALL_STATES.ONGOING});
|
||||
break;
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ loop.shared.models = (function(l10n) {
|
||||
* Constructor.
|
||||
*
|
||||
* Options:
|
||||
* - {OT} mozLoop: browser mozLoop service object.
|
||||
*
|
||||
* Required:
|
||||
* - {OT} sdk: OT SDK object.
|
||||
@ -66,6 +67,7 @@ loop.shared.models = (function(l10n) {
|
||||
*/
|
||||
initialize: function(attributes, options) {
|
||||
options = options || {};
|
||||
this.mozLoop = options.mozLoop;
|
||||
if (!options.sdk) {
|
||||
throw new Error("missing required sdk");
|
||||
}
|
||||
@ -186,6 +188,13 @@ loop.shared.models = (function(l10n) {
|
||||
this._sessionDisconnected);
|
||||
this.session.connect(this.get("apiKey"), this.get("sessionToken"),
|
||||
this._onConnectCompletion.bind(this));
|
||||
|
||||
// We store the call credentials for debugging purposes.
|
||||
if (this.mozLoop) {
|
||||
this.mozLoop.addConversationContext(this.get("windowId"),
|
||||
this.get("sessionId"),
|
||||
this.get("callId"));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -263,7 +263,11 @@ loop.StandaloneMozLoop = (function(mozL10n) {
|
||||
*/
|
||||
getLoopPref: function(prefName) {
|
||||
return localStorage.getItem(prefName);
|
||||
}
|
||||
},
|
||||
|
||||
// Dummy function to reflect those in the desktop mozLoop that we
|
||||
// don't currently use.
|
||||
addConversationContext: function() {}
|
||||
};
|
||||
|
||||
return StandaloneMozLoop;
|
||||
|
@ -21,6 +21,7 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
|
||||
fakeMozLoop = {
|
||||
setLoopPref: sandbox.stub(),
|
||||
addConversationContext: sandbox.stub(),
|
||||
rooms: {
|
||||
get: sinon.stub(),
|
||||
join: sinon.stub(),
|
||||
@ -398,6 +399,7 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
apiKey: "9876543210",
|
||||
sessionToken: "12563478",
|
||||
sessionId: "15263748",
|
||||
windowId: "42",
|
||||
expires: 20
|
||||
};
|
||||
|
||||
@ -431,6 +433,21 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
actionData);
|
||||
});
|
||||
|
||||
it("should call mozLoop.addConversationContext", function() {
|
||||
var actionData = new sharedActions.JoinedRoom(fakeJoinedData);
|
||||
|
||||
store.setupWindowData(new sharedActions.SetupWindowData({
|
||||
windowId: "42",
|
||||
type: "room",
|
||||
}));
|
||||
|
||||
store.joinedRoom(actionData);
|
||||
|
||||
sinon.assert.calledOnce(fakeMozLoop.addConversationContext);
|
||||
sinon.assert.calledWithExactly(fakeMozLoop.addConversationContext,
|
||||
"42", "15263748", "");
|
||||
});
|
||||
|
||||
it("should call mozLoop.rooms.get to get the room data if the roomName" +
|
||||
"is not known", function() {
|
||||
store.setStoreState({roomName: undefined});
|
||||
|
@ -38,6 +38,7 @@ describe("loop.store.ConversationStore", function () {
|
||||
|
||||
navigator.mozLoop = {
|
||||
getLoopPref: sandbox.stub(),
|
||||
addConversationContext: sandbox.stub(),
|
||||
calls: {
|
||||
setCallInProgress: sandbox.stub(),
|
||||
clearCallInProgress: sandbox.stub()
|
||||
@ -75,6 +76,7 @@ describe("loop.store.ConversationStore", function () {
|
||||
sessionId: "321456",
|
||||
sessionToken: "341256",
|
||||
websocketToken: "543216",
|
||||
windowId: "28",
|
||||
progressURL: "fakeURL"
|
||||
};
|
||||
|
||||
@ -222,6 +224,17 @@ describe("loop.store.ConversationStore", function () {
|
||||
sessionToken: "341256"
|
||||
});
|
||||
});
|
||||
|
||||
it("should call mozLoop.addConversationContext", function() {
|
||||
store.set(fakeSessionData);
|
||||
|
||||
store.connectionProgress(
|
||||
new sharedActions.ConnectionProgress({wsState: WS_STATES.CONNECTING}));
|
||||
|
||||
sinon.assert.calledOnce(navigator.mozLoop.addConversationContext);
|
||||
sinon.assert.calledWithExactly(navigator.mozLoop.addConversationContext,
|
||||
"28", "321456", "142536");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -9,8 +9,8 @@ var expect = chai.expect;
|
||||
describe("loop.shared.models", function() {
|
||||
"use strict";
|
||||
|
||||
var sharedModels = loop.shared.models,
|
||||
sandbox, fakeXHR, requests = [], fakeSDK, fakeSession, fakeSessionData;
|
||||
var sharedModels = loop.shared.models, sandbox, fakeXHR,
|
||||
requests = [], fakeSDK, fakeMozLoop, fakeSession, fakeSessionData;
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox = sinon.sandbox.create();
|
||||
@ -42,6 +42,7 @@ describe("loop.shared.models", function() {
|
||||
initPublisher: sandbox.spy(),
|
||||
initSession: sandbox.stub().returns(fakeSession)
|
||||
};
|
||||
fakeMozLoop = {};
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
@ -63,6 +64,7 @@ describe("loop.shared.models", function() {
|
||||
beforeEach(function() {
|
||||
conversation = new sharedModels.ConversationModel({}, {
|
||||
sdk: fakeSDK
|
||||
mozLoop: fakeMozLoop
|
||||
});
|
||||
conversation.set("loopToken", "fakeToken");
|
||||
});
|
||||
@ -159,7 +161,8 @@ describe("loop.shared.models", function() {
|
||||
|
||||
beforeEach(function() {
|
||||
model = new sharedModels.ConversationModel(fakeSessionData, {
|
||||
sdk: fakeSDK
|
||||
sdk: fakeSDK,
|
||||
mozLoop: fakeMozLoop
|
||||
});
|
||||
model.set({
|
||||
publishedStream: true,
|
||||
@ -177,6 +180,21 @@ describe("loop.shared.models", function() {
|
||||
expect(model.get("subscribedStream")).eql(false);
|
||||
});
|
||||
|
||||
it("should call addConversationContext", function() {
|
||||
fakeMozLoop.addConversationContext = sandbox.stub();
|
||||
|
||||
model.set({
|
||||
windowId: "28",
|
||||
sessionId: "321456",
|
||||
callId: "142536",
|
||||
});
|
||||
model.startSession();
|
||||
|
||||
sinon.assert.calledOnce(fakeMozLoop.addConversationContext);
|
||||
sinon.assert.calledWithExactly(fakeMozLoop.addConversationContext,
|
||||
"28", "321456", "142536");
|
||||
});
|
||||
|
||||
it("should call connect", function() {
|
||||
fakeSession.connect = sandbox.stub();
|
||||
|
||||
|
@ -115,13 +115,6 @@ this.SitePermissions = {
|
||||
* a UI for managing permissions.
|
||||
*/
|
||||
getStateLabel: function (aPermissionID, aState) {
|
||||
if (aPermissionID in gPermissionObject &&
|
||||
gPermissionObject[aPermissionID].getStateLabel) {
|
||||
let label = gPermissionObject[aPermissionID].getStateLabel(aState);
|
||||
if (label)
|
||||
return label;
|
||||
}
|
||||
|
||||
switch (aState) {
|
||||
case this.UNKNOWN:
|
||||
return gStringBundle.GetStringFromName("alwaysAsk");
|
||||
@ -151,11 +144,6 @@ let gPermissionObject = {
|
||||
* Defaults to UNKNOWN, indicating that the user will be asked each time
|
||||
* a page asks for that permissions.
|
||||
*
|
||||
* - getStateLabel
|
||||
* Called to get the localized label for the given permission state, to be
|
||||
* used in a UI for managing permissions. May return null for states that
|
||||
* should use their default label.
|
||||
*
|
||||
* - onChange
|
||||
* Called when a permission state changes.
|
||||
*
|
||||
@ -208,21 +196,8 @@ let gPermissionObject = {
|
||||
},
|
||||
|
||||
"indexedDB": {
|
||||
states: [ SitePermissions.ALLOW, SitePermissions.UNKNOWN, SitePermissions.BLOCK ],
|
||||
getStateLabel: function (aState) {
|
||||
// indexedDB redefines nsIPermissionManager.UNKNOWN_ACTION (the default)
|
||||
// as "allow" and nsIPermissionManager.ALLOW_ACTION as "ask the user."
|
||||
switch (aState) {
|
||||
case SitePermissions.UNKNOWN:
|
||||
return gStringBundle.GetStringFromName("allow");
|
||||
case SitePermissions.ALLOW:
|
||||
return gStringBundle.GetStringFromName("alwaysAsk");
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
onChange: function (aURI, aState) {
|
||||
if (aState == SitePermissions.ALLOW || aState == SitePermissions.BLOCK)
|
||||
if (aState == SitePermissions.BLOCK)
|
||||
Services.perms.remove(aURI.host, "indexedDB-unlimited");
|
||||
}
|
||||
},
|
||||
|
@ -65,6 +65,8 @@ this.PermissionsInstaller = {
|
||||
newPermNames = newPermNames.concat(expandedPermNames);
|
||||
}
|
||||
|
||||
newPermNames.push("indexedDB");
|
||||
|
||||
// Add the appcache related permissions.
|
||||
if (newManifest.appcache_path) {
|
||||
newPermNames = newPermNames.concat(["offline-app", "pin-app"]);
|
||||
@ -116,6 +118,8 @@ this.PermissionsInstaller = {
|
||||
break;
|
||||
}
|
||||
|
||||
this._setPermission("indexedDB", "allow", aApp);
|
||||
|
||||
// Add the appcache related permissions. We allow it for all kinds of
|
||||
// apps.
|
||||
if (newManifest.appcache_path) {
|
||||
|
@ -306,8 +306,7 @@ this.PermissionsTable = { geolocation: {
|
||||
privileged: ALLOW_ACTION,
|
||||
certified: ALLOW_ACTION,
|
||||
substitute: [
|
||||
"indexedDB-unlimited",
|
||||
"default-persistent-storage"
|
||||
"indexedDB-unlimited"
|
||||
]
|
||||
},
|
||||
"background-sensors": {
|
||||
@ -645,7 +644,7 @@ this.AllPossiblePermissions = [];
|
||||
}
|
||||
}
|
||||
AllPossiblePermissions =
|
||||
AllPossiblePermissions.concat(["offline-app", "pin-app"]);
|
||||
AllPossiblePermissions.concat(["indexedDB", "offline-app", "pin-app"]);
|
||||
})();
|
||||
|
||||
this.isExplicitInPermissionsTable = function(aPermName, aIntStatus) {
|
||||
|
@ -735,25 +735,12 @@ MainProcessRunnable::InitOnMainThread()
|
||||
NS_ENSURE_STATE(qm);
|
||||
|
||||
nsresult rv =
|
||||
QuotaManager::GetInfoFromPrincipal(mPrincipal,
|
||||
quota::PERSISTENCE_TYPE_INVALID,
|
||||
&mGroup, &mOrigin, &mIsApp,
|
||||
QuotaManager::GetInfoFromPrincipal(mPrincipal, &mGroup, &mOrigin, &mIsApp,
|
||||
&mHasUnlimStoragePerm);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// XXX Don't use mGroup yet! We might need to update it right after we
|
||||
// initialize persistence type.
|
||||
|
||||
InitPersistenceType();
|
||||
|
||||
// XXX Since we couldn't pass persistence type to GetInfoFromPrincipal(),
|
||||
// we need to do this manually.
|
||||
// This hack is only temporary, it will go away once we have regular
|
||||
// metadata files for persistent storge.
|
||||
if (mPersistence == quota::PERSISTENCE_TYPE_PERSISTENT) {
|
||||
mGroup = mOrigin;
|
||||
}
|
||||
|
||||
mEnforcingQuota =
|
||||
QuotaManager::IsQuotaEnforced(mPersistence, mOrigin, mIsApp,
|
||||
mHasUnlimStoragePerm);
|
||||
@ -1843,7 +1830,7 @@ public:
|
||||
|
||||
virtual void
|
||||
OnOriginClearCompleted(PersistenceType aPersistenceType,
|
||||
const OriginOrPatternString& aOriginOrPattern)
|
||||
const nsACString& aOrigin)
|
||||
MOZ_OVERRIDE
|
||||
{ }
|
||||
|
||||
|
@ -3119,6 +3119,12 @@ nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId,
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
|
||||
|
||||
nsCString origin;
|
||||
nsresult rv =
|
||||
quota::QuotaManager::GetInfoFromWindow(window, nullptr, &origin, nullptr,
|
||||
nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
IDBOpenDBOptions options;
|
||||
JS::Rooted<JS::Value> optionsVal(aCx, aOptions);
|
||||
if (!options.Init(aCx, optionsVal)) {
|
||||
@ -3128,12 +3134,6 @@ nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId,
|
||||
quota::PersistenceType persistenceType =
|
||||
quota::PersistenceTypeFromStorage(options.mStorage);
|
||||
|
||||
nsCString origin;
|
||||
nsresult rv =
|
||||
quota::QuotaManager::GetInfoFromWindow(window, persistenceType, nullptr,
|
||||
&origin, nullptr, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRefPtr<indexedDB::IndexedDatabaseManager> mgr =
|
||||
indexedDB::IndexedDatabaseManager::Get();
|
||||
|
||||
|
@ -1612,7 +1612,7 @@ nsFocusManager::Blur(nsPIDOMWindow* aWindowToClear,
|
||||
|
||||
nsRefPtr<SelectionCarets> selectionCarets = presShell->GetSelectionCarets();
|
||||
if (selectionCarets) {
|
||||
selectionCarets->SetVisibility(false);
|
||||
selectionCarets->NotifyBlur();
|
||||
}
|
||||
|
||||
bool clearFirstBlurEvent = false;
|
||||
|
@ -2235,6 +2235,7 @@ GK_ATOM(aria_label, "aria-label")
|
||||
GK_ATOM(aria_labelledby, "aria-labelledby")
|
||||
GK_ATOM(aria_level, "aria-level")
|
||||
GK_ATOM(aria_live, "aria-live")
|
||||
GK_ATOM(aria_modal, "aria-modal")
|
||||
GK_ATOM(aria_multiline, "aria-multiline")
|
||||
GK_ATOM(aria_multiselectable, "aria-multiselectable")
|
||||
GK_ATOM(aria_orientation, "aria-orientation")
|
||||
|
@ -40,8 +40,6 @@
|
||||
#include "nsWindowMemoryReporter.h"
|
||||
#include "WindowNamedPropertiesHandler.h"
|
||||
#include "nsFrameSelection.h"
|
||||
#include "nsISelectionListener.h"
|
||||
#include "nsCaret.h"
|
||||
|
||||
// Helper Classes
|
||||
#include "nsJSUtils.h"
|
||||
@ -194,8 +192,6 @@
|
||||
|
||||
#include "nsRefreshDriver.h"
|
||||
|
||||
#include "mozilla/dom/SelectionChangeEvent.h"
|
||||
|
||||
#include "mozilla/AddonPathService.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
@ -275,7 +271,6 @@ static PopupControlState gPopupControlState = openAbused;
|
||||
static int32_t gRunningTimeoutDepth = 0;
|
||||
static bool gMouseDown = false;
|
||||
static bool gDragServiceDisabled = false;
|
||||
static bool gSelectionCaretPrefEnabled = false;
|
||||
static FILE *gDumpFile = nullptr;
|
||||
static uint64_t gNextWindowID = 0;
|
||||
static uint32_t gSerialCounter = 0;
|
||||
@ -1191,9 +1186,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
|
||||
Preferences::AddBoolVarCache(&sIdleObserversAPIFuzzTimeDisabled,
|
||||
"dom.idle-observers-api.fuzz_time.disabled",
|
||||
false);
|
||||
Preferences::AddBoolVarCache(&gSelectionCaretPrefEnabled,
|
||||
"selectioncaret.enabled",
|
||||
false);
|
||||
}
|
||||
|
||||
if (gDumpFile == nullptr) {
|
||||
@ -9293,61 +9285,6 @@ public:
|
||||
nsString mAction;
|
||||
};
|
||||
|
||||
static bool
|
||||
CheckReason(int16_t aReason, SelectionChangeReason aReasonType)
|
||||
{
|
||||
switch (aReasonType) {
|
||||
case SelectionChangeReason::Drag:
|
||||
return aReason & nsISelectionListener::DRAG_REASON;
|
||||
case SelectionChangeReason::Mousedown:
|
||||
return aReason & nsISelectionListener::MOUSEDOWN_REASON;
|
||||
case SelectionChangeReason::Mouseup:
|
||||
return aReason & nsISelectionListener::MOUSEUP_REASON;
|
||||
case SelectionChangeReason::Keypress:
|
||||
return aReason & nsISelectionListener::KEYPRESS_REASON;
|
||||
case SelectionChangeReason::Selectall:
|
||||
return aReason & nsISelectionListener::SELECTALL_REASON;
|
||||
case SelectionChangeReason::Collapsetostart:
|
||||
return aReason & nsISelectionListener::COLLAPSETOSTART_REASON;
|
||||
case SelectionChangeReason::Collapsetoend:
|
||||
return aReason & nsISelectionListener::COLLAPSETOEND_REASON;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static nsRect
|
||||
GetSelectionBoundingRect(Selection* aSel, nsIPresShell* aShell)
|
||||
{
|
||||
nsRect res;
|
||||
// Bounding client rect may be empty after calling GetBoundingClientRect
|
||||
// when range is collapsed. So we get caret's rect when range is
|
||||
// collapsed.
|
||||
if (aSel->IsCollapsed()) {
|
||||
aShell->FlushPendingNotifications(Flush_Layout);
|
||||
nsIFrame* frame = nsCaret::GetGeometry(aSel, &res);
|
||||
if (frame) {
|
||||
nsIFrame* relativeTo =
|
||||
nsLayoutUtils::GetContainingBlockForClientRect(frame);
|
||||
res = nsLayoutUtils::TransformFrameRectToAncestor(frame, res, relativeTo);
|
||||
}
|
||||
} else {
|
||||
int32_t rangeCount = aSel->GetRangeCount();
|
||||
nsLayoutUtils::RectAccumulator accumulator;
|
||||
for (int32_t idx = 0; idx < rangeCount; ++idx) {
|
||||
nsRange* range = aSel->GetRangeAt(idx);
|
||||
nsRange::CollectClientRects(&accumulator, range,
|
||||
range->GetStartParent(), range->StartOffset(),
|
||||
range->GetEndParent(), range->EndOffset(),
|
||||
true, false);
|
||||
}
|
||||
res = accumulator.mResultRect.IsEmpty() ? accumulator.mFirstRect :
|
||||
accumulator.mResultRect;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::UpdateCommands(const nsAString& anAction, nsISelection* aSel, int16_t aReason)
|
||||
{
|
||||
@ -9370,55 +9307,6 @@ nsGlobalWindow::UpdateCommands(const nsAString& anAction, nsISelection* aSel, in
|
||||
}
|
||||
}
|
||||
|
||||
if (gSelectionCaretPrefEnabled && mDoc && anAction.EqualsLiteral("selectionchange")) {
|
||||
SelectionChangeEventInit init;
|
||||
init.mBubbles = true;
|
||||
if (aSel) {
|
||||
bool isTouchCaretVisible = false;
|
||||
bool isCollapsed = aSel->Collapsed();
|
||||
|
||||
nsIPresShell *shell = mDoc->GetShell();
|
||||
if (shell) {
|
||||
nsRefPtr<TouchCaret> touchCaret = shell->GetTouchCaret();
|
||||
if (touchCaret) {
|
||||
isTouchCaretVisible = touchCaret->GetVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatch selection change events when touch caret is visible even if selection
|
||||
// is collapsed because it could be the shortcut mode, otherwise ignore this
|
||||
// UpdateCommands
|
||||
if (isCollapsed && !isTouchCaretVisible) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Selection* selection = static_cast<Selection*>(aSel);
|
||||
nsRect rect = GetSelectionBoundingRect(selection, mDoc->GetShell());
|
||||
nsRefPtr<DOMRect> domRect = new DOMRect(ToSupports(this));
|
||||
domRect->SetLayoutRect(rect);
|
||||
init.mBoundingClientRect = domRect;
|
||||
|
||||
selection->Stringify(init.mSelectedText);
|
||||
for (uint32_t reasonType = 0;
|
||||
reasonType < static_cast<uint32_t>(SelectionChangeReason::EndGuard_);
|
||||
++reasonType) {
|
||||
SelectionChangeReason strongReasonType =
|
||||
static_cast<SelectionChangeReason>(reasonType);
|
||||
if (CheckReason(aReason, strongReasonType)) {
|
||||
init.mReasons.AppendElement(strongReasonType);
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<SelectionChangeEvent> event =
|
||||
SelectionChangeEvent::Constructor(mDoc, NS_LITERAL_STRING("mozselectionchange"), init);
|
||||
|
||||
event->SetTrusted(true);
|
||||
event->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
|
||||
bool ret;
|
||||
mDoc->DispatchEvent(event, &ret);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -4,33 +4,17 @@
|
||||
* 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 "base/basictypes.h"
|
||||
|
||||
#include "BluetoothUtils.h"
|
||||
#include "BluetoothReplyRunnable.h"
|
||||
#include "BluetoothService.h"
|
||||
#include "BluetoothServiceBluedroid.h"
|
||||
#include "BluetoothUtils.h"
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/Scoped.h"
|
||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsISystemMessagesInternal.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
uint16_t
|
||||
UuidToServiceClassInt(const BluetoothUuid& mUuid)
|
||||
{
|
||||
// extract short UUID 0000xxxx-0000-1000-8000-00805f9b34fb
|
||||
uint16_t shortUuid;
|
||||
memcpy(&shortUuid, mUuid.mUuid + 2, sizeof(uint16_t));
|
||||
return ntohs(shortUuid);
|
||||
}
|
||||
|
||||
bool
|
||||
SetJsObject(JSContext* aContext,
|
||||
const BluetoothValue& aValue,
|
||||
@ -123,6 +107,37 @@ BroadcastSystemMessage(const nsAString& aType,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BroadcastSystemMessage(const nsAString& aType,
|
||||
const InfallibleTArray<BluetoothNamedValue>& aData)
|
||||
{
|
||||
mozilla::AutoSafeJSContext cx;
|
||||
NS_ASSERTION(!::JS_IsExceptionPending(cx),
|
||||
"Shouldn't get here when an exception is pending!");
|
||||
|
||||
JS::Rooted<JSObject*> obj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(),
|
||||
JS::NullPtr()));
|
||||
if (!obj) {
|
||||
BT_WARNING("Failed to new JSObject for system message!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SetJsObject(cx, aData, obj)) {
|
||||
BT_WARNING("Failed to set properties of system message!");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISystemMessagesInternal> systemMessenger =
|
||||
do_GetService("@mozilla.org/system-message-internal;1");
|
||||
NS_ENSURE_TRUE(systemMessenger, false);
|
||||
|
||||
JS::Rooted<JS::Value> value(cx, JS::ObjectValue(*obj));
|
||||
systemMessenger->BroadcastMessage(aType, value,
|
||||
JS::UndefinedHandleValue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
|
||||
const BluetoothValue& aValue,
|
@ -4,8 +4,8 @@
|
||||
* 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_bluetoothutils_h__
|
||||
#define mozilla_dom_bluetooth_bluetoothutils_h__
|
||||
#ifndef mozilla_dom_bluetooth_bluetoothutils_h
|
||||
#define mozilla_dom_bluetooth_bluetoothutils_h
|
||||
|
||||
#include "BluetoothCommon.h"
|
||||
#include "js/TypeDecls.h"
|
||||
@ -16,9 +16,6 @@ class BluetoothNamedValue;
|
||||
class BluetoothValue;
|
||||
class BluetoothReplyRunnable;
|
||||
|
||||
uint16_t
|
||||
UuidToServiceClassInt(const BluetoothUuid& mUuid);
|
||||
|
||||
bool
|
||||
SetJsObject(JSContext* aContext,
|
||||
const BluetoothValue& aValue,
|
||||
@ -28,6 +25,10 @@ bool
|
||||
BroadcastSystemMessage(const nsAString& aType,
|
||||
const BluetoothValue& aData);
|
||||
|
||||
bool
|
||||
BroadcastSystemMessage(const nsAString& aType,
|
||||
const InfallibleTArray<BluetoothNamedValue>& aData);
|
||||
|
||||
void
|
||||
DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
|
||||
const BluetoothValue& aValue,
|
@ -1098,6 +1098,15 @@ BluetoothServiceBluedroid::ToggleCalls(BluetoothReplyRunnable* aRunnable)
|
||||
{
|
||||
}
|
||||
|
||||
uint16_t
|
||||
BluetoothServiceBluedroid::UuidToServiceClassInt(const BluetoothUuid& mUuid)
|
||||
{
|
||||
// extract short UUID 0000xxxx-0000-1000-8000-00805f9b34fb
|
||||
uint16_t shortUuid;
|
||||
memcpy(&shortUuid, mUuid.mUuid + 2, sizeof(uint16_t));
|
||||
return ntohs(shortUuid);
|
||||
}
|
||||
|
||||
//
|
||||
// Bluetooth notifications
|
||||
//
|
||||
|
@ -221,6 +221,8 @@ protected:
|
||||
|
||||
static ControlPlayStatus PlayStatusStringToControlPlayStatus(
|
||||
const nsAString& aPlayStatus);
|
||||
|
||||
uint16_t UuidToServiceClassInt(const BluetoothUuid& mUuid);
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
@ -392,6 +392,37 @@ BluetoothDBusService::~BluetoothDBusService()
|
||||
sGetPropertyMonitor = nullptr;
|
||||
}
|
||||
|
||||
static nsString
|
||||
GetObjectPathFromAddress(const nsAString& aAdapterPath,
|
||||
const nsAString& aDeviceAddress)
|
||||
{
|
||||
// The object path would be like /org/bluez/2906/hci0/dev_00_23_7F_CB_B4_F1,
|
||||
// and the adapter path would be the first part of the object path, according
|
||||
// to the example above, it's /org/bluez/2906/hci0.
|
||||
nsString devicePath(aAdapterPath);
|
||||
devicePath.AppendLiteral("/dev_");
|
||||
devicePath.Append(aDeviceAddress);
|
||||
devicePath.ReplaceChar(':', '_');
|
||||
return devicePath;
|
||||
}
|
||||
|
||||
static nsString
|
||||
GetAddressFromObjectPath(const nsAString& aObjectPath)
|
||||
{
|
||||
// The object path would be like /org/bluez/2906/hci0/dev_00_23_7F_CB_B4_F1,
|
||||
// and the adapter path would be the first part of the object path, according
|
||||
// to the example above, it's /org/bluez/2906/hci0.
|
||||
nsString address(aObjectPath);
|
||||
int addressHead = address.RFind("/") + 5;
|
||||
|
||||
MOZ_ASSERT(addressHead + BLUETOOTH_ADDRESS_LENGTH == (int)address.Length());
|
||||
|
||||
address.Cut(0, addressHead);
|
||||
address.ReplaceChar('_', ':');
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetConnectedDevicesFilter(const BluetoothValue& aValue)
|
||||
{
|
||||
|
@ -690,6 +690,28 @@ BluetoothHfpManager::HandleShutdown()
|
||||
sBluetoothHfpManager = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothHfpManager::ParseAtCommand(const nsACString& aAtCommand,
|
||||
const int aStart,
|
||||
nsTArray<nsCString>& aRetValues)
|
||||
{
|
||||
int length = aAtCommand.Length();
|
||||
int begin = aStart;
|
||||
|
||||
for (int i = aStart; i < length; ++i) {
|
||||
// Use ',' as separator
|
||||
if (aAtCommand[i] == ',') {
|
||||
nsCString tmp(nsDependentCSubstring(aAtCommand, begin, i - begin));
|
||||
aRetValues.AppendElement(tmp);
|
||||
|
||||
begin = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
nsCString tmp(nsDependentCSubstring(aAtCommand, begin));
|
||||
aRetValues.AppendElement(tmp);
|
||||
}
|
||||
|
||||
// Virtual function of class SocketConsumer
|
||||
void
|
||||
BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
||||
|
@ -132,6 +132,9 @@ public:
|
||||
#endif
|
||||
|
||||
private:
|
||||
void ParseAtCommand(const nsACString& aAtCommand, const int aStart,
|
||||
nsTArray<nsCString>& aRetValues);
|
||||
|
||||
class CloseScoTask;
|
||||
class GetVolumeTask;
|
||||
#ifdef MOZ_B2G_RIL
|
||||
|
@ -1,198 +0,0 @@
|
||||
/* -*- 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 "base/basictypes.h"
|
||||
|
||||
#include "BluetoothReplyRunnable.h"
|
||||
#include "BluetoothService.h"
|
||||
#include "BluetoothUtils.h"
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/Scoped.h"
|
||||
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsISystemMessagesInternal.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
bool
|
||||
SetJsObject(JSContext* aContext,
|
||||
const BluetoothValue& aValue,
|
||||
JS::Handle<JSObject*> aObj)
|
||||
{
|
||||
MOZ_ASSERT(aContext && aObj);
|
||||
|
||||
if (aValue.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
|
||||
BT_WARNING("SetJsObject: Invalid parameter type");
|
||||
return false;
|
||||
}
|
||||
|
||||
const nsTArray<BluetoothNamedValue>& arr =
|
||||
aValue.get_ArrayOfBluetoothNamedValue();
|
||||
|
||||
for (uint32_t i = 0; i < arr.Length(); i++) {
|
||||
JS::Rooted<JS::Value> val(aContext);
|
||||
const BluetoothValue& v = arr[i].value();
|
||||
|
||||
switch(v.type()) {
|
||||
case BluetoothValue::TnsString: {
|
||||
JSString* jsData = JS_NewUCStringCopyN(aContext,
|
||||
v.get_nsString().BeginReading(),
|
||||
v.get_nsString().Length());
|
||||
NS_ENSURE_TRUE(jsData, false);
|
||||
val = STRING_TO_JSVAL(jsData);
|
||||
break;
|
||||
}
|
||||
case BluetoothValue::Tuint32_t:
|
||||
val = INT_TO_JSVAL(v.get_uint32_t());
|
||||
break;
|
||||
case BluetoothValue::Tbool:
|
||||
val = BOOLEAN_TO_JSVAL(v.get_bool());
|
||||
break;
|
||||
default:
|
||||
BT_WARNING("SetJsObject: Parameter is not handled");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!JS_SetProperty(aContext, aObj,
|
||||
NS_ConvertUTF16toUTF8(arr[i].name()).get(),
|
||||
val)) {
|
||||
BT_WARNING("Failed to set property");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsString
|
||||
GetObjectPathFromAddress(const nsAString& aAdapterPath,
|
||||
const nsAString& aDeviceAddress)
|
||||
{
|
||||
// The object path would be like /org/bluez/2906/hci0/dev_00_23_7F_CB_B4_F1,
|
||||
// and the adapter path would be the first part of the object path, according
|
||||
// to the example above, it's /org/bluez/2906/hci0.
|
||||
nsString devicePath(aAdapterPath);
|
||||
devicePath.AppendLiteral("/dev_");
|
||||
devicePath.Append(aDeviceAddress);
|
||||
devicePath.ReplaceChar(':', '_');
|
||||
return devicePath;
|
||||
}
|
||||
|
||||
nsString
|
||||
GetAddressFromObjectPath(const nsAString& aObjectPath)
|
||||
{
|
||||
// The object path would be like /org/bluez/2906/hci0/dev_00_23_7F_CB_B4_F1,
|
||||
// and the adapter path would be the first part of the object path, according
|
||||
// to the example above, it's /org/bluez/2906/hci0.
|
||||
nsString address(aObjectPath);
|
||||
int addressHead = address.RFind("/") + 5;
|
||||
|
||||
MOZ_ASSERT(addressHead + BLUETOOTH_ADDRESS_LENGTH == (int)address.Length());
|
||||
|
||||
address.Cut(0, addressHead);
|
||||
address.ReplaceChar('_', ':');
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
bool
|
||||
BroadcastSystemMessage(const nsAString& aType,
|
||||
const InfallibleTArray<BluetoothNamedValue>& aData)
|
||||
{
|
||||
mozilla::AutoSafeJSContext cx;
|
||||
NS_ASSERTION(!::JS_IsExceptionPending(cx),
|
||||
"Shouldn't get here when an exception is pending!");
|
||||
|
||||
JS::Rooted<JSObject*> obj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(),
|
||||
JS::NullPtr()));
|
||||
if (!obj) {
|
||||
BT_WARNING("Failed to new JSObject for system message!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SetJsObject(cx, aData, obj)) {
|
||||
BT_WARNING("Failed to set properties of system message!");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISystemMessagesInternal> systemMessenger =
|
||||
do_GetService("@mozilla.org/system-message-internal;1");
|
||||
NS_ENSURE_TRUE(systemMessenger, false);
|
||||
|
||||
JS::Rooted<JS::Value> value(cx, JS::ObjectValue(*obj));
|
||||
systemMessenger->BroadcastMessage(aType, value,
|
||||
JS::UndefinedHandleValue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
|
||||
const BluetoothValue& aValue,
|
||||
const nsAString& aErrorStr)
|
||||
{
|
||||
// Reply will be deleted by the runnable after running on main thread
|
||||
BluetoothReply* reply;
|
||||
if (!aErrorStr.IsEmpty()) {
|
||||
nsString err(aErrorStr);
|
||||
reply = new BluetoothReply(BluetoothReplyError(err));
|
||||
} else {
|
||||
MOZ_ASSERT(aValue.type() != BluetoothValue::T__None);
|
||||
reply = new BluetoothReply(BluetoothReplySuccess(aValue));
|
||||
}
|
||||
|
||||
aRunnable->SetReply(reply);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(aRunnable))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ParseAtCommand(const nsACString& aAtCommand, const int aStart,
|
||||
nsTArray<nsCString>& aRetValues)
|
||||
{
|
||||
int length = aAtCommand.Length();
|
||||
int begin = aStart;
|
||||
|
||||
for (int i = aStart; i < length; ++i) {
|
||||
// Use ',' as separator
|
||||
if (aAtCommand[i] == ',') {
|
||||
nsCString tmp(nsDependentCSubstring(aAtCommand, begin, i - begin));
|
||||
aRetValues.AppendElement(tmp);
|
||||
|
||||
begin = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
nsCString tmp(nsDependentCSubstring(aAtCommand, begin));
|
||||
aRetValues.AppendElement(tmp);
|
||||
}
|
||||
|
||||
void
|
||||
DispatchStatusChangedEvent(const nsAString& aType,
|
||||
const nsAString& aAddress,
|
||||
bool aStatus)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> data;
|
||||
data.AppendElement(
|
||||
BluetoothNamedValue(NS_LITERAL_STRING("address"), nsString(aAddress)));
|
||||
data.AppendElement(
|
||||
BluetoothNamedValue(NS_LITERAL_STRING("status"), aStatus));
|
||||
|
||||
BluetoothSignal signal(nsString(aType), NS_LITERAL_STRING(KEY_ADAPTER), data);
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
NS_ENSURE_TRUE_VOID(bs);
|
||||
bs->DistributeSignal(signal);
|
||||
}
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
@ -1,51 +0,0 @@
|
||||
/* -*- 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_bluetoothutils_h__
|
||||
#define mozilla_dom_bluetooth_bluetoothutils_h__
|
||||
|
||||
#include "BluetoothCommon.h"
|
||||
#include "js/TypeDecls.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothNamedValue;
|
||||
class BluetoothValue;
|
||||
class BluetoothReplyRunnable;
|
||||
|
||||
bool
|
||||
SetJsObject(JSContext* aContext,
|
||||
const BluetoothValue& aValue,
|
||||
JS::Handle<JSObject*> aObj);
|
||||
|
||||
nsString
|
||||
GetObjectPathFromAddress(const nsAString& aAdapterPath,
|
||||
const nsAString& aDeviceAddress);
|
||||
|
||||
nsString
|
||||
GetAddressFromObjectPath(const nsAString& aObjectPath);
|
||||
|
||||
bool
|
||||
BroadcastSystemMessage(const nsAString& aType,
|
||||
const InfallibleTArray<BluetoothNamedValue>& aData);
|
||||
|
||||
void
|
||||
DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
|
||||
const BluetoothValue& aValue,
|
||||
const nsAString& aErrorStr);
|
||||
|
||||
void
|
||||
ParseAtCommand(const nsACString& aAtCommand, const int aStart,
|
||||
nsTArray<nsCString>& aRetValues);
|
||||
|
||||
void
|
||||
DispatchStatusChangedEvent(const nsAString& aType,
|
||||
const nsAString& aDeviceAddress,
|
||||
bool aStatus);
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
||||
#endif
|
@ -15,6 +15,7 @@ if CONFIG['MOZ_B2G_BT']:
|
||||
'BluetoothPropertyContainer.cpp',
|
||||
'BluetoothReplyRunnable.cpp',
|
||||
'BluetoothService.cpp',
|
||||
'BluetoothUtils.cpp',
|
||||
'BluetoothUuid.cpp',
|
||||
'ipc/BluetoothChild.cpp',
|
||||
'ipc/BluetoothParent.cpp',
|
||||
@ -36,8 +37,7 @@ if CONFIG['MOZ_B2G_BT']:
|
||||
'bluez/BluetoothHfpManager.cpp',
|
||||
'bluez/BluetoothOppManager.cpp',
|
||||
'bluez/BluetoothSocket.cpp',
|
||||
'bluez/BluetoothUnixSocketConnector.cpp',
|
||||
'bluez/BluetoothUtils.cpp',
|
||||
'bluez/BluetoothUnixSocketConnector.cpp'
|
||||
]
|
||||
LOCAL_INCLUDES += [
|
||||
'bluez',
|
||||
@ -60,8 +60,7 @@ if CONFIG['MOZ_B2G_BT']:
|
||||
'bluedroid/BluetoothServiceBluedroid.cpp',
|
||||
'bluedroid/BluetoothSocket.cpp',
|
||||
'bluedroid/BluetoothSocketHALInterface.cpp',
|
||||
'bluedroid/BluetoothSocketMessageWatcher.cpp',
|
||||
'bluedroid/BluetoothUtils.cpp',
|
||||
'bluedroid/BluetoothSocketMessageWatcher.cpp'
|
||||
]
|
||||
LOCAL_INCLUDES += [
|
||||
'bluedroid',
|
||||
|
@ -145,34 +145,7 @@ BluetoothService::ToggleBtAck::ToggleBtAck(bool aEnabled)
|
||||
NS_METHOD
|
||||
BluetoothService::ToggleBtAck::Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// This is requested in Bug 836516. With settings this property, WLAN
|
||||
// firmware could be aware of Bluetooth has been turned on/off, so that the
|
||||
// mecahnism of handling coexistence of WIFI and Bluetooth could be started.
|
||||
//
|
||||
// In the future, we may have our own way instead of setting a system
|
||||
// property to let firmware developers be able to sense that Bluetooth has
|
||||
// been toggled.
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
if (property_set(PROP_BLUETOOTH_ENABLED, mEnabled ? "true" : "false") != 0) {
|
||||
BT_WARNING("Failed to set bluetooth enabled property");
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_ENSURE_TRUE(sBluetoothService, NS_OK);
|
||||
|
||||
if (sInShutdown) {
|
||||
sBluetoothService = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Update mEnabled of BluetoothService object since
|
||||
// StartInternal/StopInternal have been already done.
|
||||
sBluetoothService->SetEnabled(mEnabled);
|
||||
sToggleInProgress = false;
|
||||
|
||||
sBluetoothService->FireAdapterStateChanged(mEnabled);
|
||||
BluetoothService::AcknowledgeToggleBt(mEnabled);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -709,3 +682,45 @@ BluetoothService::FireAdapterStateChanged(bool aEnable)
|
||||
NS_LITERAL_STRING(KEY_ADAPTER), value);
|
||||
DistributeSignal(signal);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothService::AcknowledgeToggleBt(bool aEnabled)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
// This is requested in Bug 836516. With settings this property, WLAN
|
||||
// firmware could be aware of Bluetooth has been turned on/off, so that the
|
||||
// mecahnism of handling coexistence of WIFI and Bluetooth could be started.
|
||||
//
|
||||
// In the future, we may have our own way instead of setting a system
|
||||
// property to let firmware developers be able to sense that Bluetooth has
|
||||
// been toggled.
|
||||
if (property_set(PROP_BLUETOOTH_ENABLED, aEnabled ? "true" : "false") != 0) {
|
||||
BT_WARNING("Failed to set bluetooth enabled property");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sInShutdown) {
|
||||
sBluetoothService = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE_VOID(sBluetoothService);
|
||||
|
||||
sBluetoothService->CompleteToggleBt(aEnabled);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothService::CompleteToggleBt(bool aEnabled)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Update |mEnabled| of |BluetoothService| object since
|
||||
// |StartInternal| and |StopInternal| have been already
|
||||
// done.
|
||||
SetEnabled(aEnabled);
|
||||
sToggleInProgress = false;
|
||||
|
||||
FireAdapterStateChanged(aEnabled);
|
||||
}
|
||||
|
@ -315,6 +315,8 @@ public:
|
||||
bool
|
||||
IsToggling() const;
|
||||
|
||||
static void AcknowledgeToggleBt(bool aEnabled);
|
||||
|
||||
void FireAdapterStateChanged(bool aEnable);
|
||||
nsresult EnableDisable(bool aEnable,
|
||||
BluetoothReplyRunnable* aRunnable);
|
||||
@ -392,6 +394,8 @@ protected:
|
||||
static BluetoothService*
|
||||
Create();
|
||||
|
||||
void CompleteToggleBt(bool aEnabled);
|
||||
|
||||
typedef nsClassHashtable<nsStringHashKey, BluetoothSignalObserverList >
|
||||
BluetoothSignalObserverTable;
|
||||
|
||||
|
1240
dom/bluetooth2/bluedroid/BluetoothDaemonHandsfreeInterface.cpp
Normal file
1240
dom/bluetooth2/bluedroid/BluetoothDaemonHandsfreeInterface.cpp
Normal file
File diff suppressed because it is too large
Load Diff
412
dom/bluetooth2/bluedroid/BluetoothDaemonHandsfreeInterface.h
Normal file
412
dom/bluetooth2/bluedroid/BluetoothDaemonHandsfreeInterface.h
Normal file
@ -0,0 +1,412 @@
|
||||
/* -*- 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_bluetoothdaemonhandsfreeinterface_h
|
||||
#define mozilla_dom_bluetooth_bluetoothdaemonhandsfreeinterface_h
|
||||
|
||||
#include "BluetoothDaemonHelpers.h"
|
||||
#include "BluetoothInterface.h"
|
||||
#include "BluetoothInterfaceHelpers.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothSetupResultHandler;
|
||||
|
||||
class BluetoothDaemonHandsfreeModule
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
SERVICE_ID = 0x05
|
||||
};
|
||||
|
||||
enum {
|
||||
OPCODE_ERROR = 0x00,
|
||||
OPCODE_CONNECT = 0x01,
|
||||
OPCODE_DISCONNECT = 0x02,
|
||||
OPCODE_CONNECT_AUDIO = 0x03,
|
||||
OPCODE_DISCONNECT_AUDIO = 0x04,
|
||||
OPCODE_START_VOICE_RECOGNITION = 0x05,
|
||||
OPCODE_STOP_VOICE_RECOGNITION =0x06,
|
||||
OPCODE_VOLUME_CONTROL = 0x07,
|
||||
OPCODE_DEVICE_STATUS_NOTIFICATION = 0x08,
|
||||
OPCODE_COPS_RESPONSE = 0x09,
|
||||
OPCODE_CIND_RESPONSE = 0x0a,
|
||||
OPCODE_FORMATTED_AT_RESPONSE = 0x0b,
|
||||
OPCODE_AT_RESPONSE = 0x0c,
|
||||
OPCODE_CLCC_RESPONSE = 0x0d,
|
||||
OPCODE_PHONE_STATE_CHANGE = 0x0e
|
||||
};
|
||||
|
||||
virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0;
|
||||
|
||||
virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode,
|
||||
BluetoothSetupResultHandler* aRes) = 0;
|
||||
|
||||
virtual nsresult UnregisterModule(uint8_t aId,
|
||||
BluetoothSetupResultHandler* aRes) = 0;
|
||||
|
||||
void SetNotificationHandler(
|
||||
BluetoothHandsfreeNotificationHandler* aNotificationHandler);
|
||||
|
||||
//
|
||||
// Commands
|
||||
//
|
||||
|
||||
nsresult ConnectCmd(const nsAString& aBdAddr,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
nsresult DisconnectCmd(const nsAString& aBdAddr,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
nsresult ConnectAudioCmd(const nsAString& aBdAddr,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
nsresult DisconnectAudioCmd(const nsAString& aBdAddr,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
/* Voice Recognition */
|
||||
|
||||
nsresult StartVoiceRecognitionCmd(BluetoothHandsfreeResultHandler* aRes);
|
||||
nsresult StopVoiceRecognitionCmd(BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
/* Volume */
|
||||
|
||||
nsresult VolumeControlCmd(BluetoothHandsfreeVolumeType aType, int aVolume,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
/* Device status */
|
||||
|
||||
nsresult DeviceStatusNotificationCmd(
|
||||
BluetoothHandsfreeNetworkState aNtkState,
|
||||
BluetoothHandsfreeServiceType aSvcType,
|
||||
int aSignal, int aBattChg,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
/* Responses */
|
||||
|
||||
nsresult CopsResponseCmd(const char* aCops,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
nsresult CindResponseCmd(int aSvc, int aNumActive, int aNumHeld,
|
||||
BluetoothHandsfreeCallState aCallSetupState,
|
||||
int aSignal, int aRoam, int aBattChg,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
nsresult FormattedAtResponseCmd(const char* aRsp,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
nsresult AtResponseCmd(BluetoothHandsfreeAtResponse aResponseCode,
|
||||
int aErrorCode,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
nsresult ClccResponseCmd(int aIndex, BluetoothHandsfreeCallDirection aDir,
|
||||
BluetoothHandsfreeCallState aState,
|
||||
BluetoothHandsfreeCallMode aMode,
|
||||
BluetoothHandsfreeCallMptyType aMpty,
|
||||
const nsAString& aNumber,
|
||||
BluetoothHandsfreeCallAddressType aType,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
/* Phone State */
|
||||
|
||||
nsresult PhoneStateChangeCmd(int aNumActive, int aNumHeld,
|
||||
BluetoothHandsfreeCallState aCallSetupState,
|
||||
const nsAString& aNumber,
|
||||
BluetoothHandsfreeCallAddressType aType,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
protected:
|
||||
nsresult Send(BluetoothDaemonPDU* aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, void* aUserData);
|
||||
|
||||
//
|
||||
// Responses
|
||||
//
|
||||
|
||||
typedef BluetoothResultRunnable0<BluetoothHandsfreeResultHandler, void>
|
||||
ResultRunnable;
|
||||
|
||||
typedef BluetoothResultRunnable1<BluetoothHandsfreeResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>
|
||||
ErrorRunnable;
|
||||
|
||||
void ErrorRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void ConnectRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void DisconnectRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void ConnectAudioRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void DisconnectAudioRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void StartVoiceRecognitionRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void StopVoiceRecognitionRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void VolumeControlRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void DeviceStatusNotificationRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void CopsResponseRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void CindResponseRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void FormattedAtResponseRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void AtResponseRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void ClccResponseRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void PhoneStateChangeRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
void HandleRsp(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void* aUserData);
|
||||
|
||||
//
|
||||
// Notifications
|
||||
//
|
||||
|
||||
class NotificationHandlerWrapper;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
BluetoothHandsfreeConnectionState,
|
||||
nsString,
|
||||
BluetoothHandsfreeConnectionState,
|
||||
const nsAString&>
|
||||
ConnectionStateNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
BluetoothHandsfreeAudioState,
|
||||
nsString,
|
||||
BluetoothHandsfreeAudioState,
|
||||
const nsAString&>
|
||||
AudioStateNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
|
||||
BluetoothHandsfreeVoiceRecognitionState>
|
||||
VoiceRecognitionNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
|
||||
AnswerCallNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
|
||||
HangupCallNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable2<NotificationHandlerWrapper, void,
|
||||
BluetoothHandsfreeVolumeType, int>
|
||||
VolumeNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
|
||||
nsString, const nsAString&>
|
||||
DialCallNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
|
||||
char>
|
||||
DtmfNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
|
||||
BluetoothHandsfreeNRECState>
|
||||
NRECNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
|
||||
BluetoothHandsfreeCallHoldType>
|
||||
CallHoldNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
|
||||
CnumNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
|
||||
CindNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
|
||||
CopsNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
|
||||
ClccNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable1<NotificationHandlerWrapper, void,
|
||||
nsCString, const nsACString&>
|
||||
UnknownAtNotification;
|
||||
|
||||
typedef BluetoothNotificationRunnable0<NotificationHandlerWrapper, void>
|
||||
KeyPressedNotification;
|
||||
|
||||
class AudioStateInitOp;
|
||||
class ConnectionStateInitOp;
|
||||
class DialCallInitOp;
|
||||
class VolumeInitOp;
|
||||
class UnknownAtInitOp;
|
||||
|
||||
void ConnectionStateNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void AudioStateNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void VoiceRecognitionNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void AnswerCallNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void HangupCallNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void VolumeNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void DialCallNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void DtmfNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void NRECNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void CallHoldNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void CnumNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void CindNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void CopsNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void ClccNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void UnknownAtNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void KeyPressedNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU);
|
||||
|
||||
void HandleNtf(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU,
|
||||
void* aUserData);
|
||||
|
||||
static BluetoothHandsfreeNotificationHandler* sNotificationHandler;
|
||||
};
|
||||
|
||||
class BluetoothDaemonHandsfreeInterface MOZ_FINAL
|
||||
: public BluetoothHandsfreeInterface
|
||||
{
|
||||
class CleanupResultHandler;
|
||||
class InitResultHandler;
|
||||
|
||||
enum {
|
||||
MODE_HEADSET = 0x00,
|
||||
MODE_NARROWBAND_SPEECH = 0x01,
|
||||
MODE_NARROWBAND_WIDEBAND_SPEECH = 0x02
|
||||
};
|
||||
|
||||
public:
|
||||
BluetoothDaemonHandsfreeInterface(BluetoothDaemonHandsfreeModule* aModule);
|
||||
~BluetoothDaemonHandsfreeInterface();
|
||||
|
||||
void Init(
|
||||
BluetoothHandsfreeNotificationHandler* aNotificationHandler,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
void Cleanup(BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
/* Connect / Disconnect */
|
||||
|
||||
void Connect(const nsAString& aBdAddr,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
void Disconnect(const nsAString& aBdAddr,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
void ConnectAudio(const nsAString& aBdAddr,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
void DisconnectAudio(const nsAString& aBdAddr,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
/* Voice Recognition */
|
||||
|
||||
void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes);
|
||||
void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
/* Volume */
|
||||
|
||||
void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
/* Device status */
|
||||
|
||||
void DeviceStatusNotification(BluetoothHandsfreeNetworkState aNtkState,
|
||||
BluetoothHandsfreeServiceType aSvcType,
|
||||
int aSignal, int aBattChg,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
/* Responses */
|
||||
|
||||
void CopsResponse(const char* aCops,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
void CindResponse(int aSvc, int aNumActive, int aNumHeld,
|
||||
BluetoothHandsfreeCallState aCallSetupState,
|
||||
int aSignal, int aRoam, int aBattChg,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
void FormattedAtResponse(const char* aRsp,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir,
|
||||
BluetoothHandsfreeCallState aState,
|
||||
BluetoothHandsfreeCallMode aMode,
|
||||
BluetoothHandsfreeCallMptyType aMpty,
|
||||
const nsAString& aNumber,
|
||||
BluetoothHandsfreeCallAddressType aType,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
/* Phone State */
|
||||
|
||||
void PhoneStateChange(int aNumActive, int aNumHeld,
|
||||
BluetoothHandsfreeCallState aCallSetupState,
|
||||
const nsAString& aNumber,
|
||||
BluetoothHandsfreeCallAddressType aType,
|
||||
BluetoothHandsfreeResultHandler* aRes);
|
||||
|
||||
private:
|
||||
void DispatchError(BluetoothHandsfreeResultHandler* aRes,
|
||||
BluetoothStatus aStatus);
|
||||
|
||||
BluetoothDaemonHandsfreeModule* mModule;
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
||||
#endif
|
@ -45,6 +45,18 @@ Convert(bool aIn, BluetoothScanMode& aOut)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(int aIn, uint8_t& aOut)
|
||||
{
|
||||
if (NS_WARN_IF(aIn < std::numeric_limits<uint8_t>::min()) ||
|
||||
NS_WARN_IF(aIn > std::numeric_limits<uint8_t>::max())) {
|
||||
aOut = 0; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = static_cast<uint8_t>(aIn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(int aIn, int16_t& aOut)
|
||||
{
|
||||
@ -71,6 +83,20 @@ Convert(uint8_t aIn, bool& aOut)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, char& aOut)
|
||||
{
|
||||
aOut = static_cast<char>(aIn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, int& aOut)
|
||||
{
|
||||
aOut = static_cast<int>(aIn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothAclState& aOut)
|
||||
{
|
||||
@ -100,6 +126,97 @@ Convert(uint8_t aIn, BluetoothBondState& aOut)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothHandsfreeAudioState& aOut)
|
||||
{
|
||||
static const BluetoothHandsfreeAudioState sAudioState[] = {
|
||||
CONVERT(0x00, HFP_AUDIO_STATE_DISCONNECTED),
|
||||
CONVERT(0x01, HFP_AUDIO_STATE_CONNECTING),
|
||||
CONVERT(0x02, HFP_AUDIO_STATE_CONNECTED),
|
||||
CONVERT(0x03, HFP_AUDIO_STATE_DISCONNECTING)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sAudioState))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sAudioState[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothHandsfreeCallHoldType& aOut)
|
||||
{
|
||||
static const BluetoothHandsfreeCallHoldType sCallHoldType[] = {
|
||||
CONVERT(0x00, HFP_CALL_HOLD_RELEASEHELD),
|
||||
CONVERT(0x01, HFP_CALL_HOLD_RELEASEACTIVE_ACCEPTHELD),
|
||||
CONVERT(0x02, HFP_CALL_HOLD_HOLDACTIVE_ACCEPTHELD),
|
||||
CONVERT(0x03, HFP_CALL_HOLD_ADDHELDTOCONF)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sCallHoldType))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sCallHoldType[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothHandsfreeConnectionState& aOut)
|
||||
{
|
||||
static const BluetoothHandsfreeConnectionState sConnectionState[] = {
|
||||
CONVERT(0x00, HFP_CONNECTION_STATE_DISCONNECTED),
|
||||
CONVERT(0x01, HFP_CONNECTION_STATE_CONNECTING),
|
||||
CONVERT(0x02, HFP_CONNECTION_STATE_CONNECTED),
|
||||
CONVERT(0x03, HFP_CONNECTION_STATE_SLC_CONNECTED),
|
||||
CONVERT(0x04, HFP_CONNECTION_STATE_DISCONNECTING)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sConnectionState))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sConnectionState[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothHandsfreeNRECState& aOut)
|
||||
{
|
||||
static const BluetoothHandsfreeNRECState sNRECState[] = {
|
||||
CONVERT(0x00, HFP_NREC_STOPPED),
|
||||
CONVERT(0x01, HFP_NREC_STARTED)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sNRECState))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sNRECState[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothHandsfreeVoiceRecognitionState& aOut)
|
||||
{
|
||||
static const BluetoothHandsfreeVoiceRecognitionState sState[] = {
|
||||
CONVERT(0x00, HFP_VOICE_RECOGNITION_STOPPED),
|
||||
CONVERT(0x01, HFP_VOICE_RECOGNITION_STOPPED)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sState))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sState[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothHandsfreeVolumeType& aOut)
|
||||
{
|
||||
static const BluetoothHandsfreeVolumeType sVolumeType[] = {
|
||||
CONVERT(0x00, HFP_VOLUME_TYPE_SPEAKER),
|
||||
CONVERT(0x01, HFP_VOLUME_TYPE_MICROPHONE)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sVolumeType))) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sVolumeType[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(int32_t aIn, BluetoothTypeOfDevice& aOut)
|
||||
{
|
||||
@ -373,6 +490,147 @@ Convert(const BluetoothAddress& aIn, nsAString& aOut)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeAtResponse aIn, uint8_t& aOut)
|
||||
{
|
||||
static const uint8_t sAtResponse[] = {
|
||||
CONVERT(HFP_AT_RESPONSE_ERROR, 0x00),
|
||||
CONVERT(HFP_AT_RESPONSE_OK, 0x01)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sAtResponse))) {
|
||||
aOut = 0x00; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sAtResponse[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeCallAddressType aIn, uint8_t& aOut)
|
||||
{
|
||||
static const uint8_t sCallAddressType[] = {
|
||||
CONVERT(HFP_CALL_ADDRESS_TYPE_UNKNOWN, 0x81),
|
||||
CONVERT(HFP_CALL_ADDRESS_TYPE_INTERNATIONAL, 0x91)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sCallAddressType))) {
|
||||
aOut = 0x00; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sCallAddressType[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeCallDirection aIn, uint8_t& aOut)
|
||||
{
|
||||
static const uint8_t sCallDirection[] = {
|
||||
CONVERT(HFP_CALL_DIRECTION_OUTGOING, 0x00),
|
||||
CONVERT(HFP_CALL_DIRECTION_INCOMING, 0x01)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sCallDirection))) {
|
||||
aOut = 0x00; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sCallDirection[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeCallState aIn, uint8_t& aOut)
|
||||
{
|
||||
static const uint8_t sCallState[] = {
|
||||
CONVERT(HFP_CALL_STATE_ACTIVE, 0x00),
|
||||
CONVERT(HFP_CALL_STATE_HELD, 0x01),
|
||||
CONVERT(HFP_CALL_STATE_DIALING, 0x02),
|
||||
CONVERT(HFP_CALL_STATE_ALERTING, 0x03),
|
||||
CONVERT(HFP_CALL_STATE_INCOMING, 0x04),
|
||||
CONVERT(HFP_CALL_STATE_WAITING, 0x05),
|
||||
CONVERT(HFP_CALL_STATE_IDLE, 0x06)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sCallState))) {
|
||||
aOut = 0x00; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sCallState[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeCallMode aIn, uint8_t& aOut)
|
||||
{
|
||||
static const uint8_t sCallMode[] = {
|
||||
CONVERT(HFP_CALL_MODE_VOICE, 0x00),
|
||||
CONVERT(HFP_CALL_MODE_DATA, 0x01),
|
||||
CONVERT(HFP_CALL_MODE_FAX, 0x02)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sCallMode))) {
|
||||
aOut = 0x00; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sCallMode[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeCallMptyType aIn, uint8_t& aOut)
|
||||
{
|
||||
static const uint8_t sCallMptyType[] = {
|
||||
CONVERT(HFP_CALL_MPTY_TYPE_SINGLE, 0x00),
|
||||
CONVERT(HFP_CALL_MPTY_TYPE_MULTI, 0x01)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sCallMptyType))) {
|
||||
aOut = 0x00; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sCallMptyType[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeNetworkState aIn, uint8_t& aOut)
|
||||
{
|
||||
static const uint8_t sNetworkState[] = {
|
||||
CONVERT(HFP_NETWORK_STATE_NOT_AVAILABLE, 0x00),
|
||||
CONVERT(HFP_NETWORK_STATE_AVAILABLE, 0x01)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sNetworkState))) {
|
||||
aOut = 0x00; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sNetworkState[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeServiceType aIn, uint8_t& aOut)
|
||||
{
|
||||
static const uint8_t sServiceType[] = {
|
||||
CONVERT(HFP_SERVICE_TYPE_HOME, 0x00),
|
||||
CONVERT(HFP_SERVICE_TYPE_ROAMING, 0x01)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sServiceType))) {
|
||||
aOut = 0x00; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sServiceType[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeVolumeType aIn, uint8_t& aOut)
|
||||
{
|
||||
static const uint8_t sVolumeType[] = {
|
||||
CONVERT(HFP_VOLUME_TYPE_SPEAKER, 0x00),
|
||||
CONVERT(HFP_VOLUME_TYPE_MICROPHONE, 0x01)
|
||||
};
|
||||
if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sVolumeType))) {
|
||||
aOut = 0x00; // silences compiler warning
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
aOut = sVolumeType[aIn];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothPropertyType aIn, uint8_t& aOut)
|
||||
{
|
||||
@ -506,6 +764,69 @@ PackPDU(const BluetoothDaemonPDUHeader& aIn, BluetoothDaemonPDU& aPDU)
|
||||
return PackPDU(aIn.mService, aIn.mOpcode, aIn.mLength, aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeAtResponse& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeAtResponse, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallAddressType& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeCallAddressType, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallDirection& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeCallDirection, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallMode& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeCallMode, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallMptyType& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeCallMptyType, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallState& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeCallState, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeNetworkState& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeNetworkState, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeServiceType& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeServiceType, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeVolumeType& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackConversion<BluetoothHandsfreeVolumeType, uint8_t>(aIn), aPDU);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothNamedValue& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
@ -591,6 +912,12 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, bool& aOut)
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint8_t, bool>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, char& aOut)
|
||||
{
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint8_t, char>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAclState& aOut)
|
||||
{
|
||||
@ -610,6 +937,50 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothTypeOfDevice& aOut)
|
||||
aPDU, UnpackConversion<int32_t, BluetoothTypeOfDevice>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeAudioState& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothHandsfreeAudioState>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeCallHoldType& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothHandsfreeCallHoldType>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeConnectionState& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothHandsfreeConnectionState>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeNRECState& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothHandsfreeNRECState>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeVoiceRecognitionState& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU,
|
||||
UnpackConversion<uint8_t, BluetoothHandsfreeVoiceRecognitionState>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeVolumeType& aOut)
|
||||
{
|
||||
return UnpackPDU(
|
||||
aPDU, UnpackConversion<uint8_t, BluetoothHandsfreeVolumeType>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothProperty& aOut)
|
||||
{
|
||||
@ -753,4 +1124,64 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothStatus& aOut)
|
||||
return UnpackPDU(aPDU, UnpackConversion<uint8_t, BluetoothStatus>(aOut));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, nsDependentCString& aOut)
|
||||
{
|
||||
// We get a pointer to the first character in the PDU, a length
|
||||
// of 1 ensures we consume the \0 byte. With 'str' pointing to
|
||||
// the string in the PDU, we can copy the actual bytes.
|
||||
|
||||
const char* str = reinterpret_cast<const char*>(aPDU.Consume(1));
|
||||
if (NS_WARN_IF(!str)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE; // end of PDU
|
||||
}
|
||||
|
||||
const char* end = static_cast<char*>(memchr(str, '\0', aPDU.GetSize()));
|
||||
if (NS_WARN_IF(!end)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE; // no string terminator
|
||||
}
|
||||
|
||||
ptrdiff_t len = end - str;
|
||||
|
||||
const uint8_t* rest = aPDU.Consume(len);
|
||||
if (NS_WARN_IF(!rest)) {
|
||||
// We couldn't consume bytes that should have been there.
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
aOut.Rebind(str, len);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackCString0& aOut)
|
||||
{
|
||||
nsDependentCString cstring;
|
||||
|
||||
nsresult rv = UnpackPDU(aPDU, cstring);
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
aOut.mString->AssignASCII(cstring.get(), cstring.Length());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackString0& aOut)
|
||||
{
|
||||
nsDependentCString cstring;
|
||||
|
||||
nsresult rv = UnpackPDU(aPDU, cstring);
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
*aOut.mString = NS_ConvertUTF8toUTF16(cstring);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
@ -83,18 +83,45 @@ Convert(bool aIn, uint8_t& aOut);
|
||||
nsresult
|
||||
Convert(bool aIn, BluetoothScanMode& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(int aIn, uint8_t& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(int aIn, int16_t& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, bool& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, char& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, int& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothAclState& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothBondState& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothHandsfreeAudioState& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothHandsfreeCallHoldType& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothHandsfreeConnectionState& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothHandsfreeNRECState& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothHandsfreeVoiceRecognitionState& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothHandsfreeVolumeType& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(uint8_t aIn, BluetoothTypeOfDevice& aOut);
|
||||
|
||||
@ -137,6 +164,33 @@ Convert(BluetoothAclState aIn, bool& aOut);
|
||||
nsresult
|
||||
Convert(const BluetoothAddress& aIn, nsAString& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeAtResponse aIn, uint8_t& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeCallAddressType aIn, uint8_t& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeCallDirection aIn, uint8_t& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeCallState aIn, uint8_t& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeCallMode aIn, uint8_t& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeCallMptyType aIn, uint8_t& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeNetworkState aIn, uint8_t& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeServiceType aIn, uint8_t& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothHandsfreeVolumeType aIn, uint8_t& aOut);
|
||||
|
||||
nsresult
|
||||
Convert(BluetoothPropertyType aIn, uint8_t& aOut);
|
||||
|
||||
@ -192,6 +246,33 @@ PackPDU(const BluetoothConfigurationParameter& aIn, BluetoothDaemonPDU& aPDU);
|
||||
nsresult
|
||||
PackPDU(const BluetoothDaemonPDUHeader& aIn, BluetoothDaemonPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeAtResponse& aIn, BluetoothDaemonPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallAddressType& aIn, BluetoothDaemonPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallDirection& aIn, BluetoothDaemonPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallMode& aIn, BluetoothDaemonPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallMptyType& aIn, BluetoothDaemonPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeCallState& aIn, BluetoothDaemonPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeNetworkState& aIn, BluetoothDaemonPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeServiceType& aIn, BluetoothDaemonPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothHandsfreeVolumeType& aIn, BluetoothDaemonPDU& aPDU);
|
||||
|
||||
nsresult
|
||||
PackPDU(const BluetoothNamedValue& aIn, BluetoothDaemonPDU& aPDU);
|
||||
|
||||
@ -279,6 +360,29 @@ PackPDU<uint8_t>(const PackArray<uint8_t>& aIn, BluetoothDaemonPDU& aPDU)
|
||||
return aPDU.Write(aIn.mData, aIn.mLength);
|
||||
}
|
||||
|
||||
/* |PackCString0| is a helper for packing 0-terminated C string,
|
||||
* including the \0 character. Pass an instance of this structure
|
||||
* as the first argument to |PackPDU| to pack a string.
|
||||
*/
|
||||
struct PackCString0
|
||||
{
|
||||
PackCString0(const nsCString& aString)
|
||||
: mString(aString)
|
||||
{ }
|
||||
|
||||
const nsCString& mString;
|
||||
};
|
||||
|
||||
/* This implementation of |PackPDU| packs a 0-terminated C string.
|
||||
*/
|
||||
inline nsresult
|
||||
PackPDU(const PackCString0& aIn, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
return PackPDU(
|
||||
PackArray<uint8_t>(reinterpret_cast<const uint8_t*>(aIn.mString.get()),
|
||||
aIn.mString.Length() + 1), aPDU);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline nsresult
|
||||
PackPDU(const T1& aIn1, const T2& aIn2, BluetoothDaemonPDU& aPDU)
|
||||
@ -352,6 +456,41 @@ PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
|
||||
return PackPDU(aIn5, aPDU);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3,
|
||||
typename T4, typename T5, typename T6,
|
||||
typename T7>
|
||||
inline nsresult
|
||||
PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
|
||||
const T4& aIn4, const T5& aIn5, const T6& aIn6,
|
||||
const T7& aIn7, BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
nsresult rv = PackPDU(aIn1, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = PackPDU(aIn2, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = PackPDU(aIn3, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = PackPDU(aIn4, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = PackPDU(aIn5, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
rv = PackPDU(aIn6, aPDU);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
return PackPDU(aIn7, aPDU);
|
||||
}
|
||||
|
||||
//
|
||||
// Unpacking
|
||||
//
|
||||
@ -389,6 +528,9 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, uint32_t& aOut)
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, bool& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, char& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAclState& aOut);
|
||||
|
||||
@ -418,6 +560,25 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothDaemonPDUHeader& aOut)
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothTypeOfDevice& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeAudioState& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeCallHoldType& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeConnectionState& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeNRECState& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU,
|
||||
BluetoothHandsfreeVoiceRecognitionState& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeVolumeType& aOut);
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothRemoteInfo& aOut);
|
||||
|
||||
@ -451,6 +612,9 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothUuid& aOut)
|
||||
return aPDU.Read(aOut.mUuid, sizeof(aOut.mUuid));
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, nsDependentCString& aOut);
|
||||
|
||||
/* |UnpackConversion| is a helper for convering unpacked values. Pass
|
||||
* an instance of this structure to |UnpackPDU| to read a value from
|
||||
* the PDU in the input type and convert it to the output type.
|
||||
@ -542,6 +706,44 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, nsTArray<T>& aOut)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* |UnpackCString0| is a helper for unpacking 0-terminated C string,
|
||||
* including the \0 character. Pass an instance of this structure
|
||||
* as the first argument to |UnpackPDU| to unpack a string.
|
||||
*/
|
||||
struct UnpackCString0
|
||||
{
|
||||
UnpackCString0(nsCString& aString)
|
||||
: mString(&aString)
|
||||
{ }
|
||||
|
||||
nsCString* mString; // non-null by construction
|
||||
};
|
||||
|
||||
/* This implementation of |UnpackPDU| unpacks a 0-terminated C string.
|
||||
*/
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackCString0& aOut);
|
||||
|
||||
/* |UnpackString0| is a helper for unpacking 0-terminated C string,
|
||||
* including the \0 character. Pass an instance of this structure
|
||||
* as the first argument to |UnpackPDU| to unpack a C string and convert
|
||||
* it to wide-character encoding.
|
||||
*/
|
||||
struct UnpackString0
|
||||
{
|
||||
UnpackString0(nsString& aString)
|
||||
: mString(&aString)
|
||||
{ }
|
||||
|
||||
nsString* mString; // non-null by construction
|
||||
};
|
||||
|
||||
/* This implementation of |UnpackPDU| unpacks a 0-terminated C string
|
||||
* and converts it to wide-character encoding.
|
||||
*/
|
||||
nsresult
|
||||
UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackString0& aOut);
|
||||
|
||||
//
|
||||
// Init operators
|
||||
//
|
||||
|
@ -5,6 +5,7 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "BluetoothDaemonInterface.h"
|
||||
#include "BluetoothDaemonHandsfreeInterface.h"
|
||||
#include "BluetoothDaemonHelpers.h"
|
||||
#include "BluetoothDaemonSetupInterface.h"
|
||||
#include "BluetoothDaemonSocketInterface.h"
|
||||
@ -1456,10 +1457,17 @@ class BluetoothDaemonProtocol MOZ_FINAL
|
||||
, public BluetoothDaemonSetupModule
|
||||
, public BluetoothDaemonCoreModule
|
||||
, public BluetoothDaemonSocketModule
|
||||
, public BluetoothDaemonHandsfreeModule
|
||||
{
|
||||
public:
|
||||
BluetoothDaemonProtocol(BluetoothDaemonConnection* aConnection);
|
||||
|
||||
nsresult RegisterModule(uint8_t aId, uint8_t aMode,
|
||||
BluetoothSetupResultHandler* aRes) MOZ_OVERRIDE;
|
||||
|
||||
nsresult UnregisterModule(uint8_t aId,
|
||||
BluetoothSetupResultHandler* aRes) MOZ_OVERRIDE;
|
||||
|
||||
// Outgoing PDUs
|
||||
//
|
||||
|
||||
@ -1481,6 +1489,8 @@ private:
|
||||
BluetoothDaemonPDU& aPDU, void* aUserData);
|
||||
void HandleSocketSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, void* aUserData);
|
||||
void HandleHandsfreeSvc(const BluetoothDaemonPDUHeader& aHeader,
|
||||
BluetoothDaemonPDU& aPDU, void* aUserData);
|
||||
|
||||
BluetoothDaemonConnection* mConnection;
|
||||
nsTArray<void*> mUserDataQ;
|
||||
@ -1493,6 +1503,20 @@ BluetoothDaemonProtocol::BluetoothDaemonProtocol(
|
||||
MOZ_ASSERT(mConnection);
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothDaemonProtocol::RegisterModule(uint8_t aId, uint8_t aMode,
|
||||
BluetoothSetupResultHandler* aRes)
|
||||
{
|
||||
return BluetoothDaemonSetupModule::RegisterModuleCmd(aId, aMode, aRes);
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothDaemonProtocol::UnregisterModule(uint8_t aId,
|
||||
BluetoothSetupResultHandler* aRes)
|
||||
{
|
||||
return BluetoothDaemonSetupModule::UnregisterModuleCmd(aId, aRes);
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothDaemonProtocol::Send(BluetoothDaemonPDU* aPDU, void* aUserData)
|
||||
{
|
||||
@ -1527,6 +1551,14 @@ BluetoothDaemonProtocol::HandleSocketSvc(
|
||||
BluetoothDaemonSocketModule::HandleSvc(aHeader, aPDU, aUserData);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonProtocol::HandleHandsfreeSvc(
|
||||
const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
|
||||
void* aUserData)
|
||||
{
|
||||
BluetoothDaemonHandsfreeModule::HandleSvc(aHeader, aPDU, aUserData);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothDaemonProtocol::Handle(BluetoothDaemonPDU& aPDU)
|
||||
{
|
||||
@ -1537,7 +1569,11 @@ BluetoothDaemonProtocol::Handle(BluetoothDaemonPDU& aPDU)
|
||||
INIT_ARRAY_AT(BluetoothDaemonCoreModule::SERVICE_ID,
|
||||
&BluetoothDaemonProtocol::HandleCoreSvc),
|
||||
INIT_ARRAY_AT(BluetoothDaemonSocketModule::SERVICE_ID,
|
||||
&BluetoothDaemonProtocol::HandleSocketSvc)
|
||||
&BluetoothDaemonProtocol::HandleSocketSvc),
|
||||
INIT_ARRAY_AT(0x03, nullptr), // HID host
|
||||
INIT_ARRAY_AT(0x04, nullptr), // PAN
|
||||
INIT_ARRAY_AT(BluetoothDaemonHandsfreeModule::SERVICE_ID,
|
||||
&BluetoothDaemonProtocol::HandleHandsfreeSvc)
|
||||
};
|
||||
|
||||
BluetoothDaemonPDUHeader header;
|
||||
@ -2110,7 +2146,13 @@ BluetoothDaemonInterface::GetBluetoothSocketInterface()
|
||||
BluetoothHandsfreeInterface*
|
||||
BluetoothDaemonInterface::GetBluetoothHandsfreeInterface()
|
||||
{
|
||||
return nullptr;
|
||||
if (mHandsfreeInterface) {
|
||||
return mHandsfreeInterface;
|
||||
}
|
||||
|
||||
mHandsfreeInterface = new BluetoothDaemonHandsfreeInterface(mProtocol);
|
||||
|
||||
return mHandsfreeInterface;
|
||||
}
|
||||
|
||||
BluetoothA2dpInterface*
|
||||
|
@ -12,6 +12,7 @@
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothDaemonChannel;
|
||||
class BluetoothDaemonHandsfreeInterface;
|
||||
class BluetoothDaemonProtocol;
|
||||
class BluetoothDaemonSocketInterface;
|
||||
|
||||
@ -126,6 +127,7 @@ private:
|
||||
nsTArray<nsRefPtr<BluetoothResultHandler> > mResultHandlerQ;
|
||||
|
||||
nsAutoPtr<BluetoothDaemonSocketInterface> mSocketInterface;
|
||||
nsAutoPtr<BluetoothDaemonHandsfreeInterface> mHandsfreeInterface;
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
@ -76,146 +76,12 @@ static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sFetchUuidsRunnableArray;
|
||||
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sBondingRunnableArray;
|
||||
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sUnbondingRunnableArray;
|
||||
|
||||
/**
|
||||
* Classes only used in this file
|
||||
*/
|
||||
|
||||
class SetupAfterEnabledTask MOZ_FINAL : public nsRunnable
|
||||
{
|
||||
public:
|
||||
class SetAdapterPropertyResultHandler MOZ_FINAL
|
||||
: public BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
|
||||
{
|
||||
BT_LOGR("Fail to set: BT_SCAN_MODE_CONNECTABLE");
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMETHOD
|
||||
Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Bluetooth just enabled, clear profile controllers and runnable arrays.
|
||||
sControllerArray.Clear();
|
||||
sChangeDiscoveryRunnableArray.Clear();
|
||||
sSetPropertyRunnableArray.Clear();
|
||||
sGetDeviceRunnableArray.Clear();
|
||||
sFetchUuidsRunnableArray.Clear();
|
||||
sBondingRunnableArray.Clear();
|
||||
sUnbondingRunnableArray.Clear();
|
||||
|
||||
// Bluetooth scan mode is SCAN_MODE_CONNECTABLE by default, i.e., It should
|
||||
// be connectable and non-discoverable.
|
||||
NS_ENSURE_TRUE(sBtInterface, NS_ERROR_FAILURE);
|
||||
sBtInterface->SetAdapterProperty(
|
||||
BluetoothNamedValue(NS_ConvertUTF8toUTF16("Discoverable"), false),
|
||||
new SetAdapterPropertyResultHandler());
|
||||
|
||||
// Trigger BluetoothOppManager to listen
|
||||
BluetoothOppManager* opp = BluetoothOppManager::Get();
|
||||
if (!opp || !opp->Listen()) {
|
||||
BT_LOGR("Fail to start BluetoothOppManager listening");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
/* |ProfileDeinitResultHandler| collects the results of all profile
|
||||
* result handlers and calls |Proceed| after all results handlers
|
||||
* have been run.
|
||||
*/
|
||||
class ProfileDeinitResultHandler MOZ_FINAL
|
||||
: public BluetoothProfileResultHandler
|
||||
{
|
||||
public:
|
||||
ProfileDeinitResultHandler(unsigned char aNumProfiles)
|
||||
: mNumProfiles(aNumProfiles)
|
||||
{
|
||||
MOZ_ASSERT(mNumProfiles);
|
||||
}
|
||||
|
||||
void Deinit() MOZ_OVERRIDE
|
||||
{
|
||||
if (!(--mNumProfiles)) {
|
||||
Proceed();
|
||||
}
|
||||
}
|
||||
|
||||
void OnError(nsresult aResult) MOZ_OVERRIDE
|
||||
{
|
||||
if (!(--mNumProfiles)) {
|
||||
Proceed();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void Proceed() const
|
||||
{
|
||||
sBtInterface->Cleanup(nullptr);
|
||||
}
|
||||
|
||||
unsigned char mNumProfiles;
|
||||
};
|
||||
|
||||
class CleanupTask MOZ_FINAL : public nsRunnable
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD
|
||||
Run()
|
||||
{
|
||||
static void (* const sDeinitManager[])(BluetoothProfileResultHandler*) = {
|
||||
BluetoothHfpManager::DeinitHfpInterface,
|
||||
BluetoothA2dpManager::DeinitA2dpInterface,
|
||||
BluetoothGattManager::DeinitGattInterface
|
||||
};
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Return error if BluetoothService is unavailable
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
|
||||
|
||||
// Cleanup static adapter properties and notify adapter.
|
||||
sAdapterBdAddress.Truncate();
|
||||
sAdapterBdName.Truncate();
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> props;
|
||||
BT_APPEND_NAMED_VALUE(props, "Name", sAdapterBdName);
|
||||
BT_APPEND_NAMED_VALUE(props, "Address", sAdapterBdAddress);
|
||||
if (sAdapterDiscoverable) {
|
||||
sAdapterDiscoverable = false;
|
||||
BT_APPEND_NAMED_VALUE(props, "Discoverable", false);
|
||||
}
|
||||
if (sAdapterDiscovering) {
|
||||
sAdapterDiscovering = false;
|
||||
BT_APPEND_NAMED_VALUE(props, "Discovering", false);
|
||||
}
|
||||
|
||||
BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER), props);
|
||||
bs->DistributeSignal(signal);
|
||||
|
||||
// Cleanup bluetooth interfaces after BT state becomes BT_STATE_OFF.
|
||||
nsRefPtr<ProfileDeinitResultHandler> res =
|
||||
new ProfileDeinitResultHandler(MOZ_ARRAY_LENGTH(sDeinitManager));
|
||||
|
||||
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sDeinitManager); ++i) {
|
||||
sDeinitManager[i](res);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Static callback functions
|
||||
*/
|
||||
static ControlPlayStatus
|
||||
PlayStatusStringToControlPlayStatus(const nsAString& aPlayStatus)
|
||||
ControlPlayStatus
|
||||
BluetoothServiceBluedroid::PlayStatusStringToControlPlayStatus(
|
||||
const nsAString& aPlayStatus)
|
||||
{
|
||||
ControlPlayStatus playStatus = ControlPlayStatus::PLAYSTATUS_UNKNOWN;
|
||||
if (aPlayStatus.EqualsLiteral("STOPPED")) {
|
||||
@ -238,8 +104,8 @@ PlayStatusStringToControlPlayStatus(const nsAString& aPlayStatus)
|
||||
/**
|
||||
* Static functions
|
||||
*/
|
||||
static bool
|
||||
EnsureBluetoothHalLoad()
|
||||
bool
|
||||
BluetoothServiceBluedroid::EnsureBluetoothHalLoad()
|
||||
{
|
||||
sBtInterface = BluetoothInterface::GetInstance();
|
||||
NS_ENSURE_TRUE(sBtInterface, false);
|
||||
@ -247,7 +113,8 @@ EnsureBluetoothHalLoad()
|
||||
return true;
|
||||
}
|
||||
|
||||
class EnableResultHandler MOZ_FINAL : public BluetoothResultHandler
|
||||
class BluetoothServiceBluedroid::EnableResultHandler MOZ_FINAL
|
||||
: public BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
|
||||
@ -256,10 +123,7 @@ public:
|
||||
|
||||
BT_LOGR("BluetoothInterface::Enable failed: %d", aStatus);
|
||||
|
||||
nsRefPtr<nsRunnable> runnable = new BluetoothService::ToggleBtAck(false);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
BluetoothService::AcknowledgeToggleBt(false);
|
||||
}
|
||||
};
|
||||
|
||||
@ -267,12 +131,12 @@ public:
|
||||
* result handlers and calls |Proceed| after all results handlers
|
||||
* have been run.
|
||||
*/
|
||||
class ProfileInitResultHandler MOZ_FINAL
|
||||
: public BluetoothProfileResultHandler
|
||||
class BluetoothServiceBluedroid::ProfileInitResultHandler MOZ_FINAL
|
||||
: public BluetoothProfileResultHandler
|
||||
{
|
||||
public:
|
||||
ProfileInitResultHandler(unsigned char aNumProfiles)
|
||||
: mNumProfiles(aNumProfiles)
|
||||
: mNumProfiles(aNumProfiles)
|
||||
{
|
||||
MOZ_ASSERT(mNumProfiles);
|
||||
}
|
||||
@ -300,7 +164,8 @@ private:
|
||||
unsigned char mNumProfiles;
|
||||
};
|
||||
|
||||
class InitResultHandler MOZ_FINAL : public BluetoothResultHandler
|
||||
class BluetoothServiceBluedroid::InitResultHandler MOZ_FINAL
|
||||
: public BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
void Init() MOZ_OVERRIDE
|
||||
@ -332,15 +197,12 @@ public:
|
||||
|
||||
sBtInterface = nullptr;
|
||||
|
||||
nsRefPtr<nsRunnable> runnable = new BluetoothService::ToggleBtAck(false);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
BluetoothService::AcknowledgeToggleBt(false);
|
||||
}
|
||||
};
|
||||
|
||||
static nsresult
|
||||
StartGonkBluetooth()
|
||||
nsresult
|
||||
BluetoothServiceBluedroid::StartGonkBluetooth()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
@ -351,10 +213,7 @@ StartGonkBluetooth()
|
||||
|
||||
if (bs->IsEnabled()) {
|
||||
// Keep current enable status
|
||||
nsRefPtr<nsRunnable> runnable = new BluetoothService::ToggleBtAck(true);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
BluetoothService::AcknowledgeToggleBt(true);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -364,7 +223,8 @@ StartGonkBluetooth()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class DisableResultHandler MOZ_FINAL : public BluetoothResultHandler
|
||||
class BluetoothServiceBluedroid::DisableResultHandler MOZ_FINAL
|
||||
: public BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
|
||||
@ -373,15 +233,12 @@ public:
|
||||
|
||||
BT_LOGR("BluetoothInterface::Disable failed: %d", aStatus);
|
||||
|
||||
nsRefPtr<nsRunnable> runnable = new BluetoothService::ToggleBtAck(true);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
BluetoothService::AcknowledgeToggleBt(true);
|
||||
}
|
||||
};
|
||||
|
||||
static nsresult
|
||||
StopGonkBluetooth()
|
||||
nsresult
|
||||
BluetoothServiceBluedroid::StopGonkBluetooth()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
@ -392,10 +249,7 @@ StopGonkBluetooth()
|
||||
|
||||
if (!bs->IsEnabled()) {
|
||||
// Keep current enable status
|
||||
nsRefPtr<nsRunnable> runnable = new BluetoothService::ToggleBtAck(false);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
BluetoothService::AcknowledgeToggleBt(false);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -404,9 +258,10 @@ StopGonkBluetooth()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
ReplyStatusError(BluetoothReplyRunnable* aBluetoothReplyRunnable,
|
||||
BluetoothStatus aStatusCode, const nsAString& aCustomMsg)
|
||||
void
|
||||
BluetoothServiceBluedroid::ReplyStatusError(
|
||||
BluetoothReplyRunnable* aBluetoothReplyRunnable,
|
||||
BluetoothStatus aStatusCode, const nsAString& aCustomMsg)
|
||||
{
|
||||
MOZ_ASSERT(aBluetoothReplyRunnable, "Reply runnable is nullptr");
|
||||
|
||||
@ -460,12 +315,7 @@ BluetoothServiceBluedroid::StartInternal(BluetoothReplyRunnable* aRunnable)
|
||||
|
||||
nsresult ret = StartGonkBluetooth();
|
||||
if (NS_FAILED(ret)) {
|
||||
nsRefPtr<nsRunnable> runnable =
|
||||
new BluetoothService::ToggleBtAck(false);
|
||||
|
||||
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
BluetoothService::AcknowledgeToggleBt(false);
|
||||
|
||||
// Reject Promise
|
||||
if(aRunnable) {
|
||||
@ -492,12 +342,7 @@ BluetoothServiceBluedroid::StopInternal(BluetoothReplyRunnable* aRunnable)
|
||||
|
||||
nsresult ret = StopGonkBluetooth();
|
||||
if (NS_FAILED(ret)) {
|
||||
nsRefPtr<nsRunnable> runnable =
|
||||
new BluetoothService::ToggleBtAck(true);
|
||||
|
||||
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
BluetoothService::AcknowledgeToggleBt(true);
|
||||
|
||||
// Reject Promise
|
||||
if(aRunnable) {
|
||||
@ -554,8 +399,9 @@ BluetoothServiceBluedroid::GetAdaptersInternal(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class GetRemoteDevicePropertiesResultHandler MOZ_FINAL
|
||||
: public BluetoothResultHandler
|
||||
class BluetoothServiceBluedroid::GetRemoteDevicePropertiesResultHandler
|
||||
MOZ_FINAL
|
||||
: public BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
GetRemoteDevicePropertiesResultHandler(const nsAString& aDeviceAddress)
|
||||
@ -653,7 +499,8 @@ BluetoothServiceBluedroid::GetPairedDevicePropertiesInternal(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class StartDiscoveryResultHandler MOZ_FINAL : public BluetoothResultHandler
|
||||
class BluetoothServiceBluedroid::StartDiscoveryResultHandler MOZ_FINAL
|
||||
: public BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
StartDiscoveryResultHandler(BluetoothReplyRunnable* aRunnable)
|
||||
@ -685,7 +532,8 @@ BluetoothServiceBluedroid::StartDiscoveryInternal(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class CancelDiscoveryResultHandler MOZ_FINAL : public BluetoothResultHandler
|
||||
class BluetoothServiceBluedroid::CancelDiscoveryResultHandler MOZ_FINAL
|
||||
: public BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
CancelDiscoveryResultHandler(BluetoothReplyRunnable* aRunnable)
|
||||
@ -717,7 +565,8 @@ BluetoothServiceBluedroid::StopDiscoveryInternal(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class GetRemoteServicesResultHandler MOZ_FINAL : public BluetoothResultHandler
|
||||
class BluetoothServiceBluedroid::GetRemoteServicesResultHandler MOZ_FINAL
|
||||
: public BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
GetRemoteServicesResultHandler(BluetoothReplyRunnable* aRunnable)
|
||||
@ -759,7 +608,8 @@ BluetoothServiceBluedroid::FetchUuidsInternal(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class SetAdapterPropertyResultHandler MOZ_FINAL : public BluetoothResultHandler
|
||||
class BluetoothServiceBluedroid::SetAdapterPropertyResultHandler MOZ_FINAL
|
||||
: public BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
SetAdapterPropertyResultHandler(BluetoothReplyRunnable* aRunnable)
|
||||
@ -810,7 +660,8 @@ BluetoothServiceBluedroid::UpdateSdpRecords(
|
||||
return true;
|
||||
}
|
||||
|
||||
class CreateBondResultHandler MOZ_FINAL : public BluetoothResultHandler
|
||||
class BluetoothServiceBluedroid::CreateBondResultHandler MOZ_FINAL
|
||||
: public BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
CreateBondResultHandler(BluetoothReplyRunnable* aRunnable)
|
||||
@ -845,7 +696,8 @@ BluetoothServiceBluedroid::CreatePairedDeviceInternal(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class RemoveBondResultHandler MOZ_FINAL : public BluetoothResultHandler
|
||||
class BluetoothServiceBluedroid::RemoveBondResultHandler MOZ_FINAL
|
||||
: public BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
RemoveBondResultHandler(BluetoothReplyRunnable* aRunnable)
|
||||
@ -880,7 +732,8 @@ BluetoothServiceBluedroid::RemoveDeviceInternal(
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class PinReplyResultHandler MOZ_FINAL : public BluetoothResultHandler
|
||||
class BluetoothServiceBluedroid::PinReplyResultHandler MOZ_FINAL
|
||||
: public BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
PinReplyResultHandler(BluetoothReplyRunnable* aRunnable)
|
||||
@ -922,7 +775,8 @@ BluetoothServiceBluedroid::SetPasskeyInternal(
|
||||
return;
|
||||
}
|
||||
|
||||
class SspReplyResultHandler MOZ_FINAL : public BluetoothResultHandler
|
||||
class BluetoothServiceBluedroid::SspReplyResultHandler MOZ_FINAL
|
||||
: public BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
SspReplyResultHandler(BluetoothReplyRunnable* aRunnable)
|
||||
@ -958,8 +812,8 @@ BluetoothServiceBluedroid::SetPairingConfirmationInternal(
|
||||
aConfirm, 0, new SspReplyResultHandler(aRunnable));
|
||||
}
|
||||
|
||||
static void
|
||||
NextBluetoothProfileController()
|
||||
void
|
||||
BluetoothServiceBluedroid::NextBluetoothProfileController()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
@ -973,10 +827,11 @@ NextBluetoothProfileController()
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ConnectDisconnect(bool aConnect, const nsAString& aDeviceAddress,
|
||||
BluetoothReplyRunnable* aRunnable,
|
||||
uint16_t aServiceUuid, uint32_t aCod = 0)
|
||||
void
|
||||
BluetoothServiceBluedroid::ConnectDisconnect(
|
||||
bool aConnect, const nsAString& aDeviceAddress,
|
||||
BluetoothReplyRunnable* aRunnable,
|
||||
uint16_t aServiceUuid, uint32_t aCod)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aRunnable);
|
||||
@ -1220,6 +1075,54 @@ BluetoothServiceBluedroid::ToggleCalls(BluetoothReplyRunnable* aRunnable)
|
||||
// Bluetooth notifications
|
||||
//
|
||||
|
||||
/* |ProfileDeinitResultHandler| collects the results of all profile
|
||||
* result handlers and calls |Proceed| after all results handlers
|
||||
* have been run.
|
||||
*/
|
||||
class BluetoothServiceBluedroid::ProfileDeinitResultHandler MOZ_FINAL
|
||||
: public BluetoothProfileResultHandler
|
||||
{
|
||||
public:
|
||||
ProfileDeinitResultHandler(unsigned char aNumProfiles)
|
||||
: mNumProfiles(aNumProfiles)
|
||||
{
|
||||
MOZ_ASSERT(mNumProfiles);
|
||||
}
|
||||
|
||||
void Deinit() MOZ_OVERRIDE
|
||||
{
|
||||
if (!(--mNumProfiles)) {
|
||||
Proceed();
|
||||
}
|
||||
}
|
||||
|
||||
void OnError(nsresult aResult) MOZ_OVERRIDE
|
||||
{
|
||||
if (!(--mNumProfiles)) {
|
||||
Proceed();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void Proceed() const
|
||||
{
|
||||
sBtInterface->Cleanup(nullptr);
|
||||
}
|
||||
|
||||
unsigned char mNumProfiles;
|
||||
};
|
||||
|
||||
class BluetoothServiceBluedroid::SetAdapterPropertyDiscoverableResultHandler
|
||||
MOZ_FINAL
|
||||
: public BluetoothResultHandler
|
||||
{
|
||||
public:
|
||||
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
|
||||
{
|
||||
BT_LOGR("Fail to set: BT_SCAN_MODE_CONNECTABLE");
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
|
||||
{
|
||||
@ -1229,23 +1132,70 @@ BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
|
||||
|
||||
sAdapterEnabled = aState;
|
||||
|
||||
if (!sAdapterEnabled &&
|
||||
NS_FAILED(NS_DispatchToMainThread(new CleanupTask()))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
return;
|
||||
if (!sAdapterEnabled) {
|
||||
static void (* const sDeinitManager[])(BluetoothProfileResultHandler*) = {
|
||||
BluetoothHfpManager::DeinitHfpInterface,
|
||||
BluetoothA2dpManager::DeinitA2dpInterface,
|
||||
BluetoothGattManager::DeinitGattInterface
|
||||
};
|
||||
|
||||
// Return error if BluetoothService is unavailable
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
NS_ENSURE_TRUE_VOID(bs);
|
||||
|
||||
// Cleanup static adapter properties and notify adapter.
|
||||
sAdapterBdAddress.Truncate();
|
||||
sAdapterBdName.Truncate();
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> props;
|
||||
BT_APPEND_NAMED_VALUE(props, "Name", sAdapterBdName);
|
||||
BT_APPEND_NAMED_VALUE(props, "Address", sAdapterBdAddress);
|
||||
if (sAdapterDiscoverable) {
|
||||
sAdapterDiscoverable = false;
|
||||
BT_APPEND_NAMED_VALUE(props, "Discoverable", false);
|
||||
}
|
||||
if (sAdapterDiscovering) {
|
||||
sAdapterDiscovering = false;
|
||||
BT_APPEND_NAMED_VALUE(props, "Discovering", false);
|
||||
}
|
||||
|
||||
BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER), props);
|
||||
bs->DistributeSignal(signal);
|
||||
|
||||
// Cleanup bluetooth interfaces after BT state becomes BT_STATE_OFF.
|
||||
nsRefPtr<ProfileDeinitResultHandler> res =
|
||||
new ProfileDeinitResultHandler(MOZ_ARRAY_LENGTH(sDeinitManager));
|
||||
|
||||
for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sDeinitManager); ++i) {
|
||||
sDeinitManager[i](res);
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<nsRunnable> runnable =
|
||||
new BluetoothService::ToggleBtAck(sAdapterEnabled);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
return;
|
||||
}
|
||||
BluetoothService::AcknowledgeToggleBt(sAdapterEnabled);
|
||||
|
||||
if (sAdapterEnabled &&
|
||||
NS_FAILED(NS_DispatchToMainThread(new SetupAfterEnabledTask()))) {
|
||||
BT_WARNING("Failed to dispatch to main thread!");
|
||||
return;
|
||||
if (sAdapterEnabled) {
|
||||
// Bluetooth just enabled, clear profile controllers and runnable arrays.
|
||||
sControllerArray.Clear();
|
||||
sChangeDiscoveryRunnableArray.Clear();
|
||||
sSetPropertyRunnableArray.Clear();
|
||||
sGetDeviceRunnableArray.Clear();
|
||||
sFetchUuidsRunnableArray.Clear();
|
||||
sBondingRunnableArray.Clear();
|
||||
sUnbondingRunnableArray.Clear();
|
||||
|
||||
// Bluetooth scan mode is SCAN_MODE_CONNECTABLE by default, i.e., It should
|
||||
// be connectable and non-discoverable.
|
||||
NS_ENSURE_TRUE_VOID(sBtInterface);
|
||||
sBtInterface->SetAdapterProperty(
|
||||
BluetoothNamedValue(NS_ConvertUTF8toUTF16("Discoverable"), false),
|
||||
new SetAdapterPropertyDiscoverableResultHandler());
|
||||
|
||||
// Trigger BluetoothOppManager to listen
|
||||
BluetoothOppManager* opp = BluetoothOppManager::Get();
|
||||
if (!opp || !opp->Listen()) {
|
||||
BT_LOGR("Fail to start BluetoothOppManager listening");
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve promise if existed
|
||||
|
@ -16,6 +16,22 @@ BEGIN_BLUETOOTH_NAMESPACE
|
||||
class BluetoothServiceBluedroid : public BluetoothService
|
||||
, public BluetoothNotificationHandler
|
||||
{
|
||||
class CancelDiscoveryResultHandler;
|
||||
class CreateBondResultHandler;
|
||||
class DisableResultHandler;
|
||||
class EnableResultHandler;
|
||||
class GetRemoteDevicePropertiesResultHandler;
|
||||
class GetRemoteServicesResultHandler;
|
||||
class InitResultHandler;
|
||||
class PinReplyResultHandler;
|
||||
class ProfileDeinitResultHandler;
|
||||
class ProfileInitResultHandler;
|
||||
class RemoveBondResultHandler;
|
||||
class SetAdapterPropertyDiscoverableResultHandler;
|
||||
class SetAdapterPropertyResultHandler;
|
||||
class SspReplyResultHandler;
|
||||
class StartDiscoveryResultHandler;
|
||||
|
||||
public:
|
||||
BluetoothServiceBluedroid();
|
||||
~BluetoothServiceBluedroid();
|
||||
@ -193,6 +209,22 @@ public:
|
||||
uint8_t aLen) MOZ_OVERRIDE;
|
||||
virtual void LeTestModeNotification(BluetoothStatus aStatus,
|
||||
uint16_t aNumPackets) MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
static nsresult StartGonkBluetooth();
|
||||
static nsresult StopGonkBluetooth();
|
||||
static bool EnsureBluetoothHalLoad();
|
||||
|
||||
static void ConnectDisconnect(bool aConnect,
|
||||
const nsAString& aDeviceAddress,
|
||||
BluetoothReplyRunnable* aRunnable,
|
||||
uint16_t aServiceUuid, uint32_t aCod = 0);
|
||||
static void NextBluetoothProfileController();
|
||||
static ControlPlayStatus PlayStatusStringToControlPlayStatus(
|
||||
const nsAString& aPlayStatus);
|
||||
static void ReplyStatusError(BluetoothReplyRunnable* aReplyRunnable,
|
||||
BluetoothStatus aStatusCode,
|
||||
const nsAString& aCustomMsg);
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
@ -51,6 +51,7 @@ if CONFIG['MOZ_B2G_BT']:
|
||||
'bluedroid/BluetoothA2dpHALInterface.cpp',
|
||||
'bluedroid/BluetoothA2dpManager.cpp',
|
||||
'bluedroid/BluetoothAvrcpHALInterface.cpp',
|
||||
'bluedroid/BluetoothDaemonHandsfreeInterface.cpp',
|
||||
'bluedroid/BluetoothDaemonHelpers.cpp',
|
||||
'bluedroid/BluetoothDaemonInterface.cpp',
|
||||
'bluedroid/BluetoothDaemonSetupInterface.cpp',
|
||||
|
@ -94,6 +94,7 @@ function BrowserElementChild() {
|
||||
|
||||
this._isContentWindowCreated = false;
|
||||
this._pendingSetInputMethodActive = [];
|
||||
this._forceDispatchSelectionStateChanged = false;
|
||||
|
||||
this._init();
|
||||
};
|
||||
@ -161,8 +162,8 @@ BrowserElementChild.prototype = {
|
||||
/* useCapture = */ true,
|
||||
/* wantsUntrusted = */ false);
|
||||
|
||||
addEventListener('mozselectionchange',
|
||||
this._selectionChangeHandler.bind(this),
|
||||
addEventListener('mozselectionstatechanged',
|
||||
this._selectionStateChangedHandler.bind(this),
|
||||
/* useCapture = */ false,
|
||||
/* wantsUntrusted = */ false);
|
||||
|
||||
@ -591,23 +592,61 @@ BrowserElementChild.prototype = {
|
||||
sendAsyncMsg('scrollviewchange', detail);
|
||||
},
|
||||
|
||||
_selectionChangeHandler: function(e) {
|
||||
_selectionStateChangedHandler: function(e) {
|
||||
e.stopPropagation();
|
||||
let boundingClientRect = e.boundingClientRect;
|
||||
if (!boundingClientRect) {
|
||||
return;
|
||||
|
||||
let isCollapsed = (e.selectedText.length == 0);
|
||||
let isMouseUp = (e.states.indexOf('mouseup') == 0);
|
||||
let canPaste = this._isCommandEnabled("paste");
|
||||
|
||||
if (!this._forceDispatchSelectionStateChanged) {
|
||||
// SelectionStateChanged events with the following states are not
|
||||
// necessary to trigger the text dialog, bypass these events
|
||||
// by default.
|
||||
//
|
||||
if(e.states.length == 0 ||
|
||||
e.states.indexOf('drag') == 0 ||
|
||||
e.states.indexOf('keypress') == 0 ||
|
||||
e.states.indexOf('mousedown') == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The collapsed SelectionStateChanged event is unnecessary to dispatch,
|
||||
// bypass this event by default. But there is one exception to support
|
||||
// the shortcut mode which can paste previous copied content easily
|
||||
if (isCollapsed) {
|
||||
if (isMouseUp && canPaste) {
|
||||
//Dispatch this selection change event to support shortcut mode
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For every touch on the screen, there are always two mouse events received,
|
||||
// mousedown/mouseup, no matter touch or long tap on the screen. When there is
|
||||
// is a non-collapsed selection change event which comes with mouseup reason,
|
||||
// it implies some texts are selected. In order to hide the text dialog during next
|
||||
// touch, here sets the forceDispatchSelectionStateChanged flag as true to dispatch the
|
||||
// next SelecitonChange event(with the mousedown) so that the parent side can
|
||||
// hide the text dialog.
|
||||
if (isMouseUp && !isCollapsed) {
|
||||
this._forceDispatchSelectionStateChanged = true;
|
||||
} else {
|
||||
this._forceDispatchSelectionStateChanged = false;
|
||||
}
|
||||
|
||||
let zoomFactor = content.screen.width / content.innerWidth;
|
||||
|
||||
let detail = {
|
||||
rect: {
|
||||
width: boundingClientRect.width,
|
||||
height: boundingClientRect.height,
|
||||
top: boundingClientRect.top,
|
||||
bottom: boundingClientRect.bottom,
|
||||
left: boundingClientRect.left,
|
||||
right: boundingClientRect.right,
|
||||
width: boundingClientRect ? boundingClientRect.width : 0,
|
||||
height: boundingClientRect ? boundingClientRect.height : 0,
|
||||
top: boundingClientRect ? boundingClientRect.top : 0,
|
||||
bottom: boundingClientRect ? boundingClientRect.bottom : 0,
|
||||
left: boundingClientRect ? boundingClientRect.left : 0,
|
||||
right: boundingClientRect ? boundingClientRect.right : 0,
|
||||
},
|
||||
commands: {
|
||||
canSelectAll: this._isCommandEnabled("selectall"),
|
||||
@ -616,7 +655,7 @@ BrowserElementChild.prototype = {
|
||||
canPaste: this._isCommandEnabled("paste"),
|
||||
},
|
||||
zoomFactor: zoomFactor,
|
||||
reasons: e.reasons,
|
||||
states: e.states,
|
||||
isCollapsed: (e.selectedText.length == 0),
|
||||
};
|
||||
|
||||
@ -631,7 +670,7 @@ BrowserElementChild.prototype = {
|
||||
currentWindow = currentWindow.parent;
|
||||
}
|
||||
|
||||
sendAsyncMsg('selectionchange', detail);
|
||||
sendAsyncMsg('selectionstatechanged', detail);
|
||||
},
|
||||
|
||||
_themeColorChangedHandler: function(eventType, target) {
|
||||
|
@ -197,7 +197,7 @@ BrowserElementParent.prototype = {
|
||||
"got-visible": this._gotDOMRequestResult,
|
||||
"visibilitychange": this._childVisibilityChange,
|
||||
"got-set-input-method-active": this._gotDOMRequestResult,
|
||||
"selectionchange": this._handleSelectionChange,
|
||||
"selectionstatechanged": this._handleSelectionStateChanged,
|
||||
"scrollviewchange": this._handleScrollViewChange,
|
||||
"touchcarettap": this._handleTouchCaretTap
|
||||
};
|
||||
@ -435,8 +435,8 @@ BrowserElementParent.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
_handleSelectionChange: function(data) {
|
||||
let evt = this._createEvent('selectionchange', data.json,
|
||||
_handleSelectionStateChanged: function(data) {
|
||||
let evt = this._createEvent('selectionstatechanged', data.json,
|
||||
/* cancelable = */ false);
|
||||
this._frameElement.dispatchEvent(evt);
|
||||
},
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Any copyright is dedicated to the public domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that "cut, copy, paste, selectall" and selectionchange event works from inside an <iframe mozbrowser>.
|
||||
// Test that "cut, copy, paste, selectall" and selectionstatechanged event works from inside an <iframe mozbrowser>.
|
||||
"use strict";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
@ -142,9 +142,9 @@ function dispatchTest(e) {
|
||||
}
|
||||
|
||||
function testSelectAll(e) {
|
||||
iframe.addEventListener("mozbrowserselectionchange", function selectchangeforselectall(e) {
|
||||
iframe.removeEventListener("mozbrowserselectionchange", selectchangeforselectall, true);
|
||||
ok(true, "got mozbrowserselectionchange event." + stateMeaning);
|
||||
iframe.addEventListener("mozbrowserselectionstatechanged", function selectchangeforselectall(e) {
|
||||
iframe.removeEventListener("mozbrowserselectionstatechanged", selectchangeforselectall, true);
|
||||
ok(true, "got mozbrowserselectionstatechanged event." + stateMeaning);
|
||||
ok(e.detail, "event.detail is not null." + stateMeaning);
|
||||
ok(e.detail.width != 0, "event.detail.width is not zero" + stateMeaning);
|
||||
ok(e.detail.height != 0, "event.detail.height is not zero" + stateMeaning);
|
||||
@ -153,7 +153,7 @@ function testSelectAll(e) {
|
||||
|
||||
mm.addMessageListener('content-focus', function messageforfocus(msg) {
|
||||
mm.removeMessageListener('content-focus', messageforfocus);
|
||||
// test selectall command, after calling this the selectionchange event should be fired.
|
||||
// test selectall command, after calling this the selectionstatechanged event should be fired.
|
||||
doCommand('selectall');
|
||||
});
|
||||
|
||||
|
@ -223,25 +223,6 @@ WebGLFramebuffer::Attachment::RectangleObject() const
|
||||
// The following IsValidFBOTextureXXX functions check the internal format that
|
||||
// is used by GL or GL ES texture formats. This corresponds to the state that
|
||||
// is stored in WebGLTexture::ImageInfo::InternalFormat()
|
||||
static inline bool
|
||||
IsValidFBOTextureColorFormat(TexInternalFormat internalformat)
|
||||
{
|
||||
/* These formats are internal formats for each texture -- the actual low
|
||||
* level format, which we might have to do conversions for when running
|
||||
* against desktop GL (e.g. GL_RGBA + GL_FLOAT -> GL_RGBA32F).
|
||||
*
|
||||
* This function just handles all of them whether desktop GL or ES.
|
||||
*/
|
||||
|
||||
TexInternalFormat unsizedformat = UnsizedInternalFormatFromInternalFormat(internalformat);
|
||||
return unsizedformat == LOCAL_GL_ALPHA ||
|
||||
unsizedformat == LOCAL_GL_LUMINANCE ||
|
||||
unsizedformat == LOCAL_GL_LUMINANCE_ALPHA ||
|
||||
unsizedformat == LOCAL_GL_RGB ||
|
||||
unsizedformat == LOCAL_GL_RGBA ||
|
||||
unsizedformat == LOCAL_GL_SRGB ||
|
||||
unsizedformat == LOCAL_GL_SRGB_ALPHA;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsValidFBOTextureDepthFormat(GLenum internalformat)
|
||||
@ -258,14 +239,6 @@ IsValidFBOTextureDepthStencilFormat(GLenum internalformat)
|
||||
// The following IsValidFBORenderbufferXXX functions check the internal format
|
||||
// that is stored by WebGLRenderbuffer::InternalFormat(). Valid values can be
|
||||
// found in WebGLContext::RenderbufferStorage.
|
||||
static inline bool
|
||||
IsValidFBORenderbufferColorFormat(GLenum internalFormat)
|
||||
{
|
||||
return internalFormat == LOCAL_GL_RGB565 ||
|
||||
internalFormat == LOCAL_GL_RGB5_A1 ||
|
||||
internalFormat == LOCAL_GL_RGBA4 ||
|
||||
internalFormat == LOCAL_GL_SRGB8_ALPHA8_EXT;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsValidFBORenderbufferDepthFormat(GLenum internalFormat)
|
||||
@ -702,7 +675,6 @@ WebGLFramebuffer::HasDefinedAttachments() const
|
||||
return hasAttachments;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
IsIncomplete(const WebGLFramebuffer::Attachment& cur)
|
||||
{
|
||||
@ -782,7 +754,6 @@ WebGLFramebuffer::AllImageRectsMatch() const
|
||||
return imageRectsMatch;
|
||||
}
|
||||
|
||||
|
||||
const WebGLRectangleObject&
|
||||
WebGLFramebuffer::RectangleObject() const
|
||||
{
|
||||
|
@ -2903,6 +2903,14 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
|
||||
mDecoder->SetFragmentEndTime(mFragmentEnd);
|
||||
}
|
||||
|
||||
// Tracks just got known, pass the info along to the output streams
|
||||
uint8_t hints = (mHasAudio ? DOMMediaStream::HINT_CONTENTS_AUDIO : 0) |
|
||||
(mHasVideo ? DOMMediaStream::HINT_CONTENTS_VIDEO : 0);
|
||||
for (uint32_t i = 0; i < mOutputStreams.Length(); ++i) {
|
||||
OutputMediaStream* out = &mOutputStreams[i];
|
||||
out->mStream->SetHintContents(hints);
|
||||
}
|
||||
|
||||
// If this element had a video track, but consists only of an audio track now,
|
||||
// delete the VideoFrameContainer. This happens when the src is changed to an
|
||||
// audio only file.
|
||||
|
@ -793,8 +793,6 @@ nsTextInputListener::NotifySelectionChanged(nsIDOMDocument* aDoc, nsISelection*
|
||||
}
|
||||
}
|
||||
|
||||
UpdateTextInputCommands(NS_LITERAL_STRING("selectionchange"), aSel, aReason);
|
||||
|
||||
// if the collapsed state did not change, don't fire notifications
|
||||
if (collapsed == mSelectionWasCollapsed)
|
||||
return NS_OK;
|
||||
|
@ -5130,7 +5130,7 @@ public:
|
||||
|
||||
virtual void
|
||||
OnOriginClearCompleted(PersistenceType aPersistenceType,
|
||||
const OriginOrPatternString& aOriginOrPattern)
|
||||
const nsACString& aOrigin)
|
||||
MOZ_OVERRIDE;
|
||||
|
||||
virtual void
|
||||
@ -5941,7 +5941,8 @@ Factory::AllocPBackgroundIDBFactoryRequestParent(
|
||||
|
||||
const DatabaseMetadata& metadata = commonParams->metadata();
|
||||
if (NS_WARN_IF(metadata.persistenceType() != PERSISTENCE_TYPE_PERSISTENT &&
|
||||
metadata.persistenceType() != PERSISTENCE_TYPE_TEMPORARY)) {
|
||||
metadata.persistenceType() != PERSISTENCE_TYPE_TEMPORARY &&
|
||||
metadata.persistenceType() != PERSISTENCE_TYPE_DEFAULT)) {
|
||||
ASSERT_UNLESS_FUZZING();
|
||||
return nullptr;
|
||||
}
|
||||
@ -9429,14 +9430,13 @@ QuotaClient::GetUsageForOrigin(PersistenceType aPersistenceType,
|
||||
}
|
||||
|
||||
void
|
||||
QuotaClient::OnOriginClearCompleted(
|
||||
PersistenceType aPersistenceType,
|
||||
const OriginOrPatternString& aOriginOrPattern)
|
||||
QuotaClient::OnOriginClearCompleted(PersistenceType aPersistenceType,
|
||||
const nsACString& aOrigin)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
|
||||
if (IndexedDatabaseManager* mgr = IndexedDatabaseManager::Get()) {
|
||||
mgr->InvalidateFileManagers(aPersistenceType, aOriginOrPattern);
|
||||
mgr->InvalidateFileManagers(aPersistenceType, aOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10753,6 +10753,9 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
|
||||
QuotaManager::GetInfoForChrome(&mGroup, &mOrigin, &mIsApp,
|
||||
&mHasUnlimStoragePerm);
|
||||
|
||||
MOZ_ASSERT(!QuotaManager::IsFirstPromptRequired(persistenceType, mOrigin,
|
||||
mIsApp));
|
||||
|
||||
mEnforcingQuota =
|
||||
QuotaManager::IsQuotaEnforced(persistenceType, mOrigin, mIsApp,
|
||||
mHasUnlimStoragePerm);
|
||||
@ -10771,14 +10774,19 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCString group;
|
||||
nsCString origin;
|
||||
bool isApp;
|
||||
bool hasUnlimStoragePerm;
|
||||
rv = QuotaManager::GetInfoFromPrincipal(principal, &group, &origin,
|
||||
&isApp, &hasUnlimStoragePerm);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
PermissionRequestBase::PermissionValue permission;
|
||||
|
||||
if (persistenceType == PERSISTENCE_TYPE_TEMPORARY) {
|
||||
// Temporary storage doesn't need to check the permission.
|
||||
permission = PermissionRequestBase::kPermissionAllowed;
|
||||
} else {
|
||||
MOZ_ASSERT(persistenceType == PERSISTENCE_TYPE_PERSISTENT);
|
||||
|
||||
if (QuotaManager::IsFirstPromptRequired(persistenceType, origin, isApp)) {
|
||||
#ifdef MOZ_CHILD_PERMISSIONS
|
||||
if (aContentParent) {
|
||||
if (NS_WARN_IF(!AssertAppPrincipal(aContentParent, principal))) {
|
||||
@ -10799,16 +10807,16 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
permission = PermissionRequestBase::kPermissionAllowed;
|
||||
}
|
||||
|
||||
if (permission != PermissionRequestBase::kPermissionDenied &&
|
||||
State_Initial == mState) {
|
||||
rv = QuotaManager::GetInfoFromPrincipal(principal, persistenceType, &mGroup,
|
||||
&mOrigin, &mIsApp,
|
||||
&mHasUnlimStoragePerm);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
mGroup = group;
|
||||
mOrigin = origin;
|
||||
mIsApp = isApp;
|
||||
mHasUnlimStoragePerm = hasUnlimStoragePerm;
|
||||
|
||||
mEnforcingQuota =
|
||||
QuotaManager::IsQuotaEnforced(persistenceType, mOrigin, mIsApp,
|
||||
@ -10971,22 +10979,14 @@ FactoryOp::FinishOpen()
|
||||
MOZ_ASSERT(!mContentParent);
|
||||
MOZ_ASSERT(!QuotaClient::IsShuttingDownOnMainThread());
|
||||
|
||||
PersistenceType persistenceType = mCommonParams.metadata().persistenceType();
|
||||
|
||||
// XXX This is temporary, but we don't currently support the explicit
|
||||
// 'persistent' storage type.
|
||||
if (persistenceType == PERSISTENCE_TYPE_PERSISTENT &&
|
||||
mCommonParams.metadata().persistenceTypeIsExplicit()) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
QuotaManager* quotaManager = QuotaManager::GetOrCreate();
|
||||
if (NS_WARN_IF(!quotaManager)) {
|
||||
IDB_REPORT_INTERNAL_ERR();
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
PersistenceType persistenceType = mCommonParams.metadata().persistenceType();
|
||||
|
||||
nsresult rv =
|
||||
quotaManager->
|
||||
WaitForOpenAllowed(OriginOrPatternString::FromOrigin(mOrigin),
|
||||
|
@ -998,10 +998,8 @@ IDBDatabase::GetQuotaInfo(nsACString& aOrigin,
|
||||
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
PersistenceType persistenceType = mSpec->metadata().persistenceType();
|
||||
|
||||
if (aPersistenceType) {
|
||||
*aPersistenceType = persistenceType;
|
||||
*aPersistenceType = mSpec->metadata().persistenceType();
|
||||
MOZ_ASSERT(*aPersistenceType != PERSISTENCE_TYPE_INVALID);
|
||||
}
|
||||
|
||||
@ -1025,7 +1023,6 @@ IDBDatabase::GetQuotaInfo(nsACString& aOrigin,
|
||||
}
|
||||
|
||||
rv = QuotaManager::GetInfoFromPrincipal(principal,
|
||||
persistenceType,
|
||||
nullptr,
|
||||
&aOrigin,
|
||||
nullptr,
|
||||
|
@ -479,24 +479,18 @@ IDBFactory::OpenInternal(nsIPrincipal* aPrincipal,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// XXX We need a bug to switch to temporary storage by default.
|
||||
|
||||
PersistenceType persistenceType;
|
||||
bool persistenceTypeIsExplicit;
|
||||
|
||||
if (principalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
|
||||
// Chrome privilege always gets persistent storage.
|
||||
persistenceType = PERSISTENCE_TYPE_PERSISTENT;
|
||||
persistenceTypeIsExplicit = false;
|
||||
} else {
|
||||
persistenceType = PersistenceTypeFromStorage(aStorageType);
|
||||
persistenceTypeIsExplicit = aStorageType.WasPassed();
|
||||
}
|
||||
|
||||
DatabaseMetadata& metadata = commonParams.metadata();
|
||||
metadata.name() = aName;
|
||||
metadata.persistenceType() = persistenceType;
|
||||
metadata.persistenceTypeIsExplicit() = persistenceTypeIsExplicit;
|
||||
|
||||
FactoryRequestParams params;
|
||||
if (aDeleting) {
|
||||
|
@ -157,15 +157,9 @@ IDBMutableFile::Create(IDBDatabase* aDatabase,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const DatabaseSpec* spec = aDatabase->Spec();
|
||||
MOZ_ASSERT(spec);
|
||||
|
||||
PersistenceType persistenceType = spec->metadata().persistenceType();
|
||||
|
||||
nsCString group;
|
||||
nsCString origin;
|
||||
if (NS_WARN_IF(NS_FAILED(QuotaManager::GetInfoFromPrincipal(principal,
|
||||
persistenceType,
|
||||
&group,
|
||||
&origin,
|
||||
nullptr,
|
||||
@ -173,6 +167,11 @@ IDBMutableFile::Create(IDBDatabase* aDatabase,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const DatabaseSpec* spec = aDatabase->Spec();
|
||||
MOZ_ASSERT(spec);
|
||||
|
||||
PersistenceType persistenceType = spec->metadata().persistenceType();
|
||||
|
||||
nsCString storageId;
|
||||
QuotaManager::GetStorageId(persistenceType,
|
||||
origin,
|
||||
|
@ -80,7 +80,8 @@ public:
|
||||
AssertIsOnIOThread();
|
||||
|
||||
return !mPersistentStorageFileManagers.IsEmpty() ||
|
||||
!mTemporaryStorageFileManagers.IsEmpty();
|
||||
!mTemporaryStorageFileManagers.IsEmpty() ||
|
||||
!mDefaultStorageFileManagers.IsEmpty();
|
||||
}
|
||||
|
||||
void
|
||||
@ -105,6 +106,7 @@ private:
|
||||
|
||||
nsTArray<nsRefPtr<FileManager> > mPersistentStorageFileManagers;
|
||||
nsTArray<nsRefPtr<FileManager> > mTemporaryStorageFileManagers;
|
||||
nsTArray<nsRefPtr<FileManager> > mDefaultStorageFileManagers;
|
||||
};
|
||||
|
||||
namespace {
|
||||
@ -178,16 +180,6 @@ private:
|
||||
bool mWaiting;
|
||||
};
|
||||
|
||||
struct MOZ_STACK_CLASS InvalidateInfo
|
||||
{
|
||||
InvalidateInfo(PersistenceType aPersistenceType, const nsACString& aPattern)
|
||||
: persistenceType(aPersistenceType), pattern(aPattern)
|
||||
{ }
|
||||
|
||||
PersistenceType persistenceType;
|
||||
const nsACString& pattern;
|
||||
};
|
||||
|
||||
void
|
||||
TestingPrefChangedCallback(const char* aPrefName, void* aClosure)
|
||||
{
|
||||
@ -554,66 +546,49 @@ IndexedDatabaseManager::AddFileManager(FileManager* aFileManager)
|
||||
info->AddFileManager(aFileManager);
|
||||
}
|
||||
|
||||
// static
|
||||
PLDHashOperator
|
||||
IndexedDatabaseManager::InvalidateAndRemoveFileManagers(
|
||||
const nsACString& aKey,
|
||||
nsAutoPtr<FileManagerInfo>& aValue,
|
||||
void* aUserArg)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
NS_ASSERTION(!aKey.IsEmpty(), "Empty key!");
|
||||
NS_ASSERTION(aValue, "Null pointer!");
|
||||
|
||||
if (!aUserArg) {
|
||||
aValue->InvalidateAllFileManagers();
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
||||
InvalidateInfo* info = static_cast<InvalidateInfo*>(aUserArg);
|
||||
|
||||
if (PatternMatchesOrigin(info->pattern, aKey)) {
|
||||
aValue->InvalidateAndRemoveFileManagers(info->persistenceType);
|
||||
|
||||
if (!aValue->HasFileManagers()) {
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
IndexedDatabaseManager::InvalidateAllFileManagers()
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
|
||||
mFileManagerInfos.Enumerate(InvalidateAndRemoveFileManagers, nullptr);
|
||||
class MOZ_STACK_CLASS Helper MOZ_FINAL
|
||||
{
|
||||
public:
|
||||
static PLDHashOperator
|
||||
Enumerate(const nsACString& aKey,
|
||||
FileManagerInfo* aValue,
|
||||
void* aUserArg)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
MOZ_ASSERT(!aKey.IsEmpty());
|
||||
MOZ_ASSERT(aValue);
|
||||
|
||||
aValue->InvalidateAllFileManagers();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
};
|
||||
|
||||
mFileManagerInfos.EnumerateRead(Helper::Enumerate, nullptr);
|
||||
mFileManagerInfos.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
IndexedDatabaseManager::InvalidateFileManagers(
|
||||
PersistenceType aPersistenceType,
|
||||
const OriginOrPatternString& aOriginOrPattern)
|
||||
const nsACString& aOrigin)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
NS_ASSERTION(!aOriginOrPattern.IsEmpty(), "Empty pattern!");
|
||||
MOZ_ASSERT(!aOrigin.IsEmpty());
|
||||
|
||||
if (aOriginOrPattern.IsOrigin()) {
|
||||
FileManagerInfo* info;
|
||||
if (!mFileManagerInfos.Get(aOriginOrPattern, &info)) {
|
||||
return;
|
||||
}
|
||||
|
||||
info->InvalidateAndRemoveFileManagers(aPersistenceType);
|
||||
|
||||
if (!info->HasFileManagers()) {
|
||||
mFileManagerInfos.Remove(aOriginOrPattern);
|
||||
}
|
||||
FileManagerInfo* info;
|
||||
if (!mFileManagerInfos.Get(aOrigin, &info)) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
InvalidateInfo info(aPersistenceType, aOriginOrPattern);
|
||||
mFileManagerInfos.Enumerate(InvalidateAndRemoveFileManagers, &info);
|
||||
|
||||
info->InvalidateAndRemoveFileManagers(aPersistenceType);
|
||||
|
||||
if (!info->HasFileManagers()) {
|
||||
mFileManagerInfos.Remove(aOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
@ -792,6 +767,10 @@ FileManagerInfo::InvalidateAllFileManagers() const
|
||||
for (i = 0; i < mTemporaryStorageFileManagers.Length(); i++) {
|
||||
mTemporaryStorageFileManagers[i]->Invalidate();
|
||||
}
|
||||
|
||||
for (i = 0; i < mDefaultStorageFileManagers.Length(); i++) {
|
||||
mDefaultStorageFileManagers[i]->Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -836,11 +815,12 @@ FileManagerInfo::GetArray(PersistenceType aPersistenceType)
|
||||
return mPersistentStorageFileManagers;
|
||||
case PERSISTENCE_TYPE_TEMPORARY:
|
||||
return mTemporaryStorageFileManagers;
|
||||
case PERSISTENCE_TYPE_DEFAULT:
|
||||
return mDefaultStorageFileManagers;
|
||||
|
||||
case PERSISTENCE_TYPE_INVALID:
|
||||
default:
|
||||
MOZ_CRASH("Bad storage type value!");
|
||||
return mPersistentStorageFileManagers;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,12 +26,6 @@ namespace dom {
|
||||
|
||||
class TabContext;
|
||||
|
||||
namespace quota {
|
||||
|
||||
class OriginOrPatternString;
|
||||
|
||||
} // namespace quota
|
||||
|
||||
namespace indexedDB {
|
||||
|
||||
class FileManager;
|
||||
@ -39,7 +33,6 @@ class FileManagerInfo;
|
||||
|
||||
class IndexedDatabaseManager MOZ_FINAL : public nsIObserver
|
||||
{
|
||||
typedef mozilla::dom::quota::OriginOrPatternString OriginOrPatternString;
|
||||
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
||||
|
||||
public:
|
||||
@ -96,7 +89,7 @@ public:
|
||||
|
||||
void
|
||||
InvalidateFileManagers(PersistenceType aPersistenceType,
|
||||
const OriginOrPatternString& aOriginOrPattern);
|
||||
const nsACString& aOrigin);
|
||||
|
||||
void
|
||||
InvalidateFileManager(PersistenceType aPersistenceType,
|
||||
@ -150,11 +143,6 @@ private:
|
||||
void
|
||||
Destroy();
|
||||
|
||||
static PLDHashOperator
|
||||
InvalidateAndRemoveFileManagers(const nsACString& aKey,
|
||||
nsAutoPtr<FileManagerInfo>& aValue,
|
||||
void* aUserArg);
|
||||
|
||||
// Maintains a list of all file managers per origin. This list isn't
|
||||
// protected by any mutex but it is only ever touched on the IO thread.
|
||||
nsClassHashtable<nsCStringHashKey, FileManagerInfo> mFileManagerInfos;
|
||||
|
@ -67,7 +67,6 @@ struct DatabaseMetadata
|
||||
nsString name;
|
||||
uint64_t version;
|
||||
PersistenceType persistenceType;
|
||||
bool persistenceTypeIsExplicit;
|
||||
};
|
||||
|
||||
struct ObjectStoreMetadata
|
||||
|
@ -102,13 +102,11 @@ PermissionRequestBase::PermissionValueForIntPermission(uint32_t aIntPermission)
|
||||
{
|
||||
AssertSanity();
|
||||
|
||||
// The 'indexedDB' permission is unusual in that the default action is to
|
||||
// allow access. Switch that here to make the logic clearer.
|
||||
switch (aIntPermission) {
|
||||
case kPermissionDefault:
|
||||
return kPermissionAllowed;
|
||||
case kPermissionAllowed:
|
||||
return kPermissionPrompt;
|
||||
case kPermissionAllowed:
|
||||
return kPermissionAllowed;
|
||||
case kPermissionDenied:
|
||||
return kPermissionDenied;
|
||||
default:
|
||||
@ -180,13 +178,11 @@ PermissionRequestBase::SetExplicitPermission(nsIPrincipal* aPrincipal,
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv = aIntPermission == kPermissionAllowed ?
|
||||
permMan->RemoveFromPrincipal(aPrincipal, kPermissionString) :
|
||||
permMan->AddFromPrincipal(aPrincipal,
|
||||
kPermissionString,
|
||||
aIntPermission,
|
||||
nsIPermissionManager::EXPIRE_NEVER,
|
||||
/* aExpireTime */ 0);
|
||||
nsresult rv = permMan->AddFromPrincipal(aPrincipal,
|
||||
kPermissionString,
|
||||
aIntPermission,
|
||||
nsIPermissionManager::EXPIRE_NEVER,
|
||||
/* aExpireTime */ 0);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return;
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ function test()
|
||||
requestLongerTimeout(2);
|
||||
waitForExplicitFinish();
|
||||
// Avoids the prompt
|
||||
setPermission(testPageURL1, "indexedDB", "unknown");
|
||||
setPermission(testPageURL2, "indexedDB", "unknown");
|
||||
setPermission(testPageURL1, "indexedDB");
|
||||
setPermission(testPageURL2, "indexedDB");
|
||||
executeSoon(test1);
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ function test3()
|
||||
{
|
||||
// Remove database from domain 2
|
||||
ForgetAboutSite.removeDataFromDomain(domains[1]);
|
||||
setPermission(testPageURL4, "indexedDB", "unknown");
|
||||
setPermission(testPageURL4, "indexedDB");
|
||||
executeSoon(test4);
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,8 @@
|
||||
{
|
||||
const name = window.location.pathname;
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
let request = indexedDB.open(name, { version: 1,
|
||||
storage: "persistent" });
|
||||
request.onerror = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
@ -14,7 +14,7 @@ function test()
|
||||
PopupNotifications.transitionsEnabled = false;
|
||||
|
||||
// We want a prompt.
|
||||
setPermission(testPageURL, "indexedDB", "allow");
|
||||
removePermission(testPageURL, "indexedDB");
|
||||
executeSoon(test1);
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ function test1()
|
||||
"First database creation was successful");
|
||||
ok(!exception, "No exception");
|
||||
is(getPermission(testPageURL, "indexedDB"),
|
||||
Components.interfaces.nsIPermissionManager.UNKNOWN_ACTION,
|
||||
Components.interfaces.nsIPermissionManager.ALLOW_ACTION,
|
||||
"Correct permission set");
|
||||
gBrowser.removeCurrentTab();
|
||||
executeSoon(test2);
|
||||
@ -67,7 +67,7 @@ function test2()
|
||||
"First database creation was successful");
|
||||
ok(!exception, "No exception");
|
||||
is(getPermission(testPageURL, "indexedDB"),
|
||||
Components.interfaces.nsIPermissionManager.UNKNOWN_ACTION,
|
||||
Components.interfaces.nsIPermissionManager.ALLOW_ACTION,
|
||||
"Correct permission set");
|
||||
gBrowser.removeCurrentTab();
|
||||
unregisterAllPopupEventHandlers();
|
||||
|
@ -12,7 +12,7 @@ function test()
|
||||
waitForExplicitFinish();
|
||||
// We want the prompt.
|
||||
PopupNotifications.transitionsEnabled = false;
|
||||
setPermission(testPageURL, "indexedDB", "allow");
|
||||
removePermission(testPageURL, "indexedDB");
|
||||
executeSoon(test1);
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,8 @@ const notificationID = "indexedDB-permissions-prompt";
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
// Avoids the actual prompt
|
||||
setPermission(testPageURL, "indexedDB");
|
||||
executeSoon(test1);
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,9 @@
|
||||
window.removeEventListener("indexedDB-addMore", onAddMore, true);
|
||||
window.removeEventListener("indexedDB-done", onDone, true);
|
||||
|
||||
let request = indexedDB.open(window.location.pathname, version++);
|
||||
let request =
|
||||
indexedDB.open(window.location.pathname, { version: version++,
|
||||
storage: "persistent" });
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = function(event) {
|
||||
db.deleteObjectStore("foo");
|
||||
@ -55,7 +57,8 @@
|
||||
window.addEventListener("indexedDB-addMore", onAddMore, true);
|
||||
window.addEventListener("indexedDB-done", onDone, true);
|
||||
|
||||
let request = indexedDB.open(name, version++);
|
||||
let request = indexedDB.open(name, { version: version++,
|
||||
storage: "persistent" });
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
@ -13,6 +13,7 @@ function test()
|
||||
waitForExplicitFinish();
|
||||
requestLongerTimeout(10);
|
||||
PopupNotifications.transitionsEnabled = false;
|
||||
setPermission(testPageURL, "indexedDB");
|
||||
removePermission(testPageURL, "indexedDB-unlimited");
|
||||
Services.prefs.setIntPref("dom.indexedDB.warningQuota", 2);
|
||||
executeSoon(test1);
|
||||
@ -43,7 +44,7 @@ function test1()
|
||||
"Correct permission set");
|
||||
gBrowser.removeCurrentTab();
|
||||
unregisterAllPopupEventHandlers();
|
||||
executeSoon(finish);
|
||||
executeSoon(test2);
|
||||
});
|
||||
executeSoon(function() { dispatchEvent("indexedDB-done"); });
|
||||
}
|
||||
|
@ -13,7 +13,8 @@
|
||||
function onAddMore() {
|
||||
const name = window.location.pathname + i++;
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
let request = indexedDB.open(name, { version: 1,
|
||||
storage: "persistent" });
|
||||
request.onerror = errorHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
|
@ -13,6 +13,7 @@ function test()
|
||||
waitForExplicitFinish();
|
||||
requestLongerTimeout(10);
|
||||
PopupNotifications.transitionsEnabled = false;
|
||||
setPermission(testPageURL, "indexedDB");
|
||||
removePermission(testPageURL, "indexedDB-unlimited");
|
||||
Services.prefs.setIntPref("dom.indexedDB.warningQuota", 2);
|
||||
executeSoon(test1);
|
||||
|
@ -49,7 +49,8 @@
|
||||
deleteRequest.onerror = errorHandler;
|
||||
deleteRequest.onsuccess = function () {
|
||||
// It is imperative that we open a different database this time.
|
||||
let request = indexedDB.open("take2", 1);
|
||||
let request = indexedDB.open("take2", { version: 1,
|
||||
storage: "persistent" });
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = function(event) {
|
||||
db = event.target.result;
|
||||
@ -67,7 +68,8 @@
|
||||
window.addEventListener("indexedDB-reset", onReset, true);
|
||||
window.addEventListener("indexedDB-done", onDone, true);
|
||||
|
||||
let request = indexedDB.open(name, 1);
|
||||
let request = indexedDB.open(name, { version: 1,
|
||||
storage: "persistent" });
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
@ -13,6 +13,7 @@ function test()
|
||||
waitForExplicitFinish();
|
||||
requestLongerTimeout(10);
|
||||
PopupNotifications.transitionsEnabled = false;
|
||||
setPermission(testPageURL, "indexedDB");
|
||||
removePermission(testPageURL, "indexedDB-unlimited");
|
||||
Services.prefs.setIntPref("dom.indexedDB.warningQuota", 2);
|
||||
executeSoon(test1);
|
||||
|
@ -13,6 +13,7 @@ function test()
|
||||
waitForExplicitFinish();
|
||||
requestLongerTimeout(10);
|
||||
PopupNotifications.transitionsEnabled = false;
|
||||
setPermission(testPageURL, "indexedDB");
|
||||
removePermission(testPageURL, "indexedDB-unlimited");
|
||||
Services.prefs.setIntPref("dom.indexedDB.warningQuota", 2);
|
||||
executeSoon(test1);
|
||||
|
@ -49,6 +49,8 @@
|
||||
};
|
||||
|
||||
function testSteps() {
|
||||
window.parent.SpecialPowers.addPermission("indexedDB", true, document);
|
||||
|
||||
let request = indexedDB.open(window.location.pathname, 1);
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
request.onerror = grabEventAndContinueHandler;
|
||||
|
@ -87,6 +87,8 @@
|
||||
}
|
||||
|
||||
function testSteps() {
|
||||
window.parent.SpecialPowers.addPermission("indexedDB", true, document);
|
||||
|
||||
let request = indexedDB.open(window.location.pathname, 1);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
|
@ -51,6 +51,8 @@
|
||||
};
|
||||
|
||||
function testSteps() {
|
||||
window.parent.SpecialPowers.addPermission("indexedDB", true, document);
|
||||
|
||||
// Test 1: Throwing an exception in an upgradeneeded handler should
|
||||
// abort the versionchange transaction and fire an error at the request.
|
||||
let request = indexedDB.open(window.location.pathname, 1);
|
||||
|
@ -109,24 +109,10 @@ function dispatchEvent(eventName)
|
||||
gBrowser.selectedBrowser.contentWindow.dispatchEvent(event);
|
||||
}
|
||||
|
||||
function setPermission(url, permission, value)
|
||||
function setPermission(url, permission)
|
||||
{
|
||||
const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
|
||||
|
||||
switch (value) {
|
||||
case "allow":
|
||||
value = nsIPermissionManager.ALLOW_ACTION;
|
||||
break;
|
||||
case "deny":
|
||||
value = nsIPermissionManager.DENY_ACTION;
|
||||
break;
|
||||
case "unknown":
|
||||
value = nsIPermissionManager.UNKNOWN_ACTION;
|
||||
break;
|
||||
default:
|
||||
throw new Error("No idea what to set here!");
|
||||
}
|
||||
|
||||
let uri = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService)
|
||||
.newURI(url, null, null);
|
||||
@ -135,8 +121,9 @@ function setPermission(url, permission, value)
|
||||
.getNoAppCodebasePrincipal(uri);
|
||||
|
||||
Components.classes["@mozilla.org/permissionmanager;1"]
|
||||
.getService(Components.interfaces.nsIPermissionManager)
|
||||
.addFromPrincipal(principal, permission, value);
|
||||
.getService(nsIPermissionManager)
|
||||
.addFromPrincipal(principal, permission,
|
||||
nsIPermissionManager.ALLOW_ACTION);
|
||||
}
|
||||
|
||||
function removePermission(url, permission)
|
||||
|
@ -49,6 +49,7 @@ if (!window.runTest) {
|
||||
{
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
allowIndexedDB();
|
||||
if (limitedQuota) {
|
||||
denyUnlimitedQuota();
|
||||
}
|
||||
@ -66,10 +67,11 @@ if (!window.runTest) {
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
resetUnlimitedQuota();
|
||||
resetExperimental();
|
||||
resetArchiveReader();
|
||||
resetExperimental();
|
||||
resetTesting();
|
||||
resetUnlimitedQuota();
|
||||
resetIndexedDB();
|
||||
SpecialPowers.notifyObserversInParentProcess(null, "disk-space-watcher",
|
||||
"free");
|
||||
|
||||
@ -197,6 +199,16 @@ function removePermission(type, url)
|
||||
SpecialPowers.removePermission(type, url);
|
||||
}
|
||||
|
||||
function allowIndexedDB(url)
|
||||
{
|
||||
addPermission("indexedDB", true, url);
|
||||
}
|
||||
|
||||
function resetIndexedDB(url)
|
||||
{
|
||||
removePermission("indexedDB", url);
|
||||
}
|
||||
|
||||
function allowUnlimitedQuota(url)
|
||||
{
|
||||
addPermission("indexedDB-unlimited", true, url);
|
||||
|
@ -151,9 +151,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_deleteDatabase_interactions.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_disabled_quota_prompt.html]
|
||||
# Test temporarily disabled.
|
||||
skip-if = true
|
||||
# skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_error_events_abort_transactions.html]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
|
||||
[test_event_propagation.html]
|
||||
|
@ -40,6 +40,7 @@
|
||||
{
|
||||
const databaseName = window.location.pathname;
|
||||
const databaseVersion = 1;
|
||||
const databaseStorage = "persistent";
|
||||
const objectStoreName = "foo";
|
||||
|
||||
info("setting quota pref");
|
||||
@ -50,7 +51,8 @@
|
||||
|
||||
info("opening database");
|
||||
|
||||
let request = indexedDB.open(databaseName, databaseVersion);
|
||||
let request = indexedDB.open(databaseName, {version: databaseVersion,
|
||||
storage: databaseStorage});
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
|
@ -14,6 +14,7 @@
|
||||
{
|
||||
const name = window.location.pathname;
|
||||
const version = 1;
|
||||
const storages = ["persistent", "temporary", "default"];
|
||||
|
||||
const objectStoreName = "Foo";
|
||||
const data = { key: 1, value: "bar" };
|
||||
@ -27,84 +28,44 @@
|
||||
is(e.name, "TypeError", "Good error name.");
|
||||
}
|
||||
|
||||
let request = indexedDB.open(name, { version: version,
|
||||
storage: "persistent" });
|
||||
request.onerror = grabEventAndContinueHandler;
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
let event = yield undefined;
|
||||
for (let storage of storages) {
|
||||
let request = indexedDB.open(name, { version: version,
|
||||
storage: storage });
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
let event = yield undefined;
|
||||
|
||||
is(event.type, "error", "Got error event");
|
||||
is(event.target, request, "Got correct target");
|
||||
is(event.target.error.name, "UnknownError", "Got correct error name");
|
||||
event.preventDefault();
|
||||
is(event.type, "upgradeneeded", "Got correct event type");
|
||||
|
||||
request = indexedDB.open(name, { version: version });
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
is(event.type, "upgradeneeded", "Got correct event type");
|
||||
let objectStore = db.createObjectStore(objectStoreName, { });
|
||||
|
||||
let db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
event = yield undefined;
|
||||
|
||||
let objectStore = db.createObjectStore(objectStoreName, { });
|
||||
is(event.type, "success", "Got correct event type");
|
||||
|
||||
event = yield undefined;
|
||||
is(db.name, name, "Correct name");
|
||||
is(db.version, version, "Correct version");
|
||||
is(db.storage, storage, "Correct persistence type");
|
||||
|
||||
is(event.type, "success", "Got correct event type");
|
||||
objectStore = db.transaction([objectStoreName], "readwrite")
|
||||
.objectStore(objectStoreName);
|
||||
|
||||
is(db.name, name, "Correct name");
|
||||
is(db.version, version, "Correct version");
|
||||
is(db.storage, "persistent", "Correct persistence type");
|
||||
request = objectStore.get(data.key);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
objectStore = db.transaction([objectStoreName], "readwrite")
|
||||
.objectStore(objectStoreName);
|
||||
is(event.target.result, null, "Got no data");
|
||||
|
||||
request = objectStore.get(data.key);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
request = objectStore.add(data.value, data.key);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, null, "Got no data");
|
||||
|
||||
request = objectStore.add(data.value, data.key);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, data.key, "Got correct key");
|
||||
|
||||
request = indexedDB.open(name, { version: version,
|
||||
storage: "temporary" });
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "upgradeneeded", "Got correct event type");
|
||||
|
||||
db = event.target.result;
|
||||
db.onerror = errorHandler;
|
||||
|
||||
objectStore = db.createObjectStore(objectStoreName, { });
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
is(event.type, "success", "Got correct event type");
|
||||
|
||||
is(db.name, name, "Correct name");
|
||||
is(db.version, version, "Correct version");
|
||||
is(db.storage, "temporary", "Correct persistence type");
|
||||
|
||||
objectStore = db.transaction([objectStoreName])
|
||||
.objectStore(objectStoreName);
|
||||
|
||||
request = objectStore.get(data.key);
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
is(event.target.result, null, "Got no data");
|
||||
is(event.target.result, data.key, "Got correct key");
|
||||
}
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user