зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to fx-team, a=merge
--HG-- extra : commitid : DtA94EPxpak
This commit is contained in:
Коммит
4f7b1b59b7
|
@ -692,7 +692,6 @@ pref("layout.css.scroll-snap.enabled", true);
|
|||
pref("dom.ipc.processPriorityManager.enabled", true);
|
||||
pref("dom.ipc.processPriorityManager.backgroundGracePeriodMS", 1000);
|
||||
pref("dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS", 5000);
|
||||
pref("dom.ipc.processPriorityManager.memoryPressureGracePeriodMS", 3000);
|
||||
pref("dom.ipc.processPriorityManager.temporaryPriorityLockMS", 5000);
|
||||
|
||||
// Number of different background/foreground levels for background/foreground
|
||||
|
@ -780,7 +779,12 @@ pref("hal.gonk.COMPOSITOR.nice", -4);
|
|||
// this too high, then we'll send out a memory pressure event every Z seconds
|
||||
// (see below), even while we have processes that we would happily kill in
|
||||
// order to free up memory.
|
||||
pref("hal.processPriorityManager.gonk.notifyLowMemUnderKB", 14336);
|
||||
pref("gonk.notifyHardLowMemUnderKB", 14336);
|
||||
|
||||
// Fire a memory pressure event when the system has less than Xmb of memory
|
||||
// remaining and then switch to the hard trigger, see above. This should be
|
||||
// placed above the BACKGROUND priority class.
|
||||
pref("gonk.notifySoftLowMemUnderKB", 43008);
|
||||
|
||||
// We wait this long before polling the memory-pressure fd after seeing one
|
||||
// memory pressure event. (When we're not under memory pressure, we sit
|
||||
|
|
|
@ -844,9 +844,6 @@ var CustomEventManager = {
|
|||
case 'webapps-uninstall-denied':
|
||||
WebappsHelper.handleEvent(detail);
|
||||
break;
|
||||
case 'select-choicechange':
|
||||
FormsHelper.handleEvent(detail);
|
||||
break;
|
||||
case 'system-message-listener-ready':
|
||||
Services.obs.notifyObservers(null, 'system-message-listener-ready', null);
|
||||
break;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<!--
|
||||
B2G repositories for all targets
|
||||
-->
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="78b2bc4cad3fcf83cbbbe4aeb77079cf956972cf"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="16ebbfb6ce62c14573982b0aa87537ef8f857047"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
|
||||
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<!--
|
||||
B2G repositories for all targets
|
||||
-->
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="78b2bc4cad3fcf83cbbbe4aeb77079cf956972cf"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="16ebbfb6ce62c14573982b0aa87537ef8f857047"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
|
||||
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<!--
|
||||
B2G repositories for all targets
|
||||
-->
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="78b2bc4cad3fcf83cbbbe4aeb77079cf956972cf"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="16ebbfb6ce62c14573982b0aa87537ef8f857047"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
|
||||
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<!--
|
||||
B2G repositories for all targets
|
||||
-->
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="78b2bc4cad3fcf83cbbbe4aeb77079cf956972cf"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="16ebbfb6ce62c14573982b0aa87537ef8f857047"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
|
||||
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<!--
|
||||
B2G repositories for all targets
|
||||
-->
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="78b2bc4cad3fcf83cbbbe4aeb77079cf956972cf"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="16ebbfb6ce62c14573982b0aa87537ef8f857047"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
|
||||
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<!--
|
||||
B2G repositories for all targets
|
||||
-->
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="78b2bc4cad3fcf83cbbbe4aeb77079cf956972cf"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="16ebbfb6ce62c14573982b0aa87537ef8f857047"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
|
||||
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<!--
|
||||
B2G repositories for all targets
|
||||
-->
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="78b2bc4cad3fcf83cbbbe4aeb77079cf956972cf"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="16ebbfb6ce62c14573982b0aa87537ef8f857047"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
|
||||
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<!--
|
||||
B2G repositories for all targets
|
||||
-->
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="78b2bc4cad3fcf83cbbbe4aeb77079cf956972cf"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="16ebbfb6ce62c14573982b0aa87537ef8f857047"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
|
||||
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"git": {
|
||||
"git_revision": "78b2bc4cad3fcf83cbbbe4aeb77079cf956972cf",
|
||||
"git_revision": "16ebbfb6ce62c14573982b0aa87537ef8f857047",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "0268b9905c692e4fdb7d324ca11ce418196a15fe",
|
||||
"revision": "8668ab0c480334a48e1935cce440e33dff23b33a",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<!--
|
||||
B2G repositories for all targets
|
||||
-->
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="78b2bc4cad3fcf83cbbbe4aeb77079cf956972cf"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="16ebbfb6ce62c14573982b0aa87537ef8f857047"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
|
||||
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<!--
|
||||
B2G repositories for all targets
|
||||
-->
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="78b2bc4cad3fcf83cbbbe4aeb77079cf956972cf"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="16ebbfb6ce62c14573982b0aa87537ef8f857047"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
|
||||
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<!--
|
||||
B2G repositories for all targets
|
||||
-->
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="78b2bc4cad3fcf83cbbbe4aeb77079cf956972cf"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="16ebbfb6ce62c14573982b0aa87537ef8f857047"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
|
||||
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
|
||||
|
|
|
@ -17,12 +17,12 @@ var FeedHandler = {
|
|||
* The feed list container (menupopup or subview) to be populated.
|
||||
* @param isSubview
|
||||
* Whether we're creating a subview (true) or menu (false/undefined)
|
||||
* @returns true if the menu/subview should be shown, false if there was only
|
||||
* @return true if the menu/subview should be shown, false if there was only
|
||||
* one feed and the feed should be shown inline in the browser
|
||||
* window (do not show the menupopup/subview).
|
||||
*/
|
||||
buildFeedList: function(container, isSubview) {
|
||||
var feeds = gBrowser.selectedBrowser.feeds;
|
||||
buildFeedList(container, isSubview) {
|
||||
let feeds = gBrowser.selectedBrowser.feeds;
|
||||
if (!isSubview && feeds == null) {
|
||||
// XXX hack -- menu opening depends on setting of an "open"
|
||||
// attribute, and the menu refuses to open if that attribute is
|
||||
|
@ -45,11 +45,11 @@ var FeedHandler = {
|
|||
return false;
|
||||
|
||||
// Build the menu showing the available feed choices for viewing.
|
||||
var itemNodeType = isSubview ? "toolbarbutton" : "menuitem";
|
||||
let itemNodeType = isSubview ? "toolbarbutton" : "menuitem";
|
||||
for (let feedInfo of feeds) {
|
||||
var item = document.createElement(itemNodeType);
|
||||
var baseTitle = feedInfo.title || feedInfo.href;
|
||||
var labelStr = gNavigatorBundle.getFormattedString("feedShowFeedNew", [baseTitle]);
|
||||
let item = document.createElement(itemNodeType);
|
||||
let baseTitle = feedInfo.title || feedInfo.href;
|
||||
let labelStr = gNavigatorBundle.getFormattedString("feedShowFeedNew", [baseTitle]);
|
||||
item.setAttribute("label", labelStr);
|
||||
item.setAttribute("feed", feedInfo.href);
|
||||
item.setAttribute("tooltiptext", feedInfo.href);
|
||||
|
@ -77,14 +77,14 @@ var FeedHandler = {
|
|||
* The event this method is handling. Used to decide where
|
||||
* to open the preview UI. (Optional, unless href is null)
|
||||
*/
|
||||
subscribeToFeed: function(href, event) {
|
||||
subscribeToFeed(href, event) {
|
||||
// Just load the feed in the content area to either subscribe or show the
|
||||
// preview UI
|
||||
if (!href)
|
||||
href = event.target.getAttribute("feed");
|
||||
urlSecurityCheck(href, gBrowser.contentPrincipal,
|
||||
Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
|
||||
var feedURI = makeURI(href, document.characterSet);
|
||||
let feedURI = makeURI(href, document.characterSet);
|
||||
// Use the feed scheme so X-Moz-Is-Feed will be set
|
||||
// The value doesn't matter
|
||||
if (/^https?$/.test(feedURI.scheme))
|
||||
|
@ -92,8 +92,8 @@ var FeedHandler = {
|
|||
this.loadFeed(href, event);
|
||||
},
|
||||
|
||||
loadFeed: function(href, event) {
|
||||
var feeds = gBrowser.selectedBrowser.feeds;
|
||||
loadFeed(href, event) {
|
||||
let feeds = gBrowser.selectedBrowser.feeds;
|
||||
try {
|
||||
openUILink(href, event, { ignoreAlt: true });
|
||||
}
|
||||
|
@ -118,14 +118,14 @@ var FeedHandler = {
|
|||
* Update the browser UI to show whether or not feeds are available when
|
||||
* a page is loaded or the user switches tabs to a page that has feeds.
|
||||
*/
|
||||
updateFeeds: function() {
|
||||
updateFeeds() {
|
||||
if (this._updateFeedTimeout)
|
||||
clearTimeout(this._updateFeedTimeout);
|
||||
|
||||
var feeds = gBrowser.selectedBrowser.feeds;
|
||||
var haveFeeds = feeds && feeds.length > 0;
|
||||
let feeds = gBrowser.selectedBrowser.feeds;
|
||||
let haveFeeds = feeds && feeds.length > 0;
|
||||
|
||||
var feedButton = document.getElementById("feed-button");
|
||||
let feedButton = document.getElementById("feed-button");
|
||||
if (feedButton) {
|
||||
if (haveFeeds) {
|
||||
feedButton.removeAttribute("disabled");
|
||||
|
@ -152,7 +152,7 @@ var FeedHandler = {
|
|||
}
|
||||
},
|
||||
|
||||
addFeed: function(link, browserForLink) {
|
||||
addFeed(link, browserForLink) {
|
||||
if (!browserForLink.feeds)
|
||||
browserForLink.feeds = [];
|
||||
|
||||
|
@ -169,15 +169,184 @@ var FeedHandler = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the human-readable display name of a file. This could be the
|
||||
* application name.
|
||||
* @param file
|
||||
* A nsIFile to look up the name of
|
||||
* @return The display name of the application represented by the file.
|
||||
*/
|
||||
_getFileDisplayName(file) {
|
||||
switch (AppConstants.platform) {
|
||||
case "win":
|
||||
if (file instanceof Ci.nsILocalFileWin) {
|
||||
try {
|
||||
return file.getVersionInfoField("FileDescription");
|
||||
} catch (e) {}
|
||||
}
|
||||
break;
|
||||
case "macosx":
|
||||
if (file instanceof Ci.nsILocalFileMac) {
|
||||
try {
|
||||
return file.bundleDisplayName;
|
||||
} catch (e) {}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return file.leafName;
|
||||
},
|
||||
|
||||
chooseClientApp(aTitle, aPrefName, aBrowser) {
|
||||
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||
|
||||
fp.init(window, aTitle, Ci.nsIFilePicker.modeOpen);
|
||||
fp.appendFilters(Ci.nsIFilePicker.filterApps);
|
||||
|
||||
fp.open((aResult) => {
|
||||
if (aResult == Ci.nsIFilePicker.returnOK) {
|
||||
let selectedApp = fp.file;
|
||||
if (selectedApp) {
|
||||
// XXXben - we need to compare this with the running instance
|
||||
// executable just don't know how to do that via script
|
||||
// XXXmano TBD: can probably add this to nsIShellService
|
||||
let appName = "";
|
||||
switch (AppConstants.platform) {
|
||||
case "win":
|
||||
appName = AppConstants.MOZ_APP_NAME + ".exe";
|
||||
break;
|
||||
case "macosx":
|
||||
appName = AppConstants.MOZ_MACBUNDLE_NAME;
|
||||
break;
|
||||
default:
|
||||
appName = AppConstants.MOZ_APP_NAME + "-bin";
|
||||
break;
|
||||
}
|
||||
|
||||
if (fp.file.leafName != appName) {
|
||||
Services.prefs.setComplexValue(aPrefName, Ci.nsILocalFile, selectedApp);
|
||||
aBrowser.messageManager.sendAsyncMessage("FeedWriter:SetApplicationLauncherMenuItem",
|
||||
{ name: this._getFileDisplayName(selectedApp),
|
||||
type: "SelectedAppMenuItem" });
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
executeClientApp(aSpec, aTitle, aSubtitle, aFeedHandler) {
|
||||
// aFeedHandler is either "default", indicating the system default reader, or a pref-name containing
|
||||
// an nsILocalFile pointing to the feed handler's executable.
|
||||
|
||||
let clientApp = null;
|
||||
if (aFeedHandler == "default") {
|
||||
clientApp = Cc["@mozilla.org/browser/shell-service;1"]
|
||||
.getService(Ci.nsIShellService)
|
||||
.defaultFeedReader;
|
||||
} else {
|
||||
clientApp = Services.prefs.getComplexValue(aFeedHandler, Ci.nsILocalFile);
|
||||
}
|
||||
|
||||
// For the benefit of applications that might know how to deal with more
|
||||
// URLs than just feeds, send feed: URLs in the following format:
|
||||
//
|
||||
// http urls: replace scheme with feed, e.g.
|
||||
// http://foo.com/index.rdf -> feed://foo.com/index.rdf
|
||||
// other urls: prepend feed: scheme, e.g.
|
||||
// https://foo.com/index.rdf -> feed:https://foo.com/index.rdf
|
||||
let feedURI = NetUtil.newURI(aSpec);
|
||||
if (feedURI.schemeIs("http")) {
|
||||
feedURI.scheme = "feed";
|
||||
aSpec = feedURI.spec;
|
||||
} else {
|
||||
aSpec = "feed:" + aSpec;
|
||||
}
|
||||
|
||||
// Retrieving the shell service might fail on some systems, most
|
||||
// notably systems where GNOME is not installed.
|
||||
try {
|
||||
let ss = Cc["@mozilla.org/browser/shell-service;1"]
|
||||
.getService(Ci.nsIShellService);
|
||||
ss.openApplicationWithURI(clientApp, aSpec);
|
||||
} catch(e) {
|
||||
// If we couldn't use the shell service, fallback to using a
|
||||
// nsIProcess instance
|
||||
let p = Cc["@mozilla.org/process/util;1"]
|
||||
.createInstance(Ci.nsIProcess);
|
||||
p.init(clientApp);
|
||||
p.run(false, [aSpec], 1);
|
||||
}
|
||||
},
|
||||
|
||||
init() {
|
||||
window.messageManager.addMessageListener("FeedWriter:ChooseClientApp", this);
|
||||
window.messageManager.addMessageListener("FeedWriter:RequestClientAppName", this);
|
||||
window.messageManager.addMessageListener("FeedWriter:SetFeedCharPref", this);
|
||||
window.messageManager.addMessageListener("FeedWriter:SetFeedComplexString", this);
|
||||
window.messageManager.addMessageListener("FeedWriter:ShownFirstRun", this);
|
||||
|
||||
Services.ppmm.addMessageListener("FeedConverter:ExecuteClientApp", this);
|
||||
},
|
||||
|
||||
uninit() {
|
||||
Services.ppmm.removeMessageListener("FeedConverter:ExecuteClientApp", this);
|
||||
},
|
||||
|
||||
receiveMessage(msg) {
|
||||
switch (msg.name) {
|
||||
case "FeedWriter:ChooseClientApp":
|
||||
this.chooseClientApp(msg.data.title, msg.data.prefName, msg.target);
|
||||
break;
|
||||
case "FeedWriter:RequestClientAppName":
|
||||
let selectedClientApp;
|
||||
try {
|
||||
selectedClientApp = Services.prefs.getComplexValue(msg.data.feedTypePref, Ci.nsILocalFile);
|
||||
} catch (ex) {
|
||||
// Just do nothing, then we won't bother populating
|
||||
}
|
||||
|
||||
let defaultClientApp = null;
|
||||
try {
|
||||
// This can sometimes not exist
|
||||
defaultClientApp = Cc["@mozilla.org/browser/shell-service;1"]
|
||||
.getService(Ci.nsIShellService)
|
||||
.defaultFeedReader;
|
||||
} catch(ex) {
|
||||
// Just do nothing, then we don't bother populating
|
||||
}
|
||||
|
||||
if (selectedClientApp && selectedClientApp.exists()) {
|
||||
if (defaultClientApp && selectedClientApp.path != defaultClientApp.path) {
|
||||
// Only set the default menu item if it differs from the selected one
|
||||
msg.target.messageManager
|
||||
.sendAsyncMessage("FeedWriter:SetApplicationLauncherMenuItem",
|
||||
{ name: this._getFileDisplayName(defaultClientApp),
|
||||
type: "DefaultAppMenuItem" });
|
||||
}
|
||||
msg.target.messageManager
|
||||
.sendAsyncMessage("FeedWriter:SetApplicationLauncherMenuItem",
|
||||
{ name: this._getFileDisplayName(selectedClientApp),
|
||||
type: "SelectedAppMenuItem" });
|
||||
}
|
||||
break;
|
||||
case "FeedWriter:ShownFirstRun":
|
||||
Services.prefs.setBoolPref("browser.feeds.showFirstRunUI", false);
|
||||
break;
|
||||
case "FeedWriter:SetFeedCharPref":
|
||||
Services.prefs.setCharPref(msg.data.pref, msg.data.value);
|
||||
break;
|
||||
case "FeedWriter:SetFeedComplexString": {
|
||||
let supportsString = Cc["@mozilla.org/supports-string;1"].
|
||||
createInstance(Ci.nsISupportsString);
|
||||
supportsString.data = msg.data.value;
|
||||
Services.prefs.setComplexValue(msg.data.pref, Ci.nsISupportsString, supportsString);
|
||||
break;
|
||||
}
|
||||
case "FeedConverter:ExecuteClientApp":
|
||||
this.executeClientApp(msg.data.spec, msg.data.title,
|
||||
msg.data.subtitle, msg.data.feedHandler);
|
||||
break;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1434,6 +1434,8 @@ var gBrowserInit = {
|
|||
|
||||
BrowserOnClick.uninit();
|
||||
|
||||
FeedHandler.uninit();
|
||||
|
||||
DevEdition.uninit();
|
||||
|
||||
TrackingProtection.uninit();
|
||||
|
|
|
@ -92,7 +92,7 @@ function getPrefReaderForType(t) {
|
|||
}
|
||||
|
||||
function safeGetCharPref(pref, defaultValue) {
|
||||
var prefs =
|
||||
var prefs =
|
||||
Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
try {
|
||||
|
@ -112,7 +112,7 @@ FeedConverter.prototype = {
|
|||
* This is the downloaded text data for the feed.
|
||||
*/
|
||||
_data: null,
|
||||
|
||||
|
||||
/**
|
||||
* This is the object listening to the conversion, which is ultimately the
|
||||
* docshell for the load.
|
||||
|
@ -127,81 +127,81 @@ FeedConverter.prototype = {
|
|||
/**
|
||||
* See nsIStreamConverter.idl
|
||||
*/
|
||||
convert: function FC_convert(sourceStream, sourceType, destinationType,
|
||||
context) {
|
||||
convert(sourceStream, sourceType, destinationType,
|
||||
context) {
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIStreamConverter.idl
|
||||
*/
|
||||
asyncConvertData: function FC_asyncConvertData(sourceType, destinationType,
|
||||
listener, context) {
|
||||
asyncConvertData(sourceType, destinationType,
|
||||
listener, context) {
|
||||
this._listener = listener;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Whether or not the preview page is being forced.
|
||||
*/
|
||||
_forcePreviewPage: false,
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Release our references to various things once we're done using them.
|
||||
*/
|
||||
_releaseHandles: function FC__releaseHandles() {
|
||||
_releaseHandles() {
|
||||
this._listener = null;
|
||||
this._request = null;
|
||||
this._processor = null;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIFeedResultListener.idl
|
||||
*/
|
||||
handleResult: function FC_handleResult(result) {
|
||||
handleResult(result) {
|
||||
// Feeds come in various content types, which our feed sniffer coerces to
|
||||
// the maybe.feed type. However, feeds are used as a transport for
|
||||
// the maybe.feed type. However, feeds are used as a transport for
|
||||
// different data types, e.g. news/blogs (traditional feed), video/audio
|
||||
// (podcasts) and photos (photocasts, photostreams). Each of these is
|
||||
// (podcasts) and photos (photocasts, photostreams). Each of these is
|
||||
// different in that there's a different class of application suitable for
|
||||
// handling feeds of that type, but without a content-type differentiation
|
||||
// it is difficult for us to disambiguate.
|
||||
//
|
||||
//
|
||||
// The other problem is that if the user specifies an auto-action handler
|
||||
// for one feed application, the fact that the content type is shared means
|
||||
// that all other applications will auto-load with that handler too,
|
||||
// regardless of the content-type.
|
||||
// for one feed application, the fact that the content type is shared means
|
||||
// that all other applications will auto-load with that handler too,
|
||||
// regardless of the content-type.
|
||||
//
|
||||
// This means that content-type alone is not enough to determine whether
|
||||
// or not a feed should be auto-handled. This means that for feeds we need
|
||||
// to always use this stream converter, even when an auto-action is
|
||||
// specified, not the basic one provided by WebContentConverter. This
|
||||
// to always use this stream converter, even when an auto-action is
|
||||
// specified, not the basic one provided by WebContentConverter. This
|
||||
// converter needs to consume all of the data and parse it, and based on
|
||||
// that determination make a judgment about type.
|
||||
// that determination make a judgment about type.
|
||||
//
|
||||
// Since there are no content types for this content, and I'm not going to
|
||||
// invent any, the upshot is that while a user can set an auto-handler for
|
||||
// generic feed content, the system will prevent them from setting an auto-
|
||||
// handler for other stream types. In those cases, the user will always see
|
||||
// the preview page and have to select a handler. We can guess and show
|
||||
// the preview page and have to select a handler. We can guess and show
|
||||
// a client handler, but will not be able to show web handlers for those
|
||||
// types.
|
||||
//
|
||||
// If this is just a feed, not some kind of specialized application, then
|
||||
// auto-handlers can be set and we should obey them.
|
||||
try {
|
||||
var feedService =
|
||||
let feedService =
|
||||
Cc["@mozilla.org/browser/feeds/result-service;1"].
|
||||
getService(Ci.nsIFeedResultService);
|
||||
if (!this._forcePreviewPage && result.doc) {
|
||||
var feed = result.doc.QueryInterface(Ci.nsIFeed);
|
||||
var handler = safeGetCharPref(getPrefActionForType(feed.type), "ask");
|
||||
let feed = result.doc.QueryInterface(Ci.nsIFeed);
|
||||
let handler = safeGetCharPref(getPrefActionForType(feed.type), "ask");
|
||||
|
||||
if (handler != "ask") {
|
||||
if (handler == "reader")
|
||||
handler = safeGetCharPref(getPrefReaderForType(feed.type), "bookmarks");
|
||||
switch (handler) {
|
||||
case "web":
|
||||
var wccr =
|
||||
let wccr =
|
||||
Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
|
||||
getService(Ci.nsIWebContentConverterService);
|
||||
if ((feed.type == Ci.nsIFeed.TYPE_FEED &&
|
||||
|
@ -220,25 +220,27 @@ FeedConverter.prototype = {
|
|||
// fall through -- let feed service handle error
|
||||
case "bookmarks":
|
||||
case "client":
|
||||
case "default":
|
||||
try {
|
||||
var title = feed.title ? feed.title.plainText() : "";
|
||||
var desc = feed.subtitle ? feed.subtitle.plainText() : "";
|
||||
feedService.addToClientReader(result.uri.spec, title, desc, feed.type);
|
||||
let title = feed.title ? feed.title.plainText() : "";
|
||||
let desc = feed.subtitle ? feed.subtitle.plainText() : "";
|
||||
let feedReader = safeGetCharPref(getPrefActionForType(feedType), "bookmarks");
|
||||
feedService.addToClientReader(result.uri.spec, title, desc, feed.type, feedReader);
|
||||
return;
|
||||
} catch(ex) { /* fallback to preview mode */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ios =
|
||||
|
||||
let ios =
|
||||
Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
var chromeChannel;
|
||||
let chromeChannel;
|
||||
|
||||
// handling a redirect, hence forwarding the loadInfo from the old channel
|
||||
// to the newchannel.
|
||||
var oldChannel = this._request.QueryInterface(Ci.nsIChannel);
|
||||
var loadInfo = oldChannel.loadInfo;
|
||||
let oldChannel = this._request.QueryInterface(Ci.nsIChannel);
|
||||
let loadInfo = oldChannel.loadInfo;
|
||||
|
||||
// If there was no automatic handler, or this was a podcast,
|
||||
// photostream or some other kind of application, show the preview page
|
||||
|
@ -250,7 +252,7 @@ FeedConverter.prototype = {
|
|||
feedService.addFeedResult(result);
|
||||
|
||||
// Now load the actual XUL document.
|
||||
var aboutFeedsURI = ios.newURI("about:feeds", null, null);
|
||||
let aboutFeedsURI = ios.newURI("about:feeds", null, null);
|
||||
chromeChannel = ios.newChannelFromURIWithLoadInfo(aboutFeedsURI, loadInfo);
|
||||
chromeChannel.originalURI = result.uri;
|
||||
chromeChannel.owner =
|
||||
|
@ -266,27 +268,27 @@ FeedConverter.prototype = {
|
|||
this._releaseHandles();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIStreamListener.idl
|
||||
*/
|
||||
onDataAvailable: function FC_onDataAvailable(request, context, inputStream,
|
||||
sourceOffset, count) {
|
||||
onDataAvailable(request, context, inputStream,
|
||||
sourceOffset, count) {
|
||||
if (this._processor)
|
||||
this._processor.onDataAvailable(request, context, inputStream,
|
||||
sourceOffset, count);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIRequestObserver.idl
|
||||
*/
|
||||
onStartRequest: function FC_onStartRequest(request, context) {
|
||||
var channel = request.QueryInterface(Ci.nsIChannel);
|
||||
onStartRequest(request, context) {
|
||||
let channel = request.QueryInterface(Ci.nsIChannel);
|
||||
|
||||
// Check for a header that tells us there was no sniffing
|
||||
// The value doesn't matter.
|
||||
try {
|
||||
var httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
|
||||
let httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
|
||||
// Make sure to check requestSucceeded before the potentially-throwing
|
||||
// getResponseHeader.
|
||||
if (!httpChannel.requestSucceeded) {
|
||||
|
@ -294,17 +296,17 @@ FeedConverter.prototype = {
|
|||
request.cancel(Cr.NS_BINDING_ABORTED);
|
||||
return;
|
||||
}
|
||||
var noSniff = httpChannel.getResponseHeader("X-Moz-Is-Feed");
|
||||
let noSniff = httpChannel.getResponseHeader("X-Moz-Is-Feed");
|
||||
}
|
||||
catch (ex) {
|
||||
this._sniffed = true;
|
||||
}
|
||||
|
||||
this._request = request;
|
||||
|
||||
|
||||
// Save and reset the forced state bit early, in case there's some kind of
|
||||
// error.
|
||||
var feedService =
|
||||
let feedService =
|
||||
Cc["@mozilla.org/browser/feeds/result-service;1"].
|
||||
getService(Ci.nsIFeedResultService);
|
||||
this._forcePreviewPage = feedService.forcePreviewPage;
|
||||
|
@ -316,22 +318,22 @@ FeedConverter.prototype = {
|
|||
createInstance(Ci.nsIFeedProcessor);
|
||||
this._processor.listener = this;
|
||||
this._processor.parseAsync(null, channel.URI);
|
||||
|
||||
|
||||
this._processor.onStartRequest(request, context);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIRequestObserver.idl
|
||||
*/
|
||||
onStopRequest: function FC_onStopRequest(request, context, status) {
|
||||
onStopRequest(request, context, status) {
|
||||
if (this._processor)
|
||||
this._processor.onStopRequest(request, context, status);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsISupports.idl
|
||||
*/
|
||||
QueryInterface: function FC_QueryInterface(iid) {
|
||||
QueryInterface(iid) {
|
||||
if (iid.equals(Ci.nsIFeedResultListener) ||
|
||||
iid.equals(Ci.nsIStreamConverter) ||
|
||||
iid.equals(Ci.nsIStreamListener) ||
|
||||
|
@ -344,133 +346,105 @@ FeedConverter.prototype = {
|
|||
|
||||
/**
|
||||
* Keeps parsed FeedResults around for use elsewhere in the UI after the stream
|
||||
* converter completes.
|
||||
* converter completes.
|
||||
*/
|
||||
function FeedResultService() {
|
||||
}
|
||||
|
||||
FeedResultService.prototype = {
|
||||
classID: Components.ID("{2376201c-bbc6-472f-9b62-7548040a61c6}"),
|
||||
|
||||
|
||||
/**
|
||||
* A URI spec -> [nsIFeedResult] hash. We have to keep a list as the
|
||||
* value in case the same URI is requested concurrently.
|
||||
*/
|
||||
_results: { },
|
||||
|
||||
|
||||
/**
|
||||
* See nsIFeedResultService.idl
|
||||
*/
|
||||
forcePreviewPage: false,
|
||||
|
||||
|
||||
/**
|
||||
* See nsIFeedResultService.idl
|
||||
*/
|
||||
addToClientReader: function FRS_addToClientReader(spec, title, subtitle, feedType) {
|
||||
var prefs =
|
||||
Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
addToClientReader(spec, title, subtitle, feedType, feedReader) {
|
||||
if (!feedReader) {
|
||||
feedReader = "default";
|
||||
}
|
||||
|
||||
var handler = safeGetCharPref(getPrefActionForType(feedType), "bookmarks");
|
||||
let handler = safeGetCharPref(getPrefActionForType(feedType), "bookmarks");
|
||||
if (handler == "ask" || handler == "reader")
|
||||
handler = safeGetCharPref(getPrefReaderForType(feedType), "bookmarks");
|
||||
handler = feedReader;
|
||||
|
||||
switch (handler) {
|
||||
case "client":
|
||||
var clientApp = prefs.getComplexValue(getPrefAppForType(feedType), Ci.nsILocalFile);
|
||||
|
||||
// For the benefit of applications that might know how to deal with more
|
||||
// URLs than just feeds, send feed: URLs in the following format:
|
||||
//
|
||||
// http urls: replace scheme with feed, e.g.
|
||||
// http://foo.com/index.rdf -> feed://foo.com/index.rdf
|
||||
// other urls: prepend feed: scheme, e.g.
|
||||
// https://foo.com/index.rdf -> feed:https://foo.com/index.rdf
|
||||
var ios =
|
||||
Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
var feedURI = ios.newURI(spec, null, null);
|
||||
if (feedURI.schemeIs("http")) {
|
||||
feedURI.scheme = "feed";
|
||||
spec = feedURI.spec;
|
||||
}
|
||||
else
|
||||
spec = "feed:" + spec;
|
||||
|
||||
// Retrieving the shell service might fail on some systems, most
|
||||
// notably systems where GNOME is not installed.
|
||||
try {
|
||||
var ss =
|
||||
Cc["@mozilla.org/browser/shell-service;1"].
|
||||
getService(Ci.nsIShellService);
|
||||
ss.openApplicationWithURI(clientApp, spec);
|
||||
} catch(e) {
|
||||
// If we couldn't use the shell service, fallback to using a
|
||||
// nsIProcess instance
|
||||
var p =
|
||||
Cc["@mozilla.org/process/util;1"].
|
||||
createInstance(Ci.nsIProcess);
|
||||
p.init(clientApp);
|
||||
p.run(false, [spec], 1);
|
||||
}
|
||||
Services.cpmm.sendAsyncMessage("FeedConverter:ExecuteClientApp",
|
||||
{ spec,
|
||||
title,
|
||||
subtitle,
|
||||
feedHandler: getPrefAppForType(feedType) });
|
||||
break;
|
||||
case "default":
|
||||
// Default system feed reader
|
||||
Services.cpmm.sendAsyncMessage("FeedConverter:ExecuteClientApp",
|
||||
{ spec,
|
||||
title,
|
||||
subtitle,
|
||||
feedHandler: "default" });
|
||||
break;
|
||||
|
||||
default:
|
||||
// "web" should have been handled elsewhere
|
||||
LOG("unexpected handler: " + handler);
|
||||
// fall through
|
||||
case "bookmarks":
|
||||
var wm =
|
||||
Cc["@mozilla.org/appshell/window-mediator;1"].
|
||||
getService(Ci.nsIWindowMediator);
|
||||
var topWindow = wm.getMostRecentWindow("navigator:browser");
|
||||
topWindow.PlacesCommandHook.addLiveBookmark(spec, title, subtitle)
|
||||
.catch(Components.utils.reportError);
|
||||
Services.cpmm.sendAsyncMessage("FeedConverter:addLiveBookmark",
|
||||
{ spec, title, subtitle });
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIFeedResultService.idl
|
||||
*/
|
||||
addFeedResult: function FRS_addFeedResult(feedResult) {
|
||||
addFeedResult(feedResult) {
|
||||
NS_ASSERT(feedResult.uri != null, "null URI!");
|
||||
NS_ASSERT(feedResult.uri != null, "null feedResult!");
|
||||
var spec = feedResult.uri.spec;
|
||||
if(!this._results[spec])
|
||||
let spec = feedResult.uri.spec;
|
||||
if (!this._results[spec])
|
||||
this._results[spec] = [];
|
||||
this._results[spec].push(feedResult);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIFeedResultService.idl
|
||||
*/
|
||||
getFeedResult: function RFS_getFeedResult(uri) {
|
||||
getFeedResult(uri) {
|
||||
NS_ASSERT(uri != null, "null URI!");
|
||||
var resultList = this._results[uri.spec];
|
||||
for (var i in resultList) {
|
||||
if (resultList[i].uri == uri)
|
||||
return resultList[i];
|
||||
let resultList = this._results[uri.spec];
|
||||
for (let result of resultList) {
|
||||
if (result.uri == uri)
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIFeedResultService.idl
|
||||
*/
|
||||
removeFeedResult: function FRS_removeFeedResult(uri) {
|
||||
removeFeedResult(uri) {
|
||||
NS_ASSERT(uri != null, "null URI!");
|
||||
var resultList = this._results[uri.spec];
|
||||
let resultList = this._results[uri.spec];
|
||||
if (!resultList)
|
||||
return;
|
||||
var deletions = 0;
|
||||
for (var i = 0; i < resultList.length; ++i) {
|
||||
let deletions = 0;
|
||||
for (let i = 0; i < resultList.length; ++i) {
|
||||
if (resultList[i].uri == uri) {
|
||||
delete resultList[i];
|
||||
++deletions;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// send the holes to the end
|
||||
resultList.sort();
|
||||
// and trim the list
|
||||
|
@ -479,13 +453,13 @@ FeedResultService.prototype = {
|
|||
delete this._results[uri.spec];
|
||||
},
|
||||
|
||||
createInstance: function FRS_createInstance(outer, iid) {
|
||||
createInstance(outer, iid) {
|
||||
if (outer != null)
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
return this.QueryInterface(iid);
|
||||
},
|
||||
|
||||
QueryInterface: function FRS_QueryInterface(iid) {
|
||||
|
||||
QueryInterface(iid) {
|
||||
if (iid.equals(Ci.nsIFeedResultService) ||
|
||||
iid.equals(Ci.nsIFactory) ||
|
||||
iid.equals(Ci.nsISupports))
|
||||
|
@ -501,8 +475,8 @@ FeedResultService.prototype = {
|
|||
function GenericProtocolHandler() {
|
||||
}
|
||||
GenericProtocolHandler.prototype = {
|
||||
_init: function GPH_init(scheme) {
|
||||
var ios =
|
||||
_init(scheme) {
|
||||
let ios =
|
||||
Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
this._http = ios.getProtocolHandler("http");
|
||||
|
@ -512,46 +486,46 @@ GenericProtocolHandler.prototype = {
|
|||
get scheme() {
|
||||
return this._scheme;
|
||||
},
|
||||
|
||||
|
||||
get protocolFlags() {
|
||||
return this._http.protocolFlags;
|
||||
},
|
||||
|
||||
|
||||
get defaultPort() {
|
||||
return this._http.defaultPort;
|
||||
},
|
||||
|
||||
allowPort: function GPH_allowPort(port, scheme) {
|
||||
|
||||
allowPort(port, scheme) {
|
||||
return this._http.allowPort(port, scheme);
|
||||
},
|
||||
|
||||
newURI: function GPH_newURI(spec, originalCharset, baseURI) {
|
||||
|
||||
newURI(spec, originalCharset, baseURI) {
|
||||
// Feed URIs can be either nested URIs of the form feed:realURI (in which
|
||||
// case we create a nested URI for the realURI) or feed://example.com, in
|
||||
// which case we create a nested URI for the real protocol which is http.
|
||||
|
||||
var scheme = this._scheme + ":";
|
||||
let scheme = this._scheme + ":";
|
||||
if (spec.substr(0, scheme.length) != scheme)
|
||||
throw Cr.NS_ERROR_MALFORMED_URI;
|
||||
|
||||
var prefix = spec.substr(scheme.length, 2) == "//" ? "http:" : "";
|
||||
var inner = Cc["@mozilla.org/network/io-service;1"].
|
||||
let prefix = spec.substr(scheme.length, 2) == "//" ? "http:" : "";
|
||||
let inner = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService).newURI(spec.replace(scheme, prefix),
|
||||
originalCharset, baseURI);
|
||||
var netutil = Cc["@mozilla.org/network/util;1"].getService(Ci.nsINetUtil);
|
||||
let netutil = Cc["@mozilla.org/network/util;1"].getService(Ci.nsINetUtil);
|
||||
const URI_INHERITS_SECURITY_CONTEXT = Ci.nsIProtocolHandler
|
||||
.URI_INHERITS_SECURITY_CONTEXT;
|
||||
if (netutil.URIChainHasFlags(inner, URI_INHERITS_SECURITY_CONTEXT))
|
||||
throw Cr.NS_ERROR_MALFORMED_URI;
|
||||
|
||||
var uri = netutil.newSimpleNestedURI(inner);
|
||||
let uri = netutil.newSimpleNestedURI(inner);
|
||||
uri.spec = inner.spec.replace(prefix, scheme);
|
||||
return uri;
|
||||
},
|
||||
|
||||
newChannel2: function GPH_newChannel(aUri, aLoadInfo) {
|
||||
var inner = aUri.QueryInterface(Ci.nsINestedURI).innerURI;
|
||||
var channel = Cc["@mozilla.org/network/io-service;1"].
|
||||
|
||||
newChannel2(aUri, aLoadInfo) {
|
||||
let inner = aUri.QueryInterface(Ci.nsINestedURI).innerURI;
|
||||
let channel = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService).
|
||||
newChannelFromURIWithLoadInfo(inner, aLoadInfo);
|
||||
|
||||
|
@ -561,14 +535,13 @@ GenericProtocolHandler.prototype = {
|
|||
channel.originalURI = aUri;
|
||||
return channel;
|
||||
},
|
||||
|
||||
|
||||
QueryInterface: function GPH_QueryInterface(iid) {
|
||||
QueryInterface(iid) {
|
||||
if (iid.equals(Ci.nsIProtocolHandler) ||
|
||||
iid.equals(Ci.nsISupports))
|
||||
return this;
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function FeedProtocolHandler() {
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -40,19 +40,19 @@ const NS_ERROR_DOM_SYNTAX_ERR = NS_ERROR_MODULE_DOM + 12;
|
|||
function WebContentConverter() {
|
||||
}
|
||||
WebContentConverter.prototype = {
|
||||
convert: function WCC_convert() { },
|
||||
asyncConvertData: function WCC_asyncConvertData() { },
|
||||
onDataAvailable: function WCC_onDataAvailable() { },
|
||||
onStopRequest: function WCC_onStopRequest() { },
|
||||
|
||||
onStartRequest: function WCC_onStartRequest(request, context) {
|
||||
var wccr =
|
||||
convert() { },
|
||||
asyncConvertData() { },
|
||||
onDataAvailable() { },
|
||||
onStopRequest() { },
|
||||
|
||||
onStartRequest(request, context) {
|
||||
let wccr =
|
||||
Cc[WCCR_CONTRACTID].
|
||||
getService(Ci.nsIWebContentConverterService);
|
||||
wccr.loadPreferredHandler(request);
|
||||
},
|
||||
|
||||
QueryInterface: function WCC_QueryInterface(iid) {
|
||||
|
||||
QueryInterface(iid) {
|
||||
if (iid.equals(Ci.nsIStreamConverter) ||
|
||||
iid.equals(Ci.nsIStreamListener) ||
|
||||
iid.equals(Ci.nsISupports))
|
||||
|
@ -61,14 +61,14 @@ WebContentConverter.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
var WebContentConverterFactory = {
|
||||
createInstance: function WCCF_createInstance(outer, iid) {
|
||||
let WebContentConverterFactory = {
|
||||
createInstance(outer, iid) {
|
||||
if (outer != null)
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
return new WebContentConverter().QueryInterface(iid);
|
||||
},
|
||||
|
||||
QueryInterface: function WCC_QueryInterface(iid) {
|
||||
|
||||
QueryInterface(iid) {
|
||||
if (iid.equals(Ci.nsIFactory) ||
|
||||
iid.equals(Ci.nsISupports))
|
||||
return this;
|
||||
|
@ -88,11 +88,11 @@ ServiceInfo.prototype = {
|
|||
get name() {
|
||||
return this._name;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIHandlerApp
|
||||
*/
|
||||
equals: function SI_equals(aHandlerApp) {
|
||||
equals(aHandlerApp) {
|
||||
if (!aHandlerApp)
|
||||
throw Cr.NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -121,11 +121,11 @@ ServiceInfo.prototype = {
|
|||
/**
|
||||
* See nsIWebContentHandlerInfo
|
||||
*/
|
||||
getHandlerURI: function SI_getHandlerURI(uri) {
|
||||
getHandlerURI(uri) {
|
||||
return this._uri.replace(/%s/gi, encodeURIComponent(uri));
|
||||
},
|
||||
|
||||
QueryInterface: function SI_QueryInterface(iid) {
|
||||
|
||||
QueryInterface(iid) {
|
||||
if (iid.equals(Ci.nsIWebContentHandlerInfo) ||
|
||||
iid.equals(Ci.nsISupports))
|
||||
return this;
|
||||
|
@ -139,9 +139,10 @@ const Utils = {
|
|||
},
|
||||
|
||||
checkAndGetURI(aURIString, aContentWindow) {
|
||||
let uri;
|
||||
try {
|
||||
let baseURI = aContentWindow.document.baseURIObject;
|
||||
var uri = this.makeURI(aURIString, null, baseURI);
|
||||
uri = this.makeURI(aURIString, null, baseURI);
|
||||
} catch (ex) {
|
||||
throw NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
@ -155,7 +156,7 @@ const Utils = {
|
|||
|
||||
// We also reject handlers registered from a different host (see bug 402287)
|
||||
// The pref allows us to test the feature
|
||||
var pb = Services.prefs;
|
||||
let pb = Services.prefs;
|
||||
if ((!pb.prefHasUserValue(PREF_ALLOW_DIFFERENT_HOST) ||
|
||||
!pb.getBoolPref(PREF_ALLOW_DIFFERENT_HOST)) &&
|
||||
aContentWindow.location.hostname != uri.host)
|
||||
|
@ -172,7 +173,7 @@ const Utils = {
|
|||
checkProtocolHandlerAllowed(aProtocol, aURIString) {
|
||||
// First, check to make sure this isn't already handled internally (we don't
|
||||
// want to let them take over, say "chrome").
|
||||
var handler = Services.io.getProtocolHandler(aProtocol);
|
||||
let handler = Services.io.getProtocolHandler(aProtocol);
|
||||
if (!(handler instanceof Ci.nsIExternalProtocolHandler)) {
|
||||
// This is handled internally, so we don't want them to register
|
||||
// XXX this should be a "security exception" according to spec, but that
|
||||
|
@ -181,8 +182,8 @@ const Utils = {
|
|||
}
|
||||
|
||||
// check if it is in the black list
|
||||
var pb = Services.prefs;
|
||||
var allowed;
|
||||
let pb = Services.prefs;
|
||||
let allowed;
|
||||
try {
|
||||
allowed = pb.getBoolPref(PREF_HANDLER_EXTERNAL_PREFIX + "." + aProtocol);
|
||||
}
|
||||
|
@ -211,49 +212,47 @@ const Utils = {
|
|||
};
|
||||
|
||||
function WebContentConverterRegistrar() {
|
||||
this._contentTypes = { };
|
||||
this._autoHandleContentTypes = { };
|
||||
this._contentTypes = {};
|
||||
this._autoHandleContentTypes = {};
|
||||
}
|
||||
|
||||
WebContentConverterRegistrar.prototype = {
|
||||
get stringBundle() {
|
||||
var sb = Services.strings.createBundle(STRING_BUNDLE_URI);
|
||||
let sb = Services.strings.createBundle(STRING_BUNDLE_URI);
|
||||
delete WebContentConverterRegistrar.prototype.stringBundle;
|
||||
return WebContentConverterRegistrar.prototype.stringBundle = sb;
|
||||
},
|
||||
|
||||
_getFormattedString: function WCCR__getFormattedString(key, params) {
|
||||
_getFormattedString(key, params) {
|
||||
return this.stringBundle.formatStringFromName(key, params, params.length);
|
||||
},
|
||||
|
||||
_getString: function WCCR_getString(key) {
|
||||
|
||||
_getString(key) {
|
||||
return this.stringBundle.GetStringFromName(key);
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIWebContentConverterService
|
||||
*/
|
||||
getAutoHandler:
|
||||
function WCCR_getAutoHandler(contentType) {
|
||||
getAutoHandler(contentType) {
|
||||
contentType = Utils.resolveContentType(contentType);
|
||||
if (contentType in this._autoHandleContentTypes)
|
||||
return this._autoHandleContentTypes[contentType];
|
||||
return null;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIWebContentConverterService
|
||||
*/
|
||||
setAutoHandler:
|
||||
function WCCR_setAutoHandler(contentType, handler) {
|
||||
setAutoHandler(contentType, handler) {
|
||||
if (handler && !this._typeIsRegistered(contentType, handler.uri))
|
||||
throw Cr.NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
contentType = Utils.resolveContentType(contentType);
|
||||
this._setAutoHandler(contentType, handler);
|
||||
|
||||
var ps = Services.prefs;
|
||||
var autoBranch = ps.getBranch(PREF_CONTENTHANDLERS_AUTO);
|
||||
let ps = Services.prefs;
|
||||
let autoBranch = ps.getBranch(PREF_CONTENTHANDLERS_AUTO);
|
||||
if (handler)
|
||||
autoBranch.setCharPref(contentType, handler.uri);
|
||||
else if (autoBranch.prefHasUserValue(contentType))
|
||||
|
@ -261,65 +260,57 @@ WebContentConverterRegistrar.prototype = {
|
|||
|
||||
ps.savePrefFile(null);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Update the internal data structure (not persistent)
|
||||
*/
|
||||
_setAutoHandler:
|
||||
function WCCR__setAutoHandler(contentType, handler) {
|
||||
if (handler)
|
||||
_setAutoHandler(contentType, handler) {
|
||||
if (handler)
|
||||
this._autoHandleContentTypes[contentType] = handler;
|
||||
else if (contentType in this._autoHandleContentTypes)
|
||||
delete this._autoHandleContentTypes[contentType];
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIWebContentConverterService
|
||||
*/
|
||||
getWebContentHandlerByURI:
|
||||
function WCCR_getWebContentHandlerByURI(contentType, uri) {
|
||||
var handlers = this.getContentHandlers(contentType, { });
|
||||
for (var i = 0; i < handlers.length; ++i) {
|
||||
if (handlers[i].uri == uri)
|
||||
return handlers[i];
|
||||
}
|
||||
return null;
|
||||
getWebContentHandlerByURI(contentType, uri) {
|
||||
return this.getContentHandlers(contentType)
|
||||
.find(e => e.uri == uri) || null;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIWebContentConverterService
|
||||
*/
|
||||
loadPreferredHandler:
|
||||
function WCCR_loadPreferredHandler(request) {
|
||||
var channel = request.QueryInterface(Ci.nsIChannel);
|
||||
var contentType = Utils.resolveContentType(channel.contentType);
|
||||
var handler = this.getAutoHandler(contentType);
|
||||
loadPreferredHandler(request) {
|
||||
let channel = request.QueryInterface(Ci.nsIChannel);
|
||||
let contentType = Utils.resolveContentType(channel.contentType);
|
||||
let handler = this.getAutoHandler(contentType);
|
||||
if (handler) {
|
||||
request.cancel(Cr.NS_ERROR_FAILURE);
|
||||
|
||||
var webNavigation =
|
||||
|
||||
let webNavigation =
|
||||
channel.notificationCallbacks.getInterface(Ci.nsIWebNavigation);
|
||||
webNavigation.loadURI(handler.getHandlerURI(channel.URI.spec),
|
||||
Ci.nsIWebNavigation.LOAD_FLAGS_NONE,
|
||||
webNavigation.loadURI(handler.getHandlerURI(channel.URI.spec),
|
||||
Ci.nsIWebNavigation.LOAD_FLAGS_NONE,
|
||||
null, null, null);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIWebContentConverterService
|
||||
*/
|
||||
removeProtocolHandler:
|
||||
function WCCR_removeProtocolHandler(aProtocol, aURITemplate) {
|
||||
var eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
|
||||
removeProtocolHandler(aProtocol, aURITemplate) {
|
||||
let eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
|
||||
getService(Ci.nsIExternalProtocolService);
|
||||
var handlerInfo = eps.getProtocolHandlerInfo(aProtocol);
|
||||
var handlers = handlerInfo.possibleApplicationHandlers;
|
||||
let handlerInfo = eps.getProtocolHandlerInfo(aProtocol);
|
||||
let handlers = handlerInfo.possibleApplicationHandlers;
|
||||
for (let i = 0; i < handlers.length; i++) {
|
||||
try { // We only want to test web handlers
|
||||
let handler = handlers.queryElementAt(i, Ci.nsIWebHandlerApp);
|
||||
if (handler.uriTemplate == aURITemplate) {
|
||||
handlers.removeElementAt(i);
|
||||
var hs = Cc["@mozilla.org/uriloader/handler-service;1"].
|
||||
let hs = Cc["@mozilla.org/uriloader/handler-service;1"].
|
||||
getService(Ci.nsIHandlerService);
|
||||
hs.store(handlerInfo);
|
||||
return;
|
||||
|
@ -327,24 +318,23 @@ WebContentConverterRegistrar.prototype = {
|
|||
} catch (e) { /* it wasn't a web handler */ }
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIWebContentConverterService
|
||||
*/
|
||||
removeContentHandler:
|
||||
function WCCR_removeContentHandler(contentType, uri) {
|
||||
removeContentHandler(contentType, uri) {
|
||||
function notURI(serviceInfo) {
|
||||
return serviceInfo.uri != uri;
|
||||
}
|
||||
|
||||
|
||||
if (contentType in this._contentTypes) {
|
||||
this._contentTypes[contentType] =
|
||||
this._contentTypes[contentType] =
|
||||
this._contentTypes[contentType].filter(notURI);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* These are types for which there is a separate content converter aside
|
||||
* These are types for which there is a separate content converter aside
|
||||
* from our built in generic one. We should not automatically register
|
||||
* a factory for creating a converter for these types.
|
||||
*/
|
||||
|
@ -361,12 +351,11 @@ WebContentConverterRegistrar.prototype = {
|
|||
* The URI template that the handler uses to handle the protocol.
|
||||
* @return true if it is already registered, false otherwise.
|
||||
*/
|
||||
_protocolHandlerRegistered:
|
||||
function WCCR_protocolHandlerRegistered(aProtocol, aURITemplate) {
|
||||
var eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
|
||||
_protocolHandlerRegistered(aProtocol, aURITemplate) {
|
||||
let eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
|
||||
getService(Ci.nsIExternalProtocolService);
|
||||
var handlerInfo = eps.getProtocolHandlerInfo(aProtocol);
|
||||
var handlers = handlerInfo.possibleApplicationHandlers;
|
||||
let handlerInfo = eps.getProtocolHandlerInfo(aProtocol);
|
||||
let handlers = handlerInfo.possibleApplicationHandlers;
|
||||
for (let i = 0; i < handlers.length; i++) {
|
||||
try { // We only want to test web handlers
|
||||
let handler = handlers.queryElementAt(i, Ci.nsIWebHandlerApp);
|
||||
|
@ -380,11 +369,10 @@ WebContentConverterRegistrar.prototype = {
|
|||
/**
|
||||
* See nsIWebContentHandlerRegistrar
|
||||
*/
|
||||
registerProtocolHandler:
|
||||
function WCCR_registerProtocolHandler(aProtocol, aURIString, aTitle, aBrowserOrWindow) {
|
||||
registerProtocolHandler(aProtocol, aURIString, aTitle, aBrowserOrWindow) {
|
||||
LOG("registerProtocolHandler(" + aProtocol + "," + aURIString + "," + aTitle + ")");
|
||||
var haveWindow = (aBrowserOrWindow instanceof Ci.nsIDOMWindow);
|
||||
var uri;
|
||||
let haveWindow = (aBrowserOrWindow instanceof Ci.nsIDOMWindow);
|
||||
let uri;
|
||||
if (haveWindow) {
|
||||
uri = Utils.checkAndGetURI(aURIString, aBrowserOrWindow);
|
||||
} else {
|
||||
|
@ -397,7 +385,7 @@ WebContentConverterRegistrar.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
var browser;
|
||||
let browser;
|
||||
if (haveWindow) {
|
||||
let browserWindow =
|
||||
this._getBrowserWindowForContentWindow(aBrowserOrWindow);
|
||||
|
@ -418,30 +406,29 @@ WebContentConverterRegistrar.prototype = {
|
|||
Utils.checkProtocolHandlerAllowed(aProtocol, aURIString);
|
||||
|
||||
// Now Ask the user and provide the proper callback
|
||||
var message = this._getFormattedString("addProtocolHandler",
|
||||
let message = this._getFormattedString("addProtocolHandler",
|
||||
[aTitle, uri.host, aProtocol]);
|
||||
|
||||
var notificationIcon = uri.prePath + "/favicon.ico";
|
||||
var notificationValue = "Protocol Registration: " + aProtocol;
|
||||
var addButton = {
|
||||
let notificationIcon = uri.prePath + "/favicon.ico";
|
||||
let notificationValue = "Protocol Registration: " + aProtocol;
|
||||
let addButton = {
|
||||
label: this._getString("addProtocolHandlerAddButton"),
|
||||
accessKey: this._getString("addHandlerAddButtonAccesskey"),
|
||||
protocolInfo: { protocol: aProtocol, uri: uri.spec, name: aTitle },
|
||||
|
||||
callback:
|
||||
function WCCR_addProtocolHandlerButtonCallback(aNotification, aButtonInfo) {
|
||||
var protocol = aButtonInfo.protocolInfo.protocol;
|
||||
var uri = aButtonInfo.protocolInfo.uri;
|
||||
var name = aButtonInfo.protocolInfo.name;
|
||||
callback(aNotification, aButtonInfo) {
|
||||
let protocol = aButtonInfo.protocolInfo.protocol;
|
||||
let uri = aButtonInfo.protocolInfo.uri;
|
||||
let name = aButtonInfo.protocolInfo.name;
|
||||
|
||||
var handler = Cc["@mozilla.org/uriloader/web-handler-app;1"].
|
||||
let handler = Cc["@mozilla.org/uriloader/web-handler-app;1"].
|
||||
createInstance(Ci.nsIWebHandlerApp);
|
||||
handler.name = name;
|
||||
handler.uriTemplate = uri;
|
||||
|
||||
var eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
|
||||
let eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
|
||||
getService(Ci.nsIExternalProtocolService);
|
||||
var handlerInfo = eps.getProtocolHandlerInfo(protocol);
|
||||
let handlerInfo = eps.getProtocolHandlerInfo(protocol);
|
||||
handlerInfo.possibleApplicationHandlers.appendElement(handler, false);
|
||||
|
||||
// Since the user has agreed to add a new handler, chances are good
|
||||
|
@ -450,12 +437,12 @@ WebContentConverterRegistrar.prototype = {
|
|||
// use.
|
||||
handlerInfo.alwaysAskBeforeHandling = true;
|
||||
|
||||
var hs = Cc["@mozilla.org/uriloader/handler-service;1"].
|
||||
let hs = Cc["@mozilla.org/uriloader/handler-service;1"].
|
||||
getService(Ci.nsIHandlerService);
|
||||
hs.store(handlerInfo);
|
||||
}
|
||||
};
|
||||
var notificationBox = browser.getTabBrowser().getNotificationBox(browser);
|
||||
let notificationBox = browser.getTabBrowser().getNotificationBox(browser);
|
||||
notificationBox.appendNotification(message,
|
||||
notificationValue,
|
||||
notificationIcon,
|
||||
|
@ -468,26 +455,25 @@ WebContentConverterRegistrar.prototype = {
|
|||
* If a DOM window is provided, then the request came from content, so we
|
||||
* prompt the user to confirm the registration.
|
||||
*/
|
||||
registerContentHandler:
|
||||
function WCCR_registerContentHandler(aContentType, aURIString, aTitle, aWindowOrBrowser) {
|
||||
registerContentHandler(aContentType, aURIString, aTitle, aWindowOrBrowser) {
|
||||
LOG("registerContentHandler(" + aContentType + "," + aURIString + "," + aTitle + ")");
|
||||
|
||||
// We only support feed types at present.
|
||||
// XXX this should be a "security exception" according to spec, but that
|
||||
// isn't defined yet.
|
||||
var contentType = Utils.resolveContentType(aContentType);
|
||||
let contentType = Utils.resolveContentType(aContentType);
|
||||
if (contentType != TYPE_MAYBE_FEED)
|
||||
return;
|
||||
|
||||
if (aWindowOrBrowser) {
|
||||
var haveWindow = (aWindowOrBrowser instanceof Ci.nsIDOMWindow);
|
||||
var uri;
|
||||
var notificationBox;
|
||||
let haveWindow = (aWindowOrBrowser instanceof Ci.nsIDOMWindow);
|
||||
let uri;
|
||||
let notificationBox;
|
||||
if (haveWindow) {
|
||||
uri = Utils.checkAndGetURI(aURIString, aWindowOrBrowser);
|
||||
|
||||
var browserWindow = this._getBrowserWindowForContentWindow(aWindowOrBrowser);
|
||||
var browserElement = this._getBrowserForContentWindow(browserWindow, aWindowOrBrowser);
|
||||
let browserWindow = this._getBrowserWindowForContentWindow(aWindowOrBrowser);
|
||||
let browserElement = this._getBrowserForContentWindow(browserWindow, aWindowOrBrowser);
|
||||
notificationBox = browserElement.getTabBrowser().getNotificationBox(browserElement);
|
||||
} else {
|
||||
// uri was vetted in the content process.
|
||||
|
@ -498,15 +484,15 @@ WebContentConverterRegistrar.prototype = {
|
|||
|
||||
this._appendFeedReaderNotification(uri, aTitle, notificationBox);
|
||||
}
|
||||
else
|
||||
else {
|
||||
this._registerContentHandler(contentType, aURIString, aTitle);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the browser chrome window in which the content window is in
|
||||
*/
|
||||
_getBrowserWindowForContentWindow:
|
||||
function WCCR__getBrowserWindowForContentWindow(aContentWindow) {
|
||||
_getBrowserWindowForContentWindow(aContentWindow) {
|
||||
return aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||
|
@ -526,15 +512,11 @@ WebContentConverterRegistrar.prototype = {
|
|||
* The content window. It's possible to pass a child content window
|
||||
* (i.e. the content window of a frame/iframe).
|
||||
*/
|
||||
_getBrowserForContentWindow:
|
||||
function WCCR__getBrowserForContentWindow(aBrowserWindow, aContentWindow) {
|
||||
_getBrowserForContentWindow(aBrowserWindow, aContentWindow) {
|
||||
// This depends on pseudo APIs of browser.js and tabbrowser.xml
|
||||
aContentWindow = aContentWindow.top;
|
||||
var browsers = aBrowserWindow.gBrowser.browsers;
|
||||
for (var i = 0; i < browsers.length; ++i) {
|
||||
if (browsers[i].contentWindow == aContentWindow)
|
||||
return browsers[i];
|
||||
}
|
||||
return aBrowserWindow.gBrowser.browsers.find((browser) =>
|
||||
browser.contentWindow == aContentWindow);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -558,35 +540,34 @@ WebContentConverterRegistrar.prototype = {
|
|||
* The notification box to which a notification might be appended
|
||||
* @return true if a notification has been appended, false otherwise.
|
||||
*/
|
||||
_appendFeedReaderNotification:
|
||||
function WCCR__appendFeedReaderNotification(aURI, aName, aNotificationBox) {
|
||||
var uriSpec = aURI.spec;
|
||||
var notificationValue = "feed reader notification: " + uriSpec;
|
||||
var notificationIcon = aURI.prePath + "/favicon.ico";
|
||||
_appendFeedReaderNotification(aURI, aName, aNotificationBox) {
|
||||
let uriSpec = aURI.spec;
|
||||
let notificationValue = "feed reader notification: " + uriSpec;
|
||||
let notificationIcon = aURI.prePath + "/favicon.ico";
|
||||
|
||||
// Don't append a new notification if the notificationbox
|
||||
// has a notification for the given feed reader already
|
||||
if (aNotificationBox.getNotificationWithValue(notificationValue))
|
||||
return false;
|
||||
|
||||
var buttons, message;
|
||||
let buttons;
|
||||
let message;
|
||||
if (this.getWebContentHandlerByURI(TYPE_MAYBE_FEED, uriSpec))
|
||||
message = this._getFormattedString("handlerRegistered", [aName]);
|
||||
else {
|
||||
message = this._getFormattedString("addHandler", [aName, aURI.host]);
|
||||
var self = this;
|
||||
var addButton = {
|
||||
let self = this;
|
||||
let addButton = {
|
||||
_outer: self,
|
||||
label: self._getString("addHandlerAddButton"),
|
||||
accessKey: self._getString("addHandlerAddButtonAccesskey"),
|
||||
feedReaderInfo: { uri: uriSpec, name: aName },
|
||||
|
||||
/* static */
|
||||
callback:
|
||||
function WCCR__addFeedReaderButtonCallback(aNotification, aButtonInfo) {
|
||||
var uri = aButtonInfo.feedReaderInfo.uri;
|
||||
var name = aButtonInfo.feedReaderInfo.name;
|
||||
var outer = aButtonInfo._outer;
|
||||
callback(aNotification, aButtonInfo) {
|
||||
let uri = aButtonInfo.feedReaderInfo.uri;
|
||||
let name = aButtonInfo.feedReaderInfo.name;
|
||||
let outer = aButtonInfo._outer;
|
||||
|
||||
// The reader could have been added from another window mean while
|
||||
if (!outer.getWebContentHandlerByURI(TYPE_MAYBE_FEED, uri))
|
||||
|
@ -610,7 +591,7 @@ WebContentConverterRegistrar.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Save Web Content Handler metadata to persistent preferences.
|
||||
* Save Web Content Handler metadata to persistent preferences.
|
||||
* @param contentType
|
||||
* The content Type being handled
|
||||
* @param uri
|
||||
|
@ -619,18 +600,17 @@ WebContentConverterRegistrar.prototype = {
|
|||
* The human readable name of the web service
|
||||
*
|
||||
* This data is stored under:
|
||||
*
|
||||
*
|
||||
* browser.contentHandlers.type0 = content/type
|
||||
* browser.contentHandlers.uri0 = http://www.foo.com/q=%s
|
||||
* browser.contentHandlers.title0 = Foo 2.0alphr
|
||||
*/
|
||||
_saveContentHandlerToPrefs:
|
||||
function WCCR__saveContentHandlerToPrefs(contentType, uri, title) {
|
||||
var ps = Services.prefs;
|
||||
var i = 0;
|
||||
var typeBranch = null;
|
||||
_saveContentHandlerToPrefs(contentType, uri, title) {
|
||||
let ps = Services.prefs;
|
||||
let i = 0;
|
||||
let typeBranch = null;
|
||||
while (true) {
|
||||
typeBranch =
|
||||
typeBranch =
|
||||
ps.getBranch(PREF_CONTENTHANDLERS_BRANCH + i + ".");
|
||||
try {
|
||||
typeBranch.getCharPref("type");
|
||||
|
@ -643,54 +623,49 @@ WebContentConverterRegistrar.prototype = {
|
|||
}
|
||||
if (typeBranch) {
|
||||
typeBranch.setCharPref("type", contentType);
|
||||
var pls =
|
||||
let pls =
|
||||
Cc["@mozilla.org/pref-localizedstring;1"].
|
||||
createInstance(Ci.nsIPrefLocalizedString);
|
||||
pls.data = uri;
|
||||
typeBranch.setComplexValue("uri", Ci.nsIPrefLocalizedString, pls);
|
||||
pls.data = title;
|
||||
typeBranch.setComplexValue("title", Ci.nsIPrefLocalizedString, pls);
|
||||
|
||||
|
||||
ps.savePrefFile(null);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Determines if there is a type with a particular uri registered for the
|
||||
* Determines if there is a type with a particular uri registered for the
|
||||
* specified content type already.
|
||||
* @param contentType
|
||||
* The content type that the uri handles
|
||||
* @param uri
|
||||
* The uri of the
|
||||
* The uri of the content type
|
||||
*/
|
||||
_typeIsRegistered: function WCCR__typeIsRegistered(contentType, uri) {
|
||||
_typeIsRegistered(contentType, uri) {
|
||||
if (!(contentType in this._contentTypes))
|
||||
return false;
|
||||
|
||||
var services = this._contentTypes[contentType];
|
||||
for (var i = 0; i < services.length; ++i) {
|
||||
// This uri has already been registered
|
||||
if (services[i].uri == uri)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
return this._contentTypes[contentType]
|
||||
.some(t => t.uri == uri);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Gets a stream converter contract id for the specified content type.
|
||||
* @param contentType
|
||||
* The source content type for the conversion.
|
||||
* @returns A contract id to construct a converter to convert between the
|
||||
* @returns A contract id to construct a converter to convert between the
|
||||
* contentType and *\/*.
|
||||
*/
|
||||
_getConverterContractID: function WCCR__getConverterContractID(contentType) {
|
||||
_getConverterContractID(contentType) {
|
||||
const template = "@mozilla.org/streamconv;1?from=%s&to=*/*";
|
||||
return template.replace(/%s/, contentType);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Register a web service handler for a content type.
|
||||
*
|
||||
*
|
||||
* @param contentType
|
||||
* the content type being handled
|
||||
* @param uri
|
||||
|
@ -698,18 +673,17 @@ WebContentConverterRegistrar.prototype = {
|
|||
* @param title
|
||||
* the human readable name of the web service
|
||||
*/
|
||||
_registerContentHandler:
|
||||
function WCCR__registerContentHandler(contentType, uri, title) {
|
||||
_registerContentHandler(contentType, uri, title) {
|
||||
this._updateContentTypeHandlerMap(contentType, uri, title);
|
||||
this._saveContentHandlerToPrefs(contentType, uri, title);
|
||||
|
||||
if (contentType == TYPE_MAYBE_FEED) {
|
||||
// Make the new handler the last-selected reader in the preview page
|
||||
// and make sure the preview page is shown the next time a feed is visited
|
||||
var pb = Services.prefs.getBranch(null);
|
||||
let pb = Services.prefs.getBranch(null);
|
||||
pb.setCharPref(PREF_SELECTED_READER, "web");
|
||||
|
||||
var supportsString =
|
||||
|
||||
let supportsString =
|
||||
Cc["@mozilla.org/supports-string;1"].
|
||||
createInstance(Ci.nsISupportsString);
|
||||
supportsString.data = uri;
|
||||
|
@ -730,136 +704,133 @@ WebContentConverterRegistrar.prototype = {
|
|||
* @param title
|
||||
* The human readable name of the web service
|
||||
*/
|
||||
_updateContentTypeHandlerMap:
|
||||
function WCCR__updateContentTypeHandlerMap(contentType, uri, title) {
|
||||
_updateContentTypeHandlerMap(contentType, uri, title) {
|
||||
if (!(contentType in this._contentTypes))
|
||||
this._contentTypes[contentType] = [];
|
||||
|
||||
// Avoid adding duplicates
|
||||
if (this._typeIsRegistered(contentType, uri))
|
||||
if (this._typeIsRegistered(contentType, uri))
|
||||
return;
|
||||
|
||||
|
||||
this._contentTypes[contentType].push(new ServiceInfo(contentType, uri, title));
|
||||
|
||||
|
||||
if (!(contentType in this._blockedTypes)) {
|
||||
var converterContractID = this._getConverterContractID(contentType);
|
||||
var cr = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
cr.registerFactory(WCC_CLASSID, WCC_CLASSNAME, converterContractID,
|
||||
let converterContractID = this._getConverterContractID(contentType);
|
||||
let cr = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
cr.registerFactory(WCC_CLASSID, WCC_CLASSNAME, converterContractID,
|
||||
WebContentConverterFactory);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIWebContentConverterService
|
||||
*/
|
||||
getContentHandlers:
|
||||
function WCCR_getContentHandlers(contentType, countRef) {
|
||||
countRef.value = 0;
|
||||
getContentHandlers(contentType, countRef) {
|
||||
if (countRef) {
|
||||
countRef.value = 0;
|
||||
}
|
||||
if (!(contentType in this._contentTypes))
|
||||
return [];
|
||||
|
||||
var handlers = this._contentTypes[contentType];
|
||||
countRef.value = handlers.length;
|
||||
|
||||
let handlers = this._contentTypes[contentType];
|
||||
if (countRef) {
|
||||
countRef.value = handlers.length;
|
||||
}
|
||||
return handlers;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIWebContentConverterService
|
||||
*/
|
||||
resetHandlersForType:
|
||||
function WCCR_resetHandlersForType(contentType) {
|
||||
resetHandlersForType(contentType) {
|
||||
// currently unused within the tree, so only useful for extensions; previous
|
||||
// impl. was buggy (and even infinite-looped!), so I argue that this is a
|
||||
// definite improvement
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Registers a handler from the settings on a preferences branch.
|
||||
*
|
||||
* Since we support up to six predefined readers, we need to handle gaps
|
||||
* better, since the first branch with user-added values will be .6
|
||||
*
|
||||
* How we deal with that is to check to see if there's no prefs in the
|
||||
* branch and stop cycling once that's true. This doesn't fix the case
|
||||
* where a user manually removes a reader, but that's not supported yet!
|
||||
*
|
||||
* @param branch
|
||||
* an nsIPrefBranch containing "type", "uri", and "title" preferences
|
||||
* corresponding to the content handler to be registered
|
||||
*/
|
||||
_registerContentHandlerWithBranch: function(branch) {
|
||||
/**
|
||||
* Since we support up to six predefined readers, we need to handle gaps
|
||||
* better, since the first branch with user-added values will be .6
|
||||
*
|
||||
* How we deal with that is to check to see if there's no prefs in the
|
||||
* branch and stop cycling once that's true. This doesn't fix the case
|
||||
* where a user manually removes a reader, but that's not supported yet!
|
||||
*/
|
||||
var vals = branch.getChildList("");
|
||||
_registerContentHandlerHavingBranch(branch) {
|
||||
let vals = branch.getChildList("");
|
||||
if (vals.length == 0)
|
||||
return;
|
||||
|
||||
try {
|
||||
var type = branch.getCharPref("type");
|
||||
var uri = branch.getComplexValue("uri", Ci.nsIPrefLocalizedString).data;
|
||||
var title = branch.getComplexValue("title",
|
||||
Ci.nsIPrefLocalizedString).data;
|
||||
this._updateContentTypeHandlerMap(type, uri, title);
|
||||
}
|
||||
catch(ex) {
|
||||
// do nothing, the next branch might have values
|
||||
}
|
||||
let type = branch.getCharPref("type");
|
||||
let uri = branch.getComplexValue("uri", Ci.nsIPrefLocalizedString).data;
|
||||
let title = branch.getComplexValue("title",
|
||||
Ci.nsIPrefLocalizedString).data;
|
||||
this._updateContentTypeHandlerMap(type, uri, title);
|
||||
},
|
||||
|
||||
/**
|
||||
* Load the auto handler, content handler and protocol tables from
|
||||
* Load the auto handler, content handler and protocol tables from
|
||||
* preferences.
|
||||
*/
|
||||
_init: function WCCR__init() {
|
||||
var ps = Services.prefs;
|
||||
_init() {
|
||||
let ps = Services.prefs;
|
||||
|
||||
var kids = ps.getBranch(PREF_CONTENTHANDLERS_BRANCH)
|
||||
.getChildList("");
|
||||
let children = ps.getBranch(PREF_CONTENTHANDLERS_BRANCH)
|
||||
.getChildList("");
|
||||
|
||||
// first get the numbers of the providers by getting all ###.uri prefs
|
||||
var nums = [];
|
||||
for (var i = 0; i < kids.length; i++) {
|
||||
var match = /^(\d+)\.uri$/.exec(kids[i]);
|
||||
if (!match)
|
||||
continue;
|
||||
else
|
||||
nums.push(match[1]);
|
||||
}
|
||||
let nums = children.map((child) => {
|
||||
let match = /^(\d+)\.uri$/.exec(child);
|
||||
return match ? match[1] : "";
|
||||
}).filter(child => !!child)
|
||||
.sort();
|
||||
|
||||
// sort them, to get them back in order
|
||||
nums.sort(function(a, b) {return a - b;});
|
||||
|
||||
// now register them
|
||||
for (var i = 0; i < nums.length; i++) {
|
||||
var branch = ps.getBranch(PREF_CONTENTHANDLERS_BRANCH + nums[i] + ".");
|
||||
this._registerContentHandlerWithBranch(branch);
|
||||
}
|
||||
|
||||
// We need to do this _after_ registering all of the available handlers,
|
||||
// so that getWebContentHandlerByURI can return successfully.
|
||||
try {
|
||||
var autoBranch = ps.getBranch(PREF_CONTENTHANDLERS_AUTO);
|
||||
var childPrefs = autoBranch.getChildList("");
|
||||
for (var i = 0; i < childPrefs.length; ++i) {
|
||||
var type = childPrefs[i];
|
||||
var uri = autoBranch.getCharPref(type);
|
||||
if (uri) {
|
||||
var handler = this.getWebContentHandlerByURI(type, uri);
|
||||
this._setAutoHandler(type, handler);
|
||||
}
|
||||
for (num of nums) {
|
||||
let branch = ps.getBranch(PREF_CONTENTHANDLERS_BRANCH + num + ".");
|
||||
try {
|
||||
this._registerContentHandlerHavingBranch(branch);
|
||||
} catch (ex) {
|
||||
// do nothing, the next branch might have values
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
|
||||
// We need to do this _after_ registering all of the available handlers,
|
||||
// so that getWebContentHandlerByURI can return successfully.
|
||||
let autoBranch;
|
||||
try {
|
||||
autoBranch = ps.getBranch(PREF_CONTENTHANDLERS_AUTO);
|
||||
} catch (e) {
|
||||
// No auto branch yet, that's fine
|
||||
//LOG("WCCR.init: There is no auto branch, benign");
|
||||
}
|
||||
|
||||
if (autoBranch) {
|
||||
for (let type of autoBranch.getChildList("")) {
|
||||
let uri = autoBranch.getCharPref(type);
|
||||
if (uri) {
|
||||
let handler = this.getWebContentHandlerByURI(type, uri);
|
||||
if (handler) {
|
||||
this._setAutoHandler(type, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIObserver
|
||||
*/
|
||||
observe: function WCCR_observe(subject, topic, data) {
|
||||
var os = Services.obs;
|
||||
observe(subject, topic, data) {
|
||||
let os = Services.obs;
|
||||
switch (topic) {
|
||||
case "app-startup":
|
||||
os.addObserver(this, "browser-ui-startup-complete", false);
|
||||
|
@ -870,11 +841,11 @@ WebContentConverterRegistrar.prototype = {
|
|||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* See nsIFactory
|
||||
*/
|
||||
createInstance: function WCCR_createInstance(outer, iid) {
|
||||
createInstance(outer, iid) {
|
||||
if (outer != null)
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
return this.QueryInterface(iid);
|
||||
|
@ -886,7 +857,7 @@ WebContentConverterRegistrar.prototype = {
|
|||
* See nsISupports
|
||||
*/
|
||||
QueryInterface: XPCOMUtils.generateQI(
|
||||
[Ci.nsIWebContentConverterService,
|
||||
[Ci.nsIWebContentConverterService,
|
||||
Ci.nsIWebContentHandlerRegistrar,
|
||||
Ci.nsIObserver,
|
||||
Ci.nsIFactory]),
|
||||
|
@ -898,9 +869,137 @@ WebContentConverterRegistrar.prototype = {
|
|||
};
|
||||
|
||||
function WebContentConverterRegistrarContent() {
|
||||
this._contentTypes = {};
|
||||
}
|
||||
|
||||
WebContentConverterRegistrarContent.prototype = {
|
||||
|
||||
/**
|
||||
* Load the auto handler, content handler and protocol tables from
|
||||
* preferences.
|
||||
*/
|
||||
_init() {
|
||||
let ps = Services.prefs;
|
||||
|
||||
let children = ps.getBranch(PREF_CONTENTHANDLERS_BRANCH)
|
||||
.getChildList("");
|
||||
|
||||
// first get the numbers of the providers by getting all ###.uri prefs
|
||||
let nums = children.map((child) => {
|
||||
let match = /^(\d+)\.uri$/.exec(child);
|
||||
return match ? match[1] : "";
|
||||
}).filter(child => !!child)
|
||||
.sort();
|
||||
|
||||
// now register them
|
||||
for (num of nums) {
|
||||
let branch = ps.getBranch(PREF_CONTENTHANDLERS_BRANCH + num + ".");
|
||||
try {
|
||||
this._registerContentHandlerHavingBranch(branch);
|
||||
} catch(ex) {
|
||||
// do nothing, the next branch might have values
|
||||
}
|
||||
}
|
||||
|
||||
// We need to do this _after_ registering all of the available handlers,
|
||||
// so that getWebContentHandlerByURI can return successfully.
|
||||
let autoBranch;
|
||||
try {
|
||||
autoBranch = ps.getBranch(PREF_CONTENTHANDLERS_AUTO);
|
||||
} catch (e) {
|
||||
// No auto branch yet, that's fine
|
||||
//LOG("WCCR.init: There is no auto branch, benign");
|
||||
}
|
||||
|
||||
if (autoBranch) {
|
||||
for (let type of autoBranch.getChildList("")) {
|
||||
let uri = autoBranch.getCharPref(type);
|
||||
if (uri) {
|
||||
let handler = this.getWebContentHandlerByURI(type, uri);
|
||||
if (handler) {
|
||||
this._setAutoHandler(type, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_typeIsRegistered(contentType, uri) {
|
||||
return this._contentTypes[contentType]
|
||||
.some(e => e.uri == uri);
|
||||
},
|
||||
|
||||
/**
|
||||
* Since we support up to six predefined readers, we need to handle gaps
|
||||
* better, since the first branch with user-added values will be .6
|
||||
*
|
||||
* How we deal with that is to check to see if there's no prefs in the
|
||||
* branch and stop cycling once that's true. This doesn't fix the case
|
||||
* where a user manually removes a reader, but that's not supported yet!
|
||||
*
|
||||
* @param branch
|
||||
* The pref branch to register the content handler under
|
||||
*
|
||||
*/
|
||||
_registerContentHandlerHavingBranch(branch) {
|
||||
let vals = branch.getChildList("");
|
||||
if (vals.length == 0)
|
||||
return;
|
||||
|
||||
let type = branch.getCharPref("type");
|
||||
let uri = branch.getComplexValue("uri", Ci.nsIPrefLocalizedString).data;
|
||||
let title = branch.getComplexValue("title",
|
||||
Ci.nsIPrefLocalizedString).data;
|
||||
this._updateContentTypeHandlerMap(type, uri, title);
|
||||
},
|
||||
|
||||
_updateContentTypeHandlerMap(contentType, uri, title) {
|
||||
if (!(contentType in this._contentTypes))
|
||||
this._contentTypes[contentType] = [];
|
||||
|
||||
// Avoid adding duplicates
|
||||
if (this._typeIsRegistered(contentType, uri))
|
||||
return;
|
||||
|
||||
this._contentTypes[contentType].push(new ServiceInfo(contentType, uri, title));
|
||||
|
||||
if (!(contentType in this._blockedTypes)) {
|
||||
let converterContractID = this._getConverterContractID(contentType);
|
||||
let cr = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
cr.registerFactory(WCC_CLASSID, WCC_CLASSNAME, converterContractID,
|
||||
WebContentConverterFactory);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIWebContentConverterService
|
||||
*/
|
||||
getContentHandlers(contentType, countRef) {
|
||||
this._init();
|
||||
if (countRef) {
|
||||
countRef.value = 0;
|
||||
}
|
||||
|
||||
if (!(contentType in this._contentTypes))
|
||||
return [];
|
||||
|
||||
let handlers = this._contentTypes[contentType];
|
||||
if (countRef) {
|
||||
countRef.value = handlers.length;
|
||||
}
|
||||
return handlers;
|
||||
},
|
||||
|
||||
setAutoHandler(contentType, handler) {
|
||||
Services.cpmm.sendAsyncMessage("WCCR:setAutoHandler",
|
||||
{ contentType, handler });
|
||||
},
|
||||
|
||||
getWebContentHandlerByURI(contentType, uri) {
|
||||
return this.getContentHandlers(contentType)
|
||||
.find(e => e.uri == uri) || null;
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIWebContentHandlerRegistrar
|
||||
*/
|
||||
|
@ -945,7 +1044,7 @@ WebContentConverterRegistrarContent.prototype = {
|
|||
/**
|
||||
* See nsIFactory
|
||||
*/
|
||||
createInstance: function WCCR_createInstance(outer, iid) {
|
||||
createInstance(outer, iid) {
|
||||
if (outer != null)
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
return this.QueryInterface(iid);
|
||||
|
@ -958,6 +1057,7 @@ WebContentConverterRegistrarContent.prototype = {
|
|||
*/
|
||||
QueryInterface: XPCOMUtils.generateQI(
|
||||
[Ci.nsIWebContentHandlerRegistrar,
|
||||
Ci.nsIWebContentConverterService,
|
||||
Ci.nsIFactory])
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#feedSubscribeLine {
|
||||
-moz-binding: url(subscribe.xml#feedreaderUI);
|
||||
}
|
|
@ -27,10 +27,6 @@
|
|||
href="chrome://browser/skin/feeds/subscribe.css"
|
||||
type="text/css"
|
||||
media="all"/>
|
||||
<link rel="stylesheet"
|
||||
href="chrome://browser/content/feeds/subscribe.css"
|
||||
type="text/css"
|
||||
media="all"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://browser/content/feeds/subscribe.js"/>
|
||||
</head>
|
||||
|
@ -41,8 +37,20 @@
|
|||
<p id="feedSubscriptionInfo1" />
|
||||
<p id="feedSubscriptionInfo2" />
|
||||
</div>
|
||||
<div id="feedSubscribeLine"></div>
|
||||
<div id="feedSubscribeLine">
|
||||
<label id="subscribeUsingDescription">
|
||||
<select id="handlersMenuList">
|
||||
<option id="liveBookmarksMenuItem" selected="true">&feedLiveBookmarks;</option>
|
||||
<option disabled="true">━━━━━━━</option>
|
||||
</select>
|
||||
</label>
|
||||
<label id="checkboxText">
|
||||
<input type="checkbox" id="alwaysUse" class="alwaysUse" checked="false"/>
|
||||
</label>
|
||||
<button id="subscribeButton">&feedSubscribeNow;</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="feedHeaderContainerSpacer"/>
|
||||
</div>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<!DOCTYPE bindings [
|
||||
<!ENTITY % feedDTD
|
||||
SYSTEM "chrome://browser/locale/feeds/subscribe.dtd">
|
||||
%feedDTD;
|
||||
]>
|
||||
<bindings id="feedBindings"
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<binding id="feedreaderUI" bindToUntrustedContent="true">
|
||||
<content>
|
||||
<xul:vbox>
|
||||
<xul:hbox align="center">
|
||||
<xul:description anonid="subscribeUsingDescription" class="subscribeUsingDescription"/>
|
||||
<xul:menulist anonid="handlersMenuList" class="handlersMenuList" aria-labelledby="subscribeUsingDescription">
|
||||
<xul:menupopup anonid="handlersMenuPopup" class="handlersMenuPopup">
|
||||
<xul:menuitem anonid="liveBookmarksMenuItem" label="&feedLiveBookmarks;" class="menuitem-iconic liveBookmarksMenuItem" image="chrome://browser/skin/page-livemarks.png" selected="true"/>
|
||||
<xul:menuseparator/>
|
||||
</xul:menupopup>
|
||||
</xul:menulist>
|
||||
</xul:hbox>
|
||||
<xul:hbox>
|
||||
<xul:checkbox anonid="alwaysUse" class="alwaysUse" checked="false"/>
|
||||
</xul:hbox>
|
||||
<xul:hbox align="center">
|
||||
<xul:spacer flex="1"/>
|
||||
<xul:button label="&feedSubscribeNow;" anonid="subscribeButton" class="subscribeButton"/>
|
||||
</xul:hbox>
|
||||
</xul:vbox>
|
||||
</content>
|
||||
<resources>
|
||||
<stylesheet src="chrome://browser/skin/feeds/subscribe-ui.css"/>
|
||||
</resources>
|
||||
</binding>
|
||||
</bindings>
|
||||
|
|
@ -5,5 +5,3 @@
|
|||
browser.jar:
|
||||
content/browser/feeds/subscribe.xhtml (content/subscribe.xhtml)
|
||||
content/browser/feeds/subscribe.js (content/subscribe.js)
|
||||
content/browser/feeds/subscribe.xml (content/subscribe.xml)
|
||||
content/browser/feeds/subscribe.css (content/subscribe.css)
|
||||
|
|
|
@ -24,11 +24,8 @@ SOURCES += [
|
|||
EXTRA_COMPONENTS += [
|
||||
'BrowserFeeds.manifest',
|
||||
'FeedConverter.js',
|
||||
'WebContentConverter.js',
|
||||
]
|
||||
|
||||
EXTRA_PP_COMPONENTS += [
|
||||
'FeedWriter.js',
|
||||
'WebContentConverter.js',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'browsercomps'
|
||||
|
|
|
@ -12,7 +12,7 @@ interface nsIFeedResult;
|
|||
* nsIFeedResultService provides a globally-accessible object for retrieving
|
||||
* the results of feed processing.
|
||||
*/
|
||||
[scriptable, uuid(950a829e-c20e-4dc3-b447-f8b753ae54da)]
|
||||
[scriptable, uuid(95309fd2-7b3a-47fb-97f3-5c460d9473cd)]
|
||||
interface nsIFeedResultService : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -22,8 +22,8 @@ interface nsIFeedResultService : nsISupports
|
|||
attribute boolean forcePreviewPage;
|
||||
|
||||
/**
|
||||
* Adds a URI to the user's specified external feed handler, or live
|
||||
* bookmarks.
|
||||
* Adds a URI to the user's specified external feed handler, or live
|
||||
* bookmarks.
|
||||
* @param uri
|
||||
* The uri of the feed to add.
|
||||
* @param title
|
||||
|
@ -32,11 +32,15 @@ interface nsIFeedResultService : nsISupports
|
|||
* The subtitle of the feed to add.
|
||||
* @param feedType
|
||||
* The nsIFeed type of the feed. See nsIFeed.idl
|
||||
* @param feedReader
|
||||
* The type of feed reader we're using (client, bookmarks, default)
|
||||
* If this parameter is null, the type is set to default
|
||||
*/
|
||||
void addToClientReader(in AUTF8String uri,
|
||||
void addToClientReader(in AUTF8String uri,
|
||||
in AString title,
|
||||
in AString subtitle,
|
||||
in unsigned long feedType);
|
||||
in unsigned long feedType,
|
||||
[optional] in AString feedReader);
|
||||
|
||||
/**
|
||||
* Registers a Feed Result object with a globally accessible service
|
||||
|
|
|
@ -21,8 +21,7 @@ SimpleTest.waitForExplicitFinish();
|
|||
|
||||
addLoadEvent(function() {
|
||||
var doc = SpecialPowers.wrap($("testFrame")).contentDocument;
|
||||
var daddy = doc.getElementById("feedSubscribeLine");
|
||||
var popup = doc.getAnonymousElementByAttribute(daddy, "anonid", "handlersMenuPopup");
|
||||
var popup = doc.getElementById("handlersMenuList");
|
||||
isnot(popup, null, "Feed preview should have a handlers popup");
|
||||
});
|
||||
addLoadEvent(SimpleTest.finish);
|
||||
|
|
|
@ -291,7 +291,7 @@ this.MigratorPrototype = {
|
|||
doMigrate();
|
||||
};
|
||||
BookmarkHTMLUtils.importFromURL(
|
||||
"resource:///defaults/profile/bookmarks.html", true).then(
|
||||
"chrome://browser/locale/bookmarks.html", true).then(
|
||||
onImportComplete, onImportComplete);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1760,7 +1760,7 @@ BrowserGlue.prototype = {
|
|||
let bookmarksUrl = null;
|
||||
if (restoreDefaultBookmarks) {
|
||||
// User wants to restore bookmarks.html file from default profile folder
|
||||
bookmarksUrl = "resource:///defaults/profile/bookmarks.html";
|
||||
bookmarksUrl = "chrome://browser/locale/bookmarks.html";
|
||||
}
|
||||
else if (yield OS.File.exists(BookmarkHTMLUtils.defaultPath)) {
|
||||
bookmarksUrl = OS.Path.toFileURI(BookmarkHTMLUtils.defaultPath);
|
||||
|
|
|
@ -151,26 +151,25 @@ var TabStateInternal = {
|
|||
* @returns {object} An object with the basic data for this tab.
|
||||
*/
|
||||
_collectBaseTabData: function (tab, options) {
|
||||
let tabData = {entries: [], lastAccessed: tab.lastAccessed };
|
||||
let tabData = { entries: [], lastAccessed: tab.lastAccessed };
|
||||
let browser = tab.linkedBrowser;
|
||||
|
||||
if (tab.pinned)
|
||||
if (tab.pinned) {
|
||||
tabData.pinned = true;
|
||||
else
|
||||
delete tabData.pinned;
|
||||
}
|
||||
|
||||
tabData.hidden = tab.hidden;
|
||||
if (browser.audioMuted)
|
||||
|
||||
if (browser.audioMuted) {
|
||||
tabData.muted = true;
|
||||
else
|
||||
delete tabData.muted;
|
||||
}
|
||||
|
||||
// Save tab attributes.
|
||||
tabData.attributes = TabAttributes.get(tab);
|
||||
|
||||
if (tab.__SS_extdata)
|
||||
if (tab.__SS_extdata) {
|
||||
tabData.extData = tab.__SS_extdata;
|
||||
else if (tabData.extData)
|
||||
delete tabData.extData;
|
||||
}
|
||||
|
||||
// Copy data from the tab state cache only if the tab has fully finished
|
||||
// restoring. We don't want to overwrite data contained in __SS_data.
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
@RESPATH@/browser/chrome/@AB_CD@.manifest
|
||||
@RESPATH@/chrome/@AB_CD@@JAREXT@
|
||||
@RESPATH@/chrome/@AB_CD@.manifest
|
||||
@RESPATH@/browser/defaults/profile/bookmarks.html
|
||||
@RESPATH@/browser/defaults/profile/chrome/*
|
||||
@RESPATH@/browser/defaults/profile/localstore.rdf
|
||||
@RESPATH@/browser/defaults/profile/mimeTypes.rdf
|
||||
|
|
|
@ -12,13 +12,6 @@ vpath crashreporter%.ini $(LOCALE_SRCDIR)/crashreporter
|
|||
ifdef LOCALE_MERGEDIR
|
||||
vpath crashreporter%.ini @srcdir@/en-US/crashreporter
|
||||
endif
|
||||
ifdef LOCALE_MERGEDIR
|
||||
vpath book%.inc $(LOCALE_MERGEDIR)/browser/profile
|
||||
endif
|
||||
vpath book%.inc $(LOCALE_SRCDIR)/profile
|
||||
ifdef LOCALE_MERGEDIR
|
||||
vpath book%.inc @srcdir@/en-US/profile
|
||||
endif
|
||||
|
||||
|
||||
SUBMAKEFILES += \
|
||||
|
@ -108,16 +101,7 @@ PROFILE_FILES = \
|
|||
|
||||
PROFILE_CHROME = userChrome-example.css userContent-example.css
|
||||
|
||||
NO_JA_JP_MAC_AB_CD := $(if $(filter ja-JP-mac, $(AB_CD)),ja,$(AB_CD))
|
||||
|
||||
%/defaults/profile/bookmarks.html: bookmarks.inc generic/profile/bookmarks.html.in
|
||||
$(call py_action,preprocessor, \
|
||||
-I $< \
|
||||
-DAB_CD=$(NO_JA_JP_MAC_AB_CD) \
|
||||
$(srcdir)/generic/profile/bookmarks.html.in \
|
||||
-o $@)
|
||||
|
||||
libs:: $(FINAL_TARGET)/defaults/profile/bookmarks.html ;
|
||||
DEFINES += -DBOOKMARKS_INCLUDE_DIR=$(dir $(call MERGE_FILE,profile/bookmarks.inc))
|
||||
|
||||
libs:: $(addprefix generic/profile/,$(PROFILE_FILES))
|
||||
$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/defaults/profile
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
#filter substitution
|
||||
#include @BOOKMARKS_INCLUDE_DIR@/bookmarks.inc
|
||||
#define ja_jp_mac ja-JP-mac
|
||||
#if AB_CD == ja_jp_mac
|
||||
#define AB_CD ja
|
||||
#endif
|
||||
<!-- 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/. -->
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
@AB_CD@.jar:
|
||||
% locale browser @AB_CD@ %locale/browser/
|
||||
* locale/browser/bookmarks.html (generic/profile/bookmarks.html.in)
|
||||
locale/browser/aboutAccounts.dtd (%chrome/browser/aboutAccounts.dtd)
|
||||
locale/browser/aboutCertError.dtd (%chrome/browser/aboutCertError.dtd)
|
||||
locale/browser/aboutDialog.dtd (%chrome/browser/aboutDialog.dtd)
|
||||
|
|
|
@ -11,6 +11,8 @@ Components.utils.import("resource://gre/modules/Services.jsm");
|
|||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
|
||||
"resource://gre/modules/BrowserUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
|
||||
"resource:///modules/RecentWindow.jsm");
|
||||
|
||||
const { interfaces: Ci, classes: Cc } = Components;
|
||||
|
||||
|
@ -18,12 +20,15 @@ this.Feeds = {
|
|||
init() {
|
||||
let mm = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
|
||||
mm.addMessageListener("WCCR:registerProtocolHandler", this);
|
||||
|
||||
Services.ppmm.addMessageListener("WCCR:setAutoHandler", this);
|
||||
Services.ppmm.addMessageListener("FeedConverter:addLiveBookmark", this);
|
||||
},
|
||||
|
||||
receiveMessage(aMessage) {
|
||||
let data = aMessage.data;
|
||||
switch (aMessage.name) {
|
||||
case "WCCR:registerProtocolHandler": {
|
||||
let data = aMessage.data;
|
||||
let registrar = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
|
||||
getService(Ci.nsIWebContentHandlerRegistrar);
|
||||
registrar.registerProtocolHandler(data.protocol, data.uri, data.title,
|
||||
|
@ -32,13 +37,26 @@ this.Feeds = {
|
|||
}
|
||||
|
||||
case "WCCR:registerContentHandler": {
|
||||
let data = aMessage.data;
|
||||
let registrar = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
|
||||
getService(Ci.nsIWebContentHandlerRegistrar);
|
||||
registrar.registerContentHandler(data.contentType, data.uri, data.title,
|
||||
aMessage.target);
|
||||
break;
|
||||
}
|
||||
|
||||
case "WCCR:setAutoHandler": {
|
||||
let registrar = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
|
||||
getService(Ci.nsIWebContentHandlerRegistrar);
|
||||
registrar.setAutoHandler(data.contentType, data.handler);
|
||||
break;
|
||||
}
|
||||
|
||||
case "FeedConverter:addLiveBookmark": {
|
||||
let topWindow = RecentWindow.getMostRecentBrowserWindow();
|
||||
topWindow.PlacesCommandHook.addLiveBookmark(data.spec, data.title, data.subtitle)
|
||||
.catch(Components.utils.reportError);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -5,25 +5,3 @@
|
|||
.alwaysUse {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.handlersMenuPopup > menuitem {
|
||||
-moz-padding-start: 23px;
|
||||
}
|
||||
|
||||
.handlersMenuPopup > menuitem.menuitem-iconic {
|
||||
-moz-padding-start: 2px;
|
||||
}
|
||||
|
||||
.handlersMenuPopup > .menuitem-iconic > .menu-iconic-left {
|
||||
display: -moz-box;
|
||||
min-width: 16px;
|
||||
-moz-padding-end: 2px;
|
||||
}
|
||||
|
||||
.chooseApplicationMenuItem {
|
||||
list-style-image: url("moz-icon://dummy.exe?size=16");
|
||||
}
|
||||
|
||||
#feedHeader[dir="rtl"] .handlersMenuList > menupopup {
|
||||
direction: rtl;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,20 @@ html {
|
|||
font: 3mm tahoma,arial,helvetica,sans-serif;
|
||||
}
|
||||
|
||||
#subscribeUsingDescription,
|
||||
#subscribeButton {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#subscribeUsingDescription {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
#subscribeButton {
|
||||
margin-top: 0.5em;
|
||||
margin-inline-start: auto;
|
||||
}
|
||||
|
||||
#feedBody {
|
||||
border: 1px solid THreeDShadow;
|
||||
padding: 3em;
|
||||
|
@ -21,9 +35,14 @@ html {
|
|||
margin: -4em auto 0 auto;
|
||||
background-color: InfoBackground;
|
||||
-moz-appearance: -moz-gtk-info-bar;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#feedHeader {
|
||||
#feedHeaderContainerSpacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#feedHeader {
|
||||
margin-top: 4.9em;
|
||||
margin-bottom: 1em;
|
||||
-moz-margin-start: 1.4em;
|
||||
|
@ -65,6 +84,7 @@ html {
|
|||
|
||||
#feedSubscribeLine {
|
||||
padding-top: 0.2em;
|
||||
padding-inline-start: 0.5em;
|
||||
}
|
||||
|
||||
/* Don't print subscription UI */
|
||||
|
|
|
@ -6,6 +6,3 @@
|
|||
padding: 3px;
|
||||
}
|
||||
|
||||
.chooseApplicationMenuItem {
|
||||
list-style-image: url("chrome://browser/skin/preferences/application.png");
|
||||
}
|
||||
|
|
|
@ -7,6 +7,20 @@ html {
|
|||
font: 3mm tahoma,arial,helvetica,sans-serif;
|
||||
}
|
||||
|
||||
#subscribeUsingDescription,
|
||||
#subscribeButton {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#subscribeUsingDescription {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
#subscribeButton {
|
||||
margin-top: 0.5em;
|
||||
margin-inline-start: auto;
|
||||
}
|
||||
|
||||
#feedBody {
|
||||
border: 1px solid THreeDShadow;
|
||||
padding: 3em;
|
||||
|
@ -15,6 +29,14 @@ html {
|
|||
background: -moz-Field;
|
||||
}
|
||||
|
||||
#feedHeaderContainer {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#feedHeaderContainerSpacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#feedHeader {
|
||||
border: 1px solid ThreeDShadow;
|
||||
border-radius: 10px;
|
||||
|
|
|
@ -5,25 +5,3 @@
|
|||
.alwaysUse {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.handlersMenuPopup > menuitem {
|
||||
-moz-padding-start: 23px;
|
||||
}
|
||||
|
||||
.handlersMenuPopup > menuitem.menuitem-iconic {
|
||||
-moz-padding-start: 2px;
|
||||
}
|
||||
|
||||
.handlersMenuPopup > .menuitem-iconic > .menu-iconic-left {
|
||||
display: -moz-box;
|
||||
min-width: 16px;
|
||||
-moz-padding-end: 2px;
|
||||
}
|
||||
|
||||
.chooseApplicationMenuItem {
|
||||
list-style-image: url("chrome://browser/skin/preferences/application.png");
|
||||
}
|
||||
|
||||
#feedHeader[dir="rtl"] .handlersMenuList > menupopup {
|
||||
direction: rtl;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,20 @@ html {
|
|||
font: 3mm tahoma,arial,helvetica,sans-serif;
|
||||
}
|
||||
|
||||
#subscribeUsingDescription,
|
||||
#subscribeButton {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#subscribeUsingDescription {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
#subscribeButton {
|
||||
margin-top: 0.5em;
|
||||
margin-inline-start: auto;
|
||||
}
|
||||
|
||||
#feedBody {
|
||||
border: 1px solid THreeDShadow;
|
||||
padding: 3em;
|
||||
|
@ -20,9 +34,14 @@ html {
|
|||
border-radius: 10px;
|
||||
margin: -4em auto 0 auto;
|
||||
background-color: InfoBackground;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#feedHeader {
|
||||
#feedHeaderContainerSpacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#feedHeader {
|
||||
margin-top: 4.9em;
|
||||
margin-bottom: 1em;
|
||||
-moz-margin-start: 1.4em;
|
||||
|
@ -64,6 +83,7 @@ html {
|
|||
|
||||
#feedSubscribeLine {
|
||||
padding-top: 0.2em;
|
||||
padding-inline-start: 0.5em;
|
||||
}
|
||||
|
||||
/* Don't print subscription UI */
|
||||
|
|
|
@ -101,10 +101,12 @@ $(addprefix install-,$(INSTALL_MANIFESTS)): install-%: $(TOPOBJDIR)/config/build
|
|||
@# The overhead is not that big, and this avoids waiting for proper
|
||||
@# support for defines tracking in process_install_manifest.
|
||||
@touch install_$(subst /,_,$*)
|
||||
@# BOOKMARKS_INCLUDE_DIR is for bookmarks.html only.
|
||||
$(PYTHON) -m mozbuild.action.process_install_manifest \
|
||||
--track install_$(subst /,_,$*).track \
|
||||
$(TOPOBJDIR)/$* \
|
||||
-DAB_CD=en-US \
|
||||
-DBOOKMARKS_INCLUDE_DIR=$(TOPSRCDIR)/browser/locales/en-US/profile \
|
||||
-DMOZ_APP_BUILDID=$(shell cat $(TOPOBJDIR)/config/buildid) \
|
||||
$(ACDEFINES) \
|
||||
install_$(subst /,_,$*)
|
||||
|
|
|
@ -334,9 +334,7 @@ class ProtoAndIfaceCache
|
|||
|
||||
void Trace(JSTracer* aTracer) {
|
||||
for (size_t i = 0; i < ArrayLength(*this); ++i) {
|
||||
if ((*this)[i]) {
|
||||
JS_CallObjectTracer(aTracer, &(*this)[i], "protoAndIfaceCache[i]");
|
||||
}
|
||||
JS::TraceNullableEdge(aTracer, &(*this)[i], "protoAndIfaceCache[i]");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -395,9 +393,7 @@ class ProtoAndIfaceCache
|
|||
Page* p = mPages[i];
|
||||
if (p) {
|
||||
for (size_t j = 0; j < ArrayLength(*p); ++j) {
|
||||
if ((*p)[j]) {
|
||||
JS_CallObjectTracer(trc, &(*p)[j], "protoAndIfaceCache[i]");
|
||||
}
|
||||
JS::TraceNullableEdge(trc, &(*p)[j], "protoAndIfaceCache[i]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -688,7 +688,7 @@ BluetoothA2dpManager::NotifyConnectionStatusChanged()
|
|||
|
||||
// Dispatch an event of status change
|
||||
DispatchStatusChangedEvent(
|
||||
NS_LITERAL_STRING(A2DP_STATUS_CHANGED_ID), deviceAddressStr, mA2dpConnected);
|
||||
NS_LITERAL_STRING(A2DP_STATUS_CHANGED_ID), mDeviceAddress, mA2dpConnected);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1268,7 +1268,11 @@ PackPDU(const BluetoothProperty& aIn, DaemonSocketPDU& aPDU)
|
|||
|
||||
switch (aIn.mType) {
|
||||
case PROPERTY_BDNAME:
|
||||
/* fall through */
|
||||
rv = PackPDU(PackConversion<uint8_t, uint16_t>(aIn.mRemoteName.mLength),
|
||||
PackArray<uint8_t>(aIn.mRemoteName.mName,
|
||||
aIn.mRemoteName.mLength),
|
||||
aPDU);
|
||||
break;
|
||||
case PROPERTY_REMOTE_FRIENDLY_NAME: {
|
||||
NS_ConvertUTF16toUTF8 stringUTF8(aIn.mString);
|
||||
|
||||
|
@ -1561,8 +1565,16 @@ UnpackPDU(DaemonSocketPDU& aPDU, BluetoothProperty& aOut)
|
|||
}
|
||||
|
||||
switch (aOut.mType) {
|
||||
case PROPERTY_BDNAME:
|
||||
/* fall through */
|
||||
case PROPERTY_BDNAME: {
|
||||
const uint8_t* data = aPDU.Consume(len);
|
||||
if (MOZ_HAL_IPC_UNPACK_WARN_IF(!data, BluetoothProperty)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
// We construct an nsCString here because the string
|
||||
// returned from the PDU is not 0-terminated.
|
||||
aOut.mRemoteName.Assign(data, len);
|
||||
}
|
||||
break;
|
||||
case PROPERTY_REMOTE_FRIENDLY_NAME: {
|
||||
const uint8_t* data = aPDU.Consume(len);
|
||||
if (MOZ_HAL_IPC_UNPACK_WARN_IF(!data, BluetoothProperty)) {
|
||||
|
|
|
@ -464,6 +464,10 @@ UnpackPDU(DaemonSocketPDU& aPDU, BluetoothRemoteName& aOut)
|
|||
if (!aPDU.Consume(1)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
auto end = std::find(aOut.mName, aOut.mName + sizeof(aOut.mName), '\0');
|
||||
|
||||
aOut.mLength = end - aOut.mName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -2633,10 +2633,7 @@ private:
|
|||
|
||||
InfallibleTArray<BluetoothNamedValue> properties;
|
||||
|
||||
nsAutoString addressStr;
|
||||
AddressToString(mBdAddr, addressStr);
|
||||
|
||||
AppendNamedValue(properties, "Address", addressStr);
|
||||
AppendNamedValue(properties, "Address", mBdAddr);
|
||||
AppendNamedValue(properties, "Rssi", mRssi);
|
||||
AppendNamedValue(properties, "GattAdv", mAdvData);
|
||||
AppendNamedValue(properties, "Type", static_cast<uint32_t>(type));
|
||||
|
@ -3428,13 +3425,10 @@ BluetoothGattManager::ConnectionNotification(int aConnId,
|
|||
server->mConnectionMap.Remove(aBdAddr);
|
||||
}
|
||||
|
||||
nsAutoString bdAddrStr;
|
||||
AddressToString(aBdAddr, bdAddrStr);
|
||||
|
||||
// Notify BluetoothGattServer that connection status changed
|
||||
InfallibleTArray<BluetoothNamedValue> props;
|
||||
AppendNamedValue(props, "Connected", aConnected);
|
||||
AppendNamedValue(props, "Address", bdAddrStr);
|
||||
AppendNamedValue(props, "Address", aBdAddr);
|
||||
bs->DistributeSignal(
|
||||
NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
|
||||
server->mAppUuid,
|
||||
|
@ -3742,15 +3736,12 @@ BluetoothGattManager::RequestReadNotification(
|
|||
return;
|
||||
}
|
||||
|
||||
nsAutoString bdAddrStr;
|
||||
AddressToString(aBdAddr, bdAddrStr);
|
||||
|
||||
// Distribute a signal to gattServer
|
||||
InfallibleTArray<BluetoothNamedValue> properties;
|
||||
|
||||
AppendNamedValue(properties, "TransId", aTransId);
|
||||
AppendNamedValue(properties, "AttrHandle", aAttributeHandle);
|
||||
AppendNamedValue(properties, "Address", bdAddrStr);
|
||||
AppendNamedValue(properties, "Address", aBdAddr);
|
||||
AppendNamedValue(properties, "NeedResponse", true);
|
||||
AppendNamedValue(properties, "Value", nsTArray<uint8_t>());
|
||||
|
||||
|
@ -3799,15 +3790,12 @@ BluetoothGattManager::RequestWriteNotification(
|
|||
return;
|
||||
}
|
||||
|
||||
nsAutoString bdAddrStr;
|
||||
AddressToString(aBdAddr, bdAddrStr);
|
||||
|
||||
// Distribute a signal to gattServer
|
||||
InfallibleTArray<BluetoothNamedValue> properties;
|
||||
|
||||
AppendNamedValue(properties, "TransId", aTransId);
|
||||
AppendNamedValue(properties, "AttrHandle", aAttributeHandle);
|
||||
AppendNamedValue(properties, "Address", bdAddrStr);
|
||||
AppendNamedValue(properties, "Address", aBdAddr);
|
||||
AppendNamedValue(properties, "NeedResponse", aNeedResponse);
|
||||
|
||||
nsTArray<uint8_t> value;
|
||||
|
|
|
@ -1420,13 +1420,10 @@ BluetoothOppManager::FileTransferComplete()
|
|||
return;
|
||||
}
|
||||
|
||||
nsAutoString deviceAddressStr;
|
||||
AddressToString(mDeviceAddress, deviceAddressStr);
|
||||
|
||||
NS_NAMED_LITERAL_STRING(type, "bluetooth-opp-transfer-complete");
|
||||
InfallibleTArray<BluetoothNamedValue> parameters;
|
||||
|
||||
AppendNamedValue(parameters, "address", deviceAddressStr);
|
||||
AppendNamedValue(parameters, "address", mDeviceAddress);
|
||||
AppendNamedValue(parameters, "success", mSuccessFlag);
|
||||
AppendNamedValue(parameters, "received", mIsServer);
|
||||
AppendNamedValue(parameters, "fileName", mFileName);
|
||||
|
@ -1441,13 +1438,10 @@ BluetoothOppManager::FileTransferComplete()
|
|||
void
|
||||
BluetoothOppManager::StartFileTransfer()
|
||||
{
|
||||
nsAutoString deviceAddressStr;
|
||||
AddressToString(mDeviceAddress, deviceAddressStr);
|
||||
|
||||
NS_NAMED_LITERAL_STRING(type, "bluetooth-opp-transfer-start");
|
||||
InfallibleTArray<BluetoothNamedValue> parameters;
|
||||
|
||||
AppendNamedValue(parameters, "address", deviceAddressStr);
|
||||
AppendNamedValue(parameters, "address", mDeviceAddress);
|
||||
AppendNamedValue(parameters, "received", mIsServer);
|
||||
AppendNamedValue(parameters, "fileName", mFileName);
|
||||
AppendNamedValue(parameters, "fileLength", mFileLength);
|
||||
|
@ -1461,13 +1455,10 @@ BluetoothOppManager::StartFileTransfer()
|
|||
void
|
||||
BluetoothOppManager::UpdateProgress()
|
||||
{
|
||||
nsAutoString deviceAddressStr;
|
||||
AddressToString(mDeviceAddress, deviceAddressStr);
|
||||
|
||||
NS_NAMED_LITERAL_STRING(type, "bluetooth-opp-update-progress");
|
||||
InfallibleTArray<BluetoothNamedValue> parameters;
|
||||
|
||||
AppendNamedValue(parameters, "address", deviceAddressStr);
|
||||
AppendNamedValue(parameters, "address", mDeviceAddress);
|
||||
AppendNamedValue(parameters, "received", mIsServer);
|
||||
AppendNamedValue(parameters, "processedLength", mSentFileLength);
|
||||
AppendNamedValue(parameters, "fileLength", mFileLength);
|
||||
|
@ -1478,13 +1469,10 @@ BluetoothOppManager::UpdateProgress()
|
|||
void
|
||||
BluetoothOppManager::ReceivingFileConfirmation()
|
||||
{
|
||||
nsAutoString deviceAddressStr;
|
||||
AddressToString(mDeviceAddress, deviceAddressStr);
|
||||
|
||||
NS_NAMED_LITERAL_STRING(type, "bluetooth-opp-receiving-file-confirmation");
|
||||
InfallibleTArray<BluetoothNamedValue> parameters;
|
||||
|
||||
AppendNamedValue(parameters, "address", deviceAddressStr);
|
||||
AppendNamedValue(parameters, "address", mDeviceAddress);
|
||||
AppendNamedValue(parameters, "fileName", mFileName);
|
||||
AppendNamedValue(parameters, "fileLength", mFileLength);
|
||||
AppendNamedValue(parameters, "contentType", mContentType);
|
||||
|
|
|
@ -784,26 +784,15 @@ BluetoothServiceBluedroid::GetAdaptersInternal(
|
|||
InfallibleTArray<BluetoothNamedValue> adaptersProperties;
|
||||
uint32_t numAdapters = 1; // Bluedroid supports single adapter only
|
||||
|
||||
nsAutoString bdAddressStr;
|
||||
AddressToString(mBdAddress, bdAddressStr);
|
||||
|
||||
nsTArray<nsString> bondedAddresses;
|
||||
|
||||
for (uint32_t i = 0; i < mBondedAddresses.Length(); ++i) {
|
||||
nsAutoString bondedAddressStr;
|
||||
AddressToString(mBondedAddresses[i], bondedAddressStr);
|
||||
bondedAddresses.AppendElement(bondedAddressStr);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < numAdapters; i++) {
|
||||
InfallibleTArray<BluetoothNamedValue> properties;
|
||||
|
||||
AppendNamedValue(properties, "State", mEnabled);
|
||||
AppendNamedValue(properties, "Address", bdAddressStr);
|
||||
AppendNamedValue(properties, "Address", mBdAddress);
|
||||
AppendNamedValue(properties, "Name", mBdName);
|
||||
AppendNamedValue(properties, "Discoverable", mDiscoverable);
|
||||
AppendNamedValue(properties, "Discovering", mDiscovering);
|
||||
AppendNamedValue(properties, "PairedDevices", bondedAddresses);
|
||||
AppendNamedValue(properties, "PairedDevices", mBondedAddresses);
|
||||
|
||||
AppendNamedValue(adaptersProperties, "Adapter",
|
||||
BluetoothValue(properties));
|
||||
|
@ -2014,14 +2003,11 @@ BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
|
|||
|
||||
// Cleanup static adapter properties and notify adapter.
|
||||
mBdAddress.Clear();
|
||||
mBdName.Truncate();
|
||||
|
||||
nsAutoString bdAddressStr;
|
||||
AddressToString(mBdAddress, bdAddressStr);
|
||||
mBdName.Clear();
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> props;
|
||||
AppendNamedValue(props, "Name", mBdName);
|
||||
AppendNamedValue(props, "Address", bdAddressStr);
|
||||
AppendNamedValue(props, "Address", mBdAddress);
|
||||
if (mDiscoverable) {
|
||||
mDiscoverable = false;
|
||||
AppendNamedValue(props, "Discoverable", false);
|
||||
|
@ -2120,13 +2106,10 @@ BluetoothServiceBluedroid::AdapterPropertiesNotification(
|
|||
|
||||
if (p.mType == PROPERTY_BDADDR) {
|
||||
mBdAddress = p.mBdAddress;
|
||||
nsAutoString addressStr;
|
||||
AddressToString(mBdAddress, addressStr);
|
||||
|
||||
AppendNamedValue(propertiesArray, "Address", addressStr);
|
||||
AppendNamedValue(propertiesArray, "Address", mBdAddress);
|
||||
|
||||
} else if (p.mType == PROPERTY_BDNAME) {
|
||||
mBdName = p.mString;
|
||||
mBdName = p.mRemoteName;
|
||||
AppendNamedValue(propertiesArray, "Name", mBdName);
|
||||
|
||||
} else if (p.mType == PROPERTY_ADAPTER_SCAN_MODE) {
|
||||
|
@ -2149,15 +2132,7 @@ BluetoothServiceBluedroid::AdapterPropertiesNotification(
|
|||
mBondedAddresses.Clear();
|
||||
mBondedAddresses.AppendElements(p.mBdAddressArray);
|
||||
|
||||
nsTArray<nsString> bondedAddresses;
|
||||
|
||||
for (unsigned int j = 0; j < p.mBdAddressArray.Length(); ++j) {
|
||||
nsAutoString addressStr;
|
||||
AddressToString(p.mBdAddressArray[j], addressStr);
|
||||
bondedAddresses.AppendElement(addressStr);
|
||||
}
|
||||
|
||||
AppendNamedValue(propertiesArray, "PairedDevices", bondedAddresses);
|
||||
AppendNamedValue(propertiesArray, "PairedDevices", mBondedAddresses);
|
||||
} else if (p.mType == PROPERTY_UNKNOWN) {
|
||||
/* Bug 1065999: working around unknown properties */
|
||||
} else {
|
||||
|
@ -2197,21 +2172,18 @@ BluetoothServiceBluedroid::RemoteDevicePropertiesNotification(
|
|||
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
|
||||
nsAutoString bdAddrStr;
|
||||
AddressToString(aBdAddr, bdAddrStr);
|
||||
|
||||
AppendNamedValue(propertiesArray, "Address", bdAddrStr);
|
||||
AppendNamedValue(propertiesArray, "Address", aBdAddr);
|
||||
|
||||
for (int i = 0; i < aNumProperties; ++i) {
|
||||
|
||||
const BluetoothProperty& p = aProperties[i];
|
||||
|
||||
if (p.mType == PROPERTY_BDNAME) {
|
||||
AppendNamedValue(propertiesArray, "Name", p.mString);
|
||||
AppendNamedValue(propertiesArray, "Name", p.mRemoteName);
|
||||
|
||||
// Update <address, name> mapping
|
||||
mDeviceNameMap.Remove(aBdAddr);
|
||||
mDeviceNameMap.Put(aBdAddr, p.mString);
|
||||
mDeviceNameMap.Put(aBdAddr, p.mRemoteName);
|
||||
} else if (p.mType == PROPERTY_CLASS_OF_DEVICE) {
|
||||
uint32_t cod = p.mUint32;
|
||||
AppendNamedValue(propertiesArray, "Cod", cod);
|
||||
|
@ -2235,19 +2207,7 @@ BluetoothServiceBluedroid::RemoteDevicePropertiesNotification(
|
|||
}
|
||||
|
||||
// Handler for |FetchUuidsInternal|
|
||||
|
||||
nsTArray<nsString> uuids;
|
||||
|
||||
// Construct a sorted uuid set
|
||||
for (index = 0; index < p.mUuidArray.Length(); ++index) {
|
||||
nsAutoString uuid;
|
||||
UuidToString(p.mUuidArray[index], uuid);
|
||||
|
||||
if (!uuids.Contains(uuid)) { // filter out duplicate uuids
|
||||
uuids.InsertElementSorted(uuid);
|
||||
}
|
||||
}
|
||||
AppendNamedValue(propertiesArray, "UUIDs", uuids);
|
||||
AppendNamedValue(propertiesArray, "UUIDs", p.mUuidArray);
|
||||
|
||||
} else if (p.mType == PROPERTY_TYPE_OF_DEVICE) {
|
||||
AppendNamedValue(propertiesArray, "Type",
|
||||
|
@ -2293,6 +2253,8 @@ BluetoothServiceBluedroid::RemoteDevicePropertiesNotification(
|
|||
// changing the order of (1,2) and (3).
|
||||
|
||||
// Update to registered BluetoothDevice objects
|
||||
nsAutoString bdAddrStr;
|
||||
AddressToString(aBdAddr, bdAddrStr);
|
||||
BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
|
||||
bdAddrStr, propertiesArray);
|
||||
|
||||
|
@ -2337,36 +2299,23 @@ BluetoothServiceBluedroid::DeviceFoundNotification(
|
|||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
|
||||
BluetoothAddress bdAddr;
|
||||
nsString bdName;
|
||||
BluetoothRemoteName bdName;
|
||||
|
||||
for (int i = 0; i < aNumProperties; i++) {
|
||||
|
||||
const BluetoothProperty& p = aProperties[i];
|
||||
|
||||
if (p.mType == PROPERTY_BDADDR) {
|
||||
nsAutoString addressStr;
|
||||
AddressToString(p.mBdAddress, addressStr);
|
||||
AppendNamedValue(propertiesArray, "Address", addressStr);
|
||||
AppendNamedValue(propertiesArray, "Address", p.mBdAddress);
|
||||
bdAddr = p.mBdAddress;
|
||||
} else if (p.mType == PROPERTY_BDNAME) {
|
||||
AppendNamedValue(propertiesArray, "Name", p.mString);
|
||||
bdName = p.mString;
|
||||
AppendNamedValue(propertiesArray, "Name", p.mRemoteName);
|
||||
bdName = p.mRemoteName;
|
||||
} else if (p.mType == PROPERTY_CLASS_OF_DEVICE) {
|
||||
AppendNamedValue(propertiesArray, "Cod", p.mUint32);
|
||||
|
||||
} else if (p.mType == PROPERTY_UUIDS) {
|
||||
nsTArray<nsString> uuids;
|
||||
|
||||
// Construct a sorted uuid set
|
||||
for (uint32_t index = 0; index < p.mUuidArray.Length(); ++index) {
|
||||
nsAutoString uuid;
|
||||
UuidToString(p.mUuidArray[index], uuid);
|
||||
|
||||
if (!uuids.Contains(uuid)) { // filter out duplicate uuids
|
||||
uuids.InsertElementSorted(uuid);
|
||||
}
|
||||
}
|
||||
AppendNamedValue(propertiesArray, "UUIDs", uuids);
|
||||
AppendNamedValue(propertiesArray, "UUIDs", p.mUuidArray);
|
||||
|
||||
} else if (p.mType == PROPERTY_TYPE_OF_DEVICE) {
|
||||
AppendNamedValue(propertiesArray, "Type",
|
||||
|
@ -2417,24 +2366,20 @@ BluetoothServiceBluedroid::PinRequestNotification(
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
BluetoothRemoteName bdName;
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
|
||||
// If |aBdName| is empty, get device name from |mDeviceNameMap|;
|
||||
// Otherwise update <address, name> mapping with |aBdName|
|
||||
nsAutoString bdAddr;
|
||||
AddressToString(aRemoteBdAddr, bdAddr);
|
||||
|
||||
nsAutoString bdName;
|
||||
RemoteNameToString(aBdName, bdName);
|
||||
|
||||
if (bdName.IsEmpty()) {
|
||||
if (aBdName.IsCleared()) {
|
||||
mDeviceNameMap.Get(aRemoteBdAddr, &bdName);
|
||||
} else {
|
||||
bdName.Assign(aBdName.mName, aBdName.mLength);
|
||||
mDeviceNameMap.Remove(aRemoteBdAddr);
|
||||
mDeviceNameMap.Put(aRemoteBdAddr, bdName);
|
||||
}
|
||||
|
||||
AppendNamedValue(propertiesArray, "address", bdAddr);
|
||||
AppendNamedValue(propertiesArray, "address", aRemoteBdAddr);
|
||||
AppendNamedValue(propertiesArray, "name", bdName);
|
||||
AppendNamedValue(propertiesArray, "passkey", EmptyString());
|
||||
AppendNamedValue(propertiesArray, "type",
|
||||
|
@ -2452,19 +2397,15 @@ BluetoothServiceBluedroid::SspRequestNotification(
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
BluetoothRemoteName bdName;
|
||||
InfallibleTArray<BluetoothNamedValue> propertiesArray;
|
||||
|
||||
// If |aBdName| is empty, get device name from |mDeviceNameMap|;
|
||||
// Otherwise update <address, name> mapping with |aBdName|
|
||||
nsAutoString bdAddr;
|
||||
AddressToString(aRemoteBdAddr, bdAddr);
|
||||
|
||||
nsAutoString bdName;
|
||||
RemoteNameToString(aBdName, bdName);
|
||||
|
||||
if (bdName.IsEmpty()) {
|
||||
if (aBdName.IsCleared()) {
|
||||
mDeviceNameMap.Get(aRemoteBdAddr, &bdName);
|
||||
} else {
|
||||
bdName.Assign(aBdName.mName, aBdName.mLength);
|
||||
mDeviceNameMap.Remove(aRemoteBdAddr);
|
||||
mDeviceNameMap.Put(aRemoteBdAddr, bdName);
|
||||
}
|
||||
|
@ -2496,7 +2437,7 @@ BluetoothServiceBluedroid::SspRequestNotification(
|
|||
return;
|
||||
}
|
||||
|
||||
AppendNamedValue(propertiesArray, "address", bdAddr);
|
||||
AppendNamedValue(propertiesArray, "address", aRemoteBdAddr);
|
||||
AppendNamedValue(propertiesArray, "name", bdName);
|
||||
AppendNamedValue(propertiesArray, "passkey", passkey);
|
||||
AppendNamedValue(propertiesArray, "type", pairingType);
|
||||
|
@ -2544,10 +2485,7 @@ BluetoothServiceBluedroid::BondStateChangedNotification(
|
|||
}
|
||||
|
||||
// Query pairing device name from hash table
|
||||
nsAutoString remoteBdAddr;
|
||||
AddressToString(aRemoteBdAddr, remoteBdAddr);
|
||||
|
||||
nsString remotebdName;
|
||||
BluetoothRemoteName remotebdName;
|
||||
mDeviceNameMap.Get(aRemoteBdAddr, &remotebdName);
|
||||
|
||||
// Update bonded address array and append pairing device name
|
||||
|
@ -2567,13 +2505,15 @@ BluetoothServiceBluedroid::BondStateChangedNotification(
|
|||
}
|
||||
|
||||
// Notify device of attribute changed
|
||||
nsAutoString remoteBdAddr;
|
||||
AddressToString(aRemoteBdAddr, remoteBdAddr);
|
||||
AppendNamedValue(propertiesArray, "Paired", bonded);
|
||||
DistributeSignal(NS_LITERAL_STRING("PropertyChanged"),
|
||||
remoteBdAddr,
|
||||
BluetoothValue(propertiesArray));
|
||||
|
||||
// Notify adapter of device paired/unpaired
|
||||
InsertNamedValue(propertiesArray, 0, "Address", remoteBdAddr);
|
||||
InsertNamedValue(propertiesArray, 0, "Address", aRemoteBdAddr);
|
||||
DistributeSignal(bonded ? NS_LITERAL_STRING(DEVICE_PAIRED_ID)
|
||||
: NS_LITERAL_STRING(DEVICE_UNPAIRED_ID),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER),
|
||||
|
|
|
@ -497,7 +497,7 @@ protected:
|
|||
|
||||
// Adapter properties
|
||||
BluetoothAddress mBdAddress;
|
||||
nsString mBdName;
|
||||
BluetoothRemoteName mBdName;
|
||||
bool mEnabled;
|
||||
bool mDiscoverable;
|
||||
bool mDiscovering;
|
||||
|
@ -522,7 +522,7 @@ protected:
|
|||
nsTArray<GetDeviceRequest> mGetDeviceRequests;
|
||||
|
||||
// <address, name> mapping table for remote devices
|
||||
nsDataHashtable<BluetoothAddressHashKey, nsString> mDeviceNameMap;
|
||||
nsDataHashtable<BluetoothAddressHashKey, BluetoothRemoteName> mDeviceNameMap;
|
||||
|
||||
// Arrays for SDP operations
|
||||
nsTArray<GetRemoteServiceRecordRequest> mGetRemoteServiceRecordArray;
|
||||
|
|
|
@ -624,7 +624,7 @@ BluetoothHfpManager::NotifyConnectionStateChanged(const nsAString& aType)
|
|||
return;
|
||||
}
|
||||
|
||||
DispatchStatusChangedEvent(eventName, deviceAddressStr, status);
|
||||
DispatchStatusChangedEvent(eventName, mDeviceAddress, status);
|
||||
|
||||
// Notify profile controller
|
||||
if (aType.EqualsLiteral(BLUETOOTH_HFP_STATUS_CHANGED_ID)) {
|
||||
|
|
|
@ -366,7 +366,7 @@ BluetoothA2dpManager::NotifyConnectionStatusChanged()
|
|||
|
||||
// Dispatch an event of status change
|
||||
DispatchStatusChangedEvent(
|
||||
NS_LITERAL_STRING(A2DP_STATUS_CHANGED_ID), deviceAddressStr, mA2dpConnected);
|
||||
NS_LITERAL_STRING(A2DP_STATUS_CHANGED_ID), mDeviceAddress, mA2dpConnected);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -547,7 +547,7 @@ BluetoothHfpManager::NotifyConnectionStatusChanged(const nsAString& aType)
|
|||
return;
|
||||
}
|
||||
|
||||
DispatchStatusChangedEvent(eventName, deviceAddressStr, status);
|
||||
DispatchStatusChangedEvent(eventName, mDeviceAddress, status);
|
||||
}
|
||||
|
||||
#ifdef MOZ_B2G_RIL
|
||||
|
|
|
@ -1383,16 +1383,13 @@ BluetoothOppManager::FileTransferComplete()
|
|||
return;
|
||||
}
|
||||
|
||||
nsAutoString connectedDeviceAddressStr;
|
||||
AddressToString(mConnectedDeviceAddress, connectedDeviceAddressStr);
|
||||
|
||||
nsString type, name;
|
||||
BluetoothValue v;
|
||||
InfallibleTArray<BluetoothNamedValue> parameters;
|
||||
type.AssignLiteral("bluetooth-opp-transfer-complete");
|
||||
|
||||
name.AssignLiteral("address");
|
||||
v = connectedDeviceAddressStr;
|
||||
v = mConnectedDeviceAddress;
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
name.AssignLiteral("success");
|
||||
|
@ -1426,16 +1423,13 @@ BluetoothOppManager::FileTransferComplete()
|
|||
void
|
||||
BluetoothOppManager::StartFileTransfer()
|
||||
{
|
||||
nsAutoString connectedDeviceAddressStr;
|
||||
AddressToString(mConnectedDeviceAddress, connectedDeviceAddressStr);
|
||||
|
||||
nsString type, name;
|
||||
BluetoothValue v;
|
||||
InfallibleTArray<BluetoothNamedValue> parameters;
|
||||
type.AssignLiteral("bluetooth-opp-transfer-start");
|
||||
|
||||
name.AssignLiteral("address");
|
||||
v = connectedDeviceAddressStr;
|
||||
v = mConnectedDeviceAddress;
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
name.AssignLiteral("received");
|
||||
|
@ -1465,16 +1459,13 @@ BluetoothOppManager::StartFileTransfer()
|
|||
void
|
||||
BluetoothOppManager::UpdateProgress()
|
||||
{
|
||||
nsAutoString connectedDeviceAddressStr;
|
||||
AddressToString(mConnectedDeviceAddress, connectedDeviceAddressStr);
|
||||
|
||||
nsString type, name;
|
||||
BluetoothValue v;
|
||||
InfallibleTArray<BluetoothNamedValue> parameters;
|
||||
type.AssignLiteral("bluetooth-opp-update-progress");
|
||||
|
||||
name.AssignLiteral("address");
|
||||
v = connectedDeviceAddressStr;
|
||||
v = mConnectedDeviceAddress;
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
name.AssignLiteral("received");
|
||||
|
@ -1498,16 +1489,13 @@ BluetoothOppManager::UpdateProgress()
|
|||
void
|
||||
BluetoothOppManager::ReceivingFileConfirmation()
|
||||
{
|
||||
nsAutoString connectedDeviceAddressStr;
|
||||
AddressToString(mConnectedDeviceAddress, connectedDeviceAddressStr);
|
||||
|
||||
nsString type, name;
|
||||
BluetoothValue v;
|
||||
InfallibleTArray<BluetoothNamedValue> parameters;
|
||||
type.AssignLiteral("bluetooth-opp-receiving-file-confirmation");
|
||||
|
||||
name.AssignLiteral("address");
|
||||
v = connectedDeviceAddressStr;
|
||||
v = mConnectedDeviceAddress;
|
||||
parameters.AppendElement(BluetoothNamedValue(name, v));
|
||||
|
||||
name.AssignLiteral("fileName");
|
||||
|
|
|
@ -713,6 +713,52 @@ struct BluetoothRemoteInfo {
|
|||
|
||||
struct BluetoothRemoteName {
|
||||
uint8_t mName[248]; /* not \0-terminated */
|
||||
uint8_t mLength;
|
||||
|
||||
BluetoothRemoteName()
|
||||
: mLength(0)
|
||||
{ }
|
||||
|
||||
explicit BluetoothRemoteName(const nsACString_internal& aString)
|
||||
: mLength(0)
|
||||
{
|
||||
MOZ_ASSERT(aString.Length() <= MOZ_ARRAY_LENGTH(mName));
|
||||
memcpy(mName, aString.Data(), aString.Length());
|
||||
mLength = aString.Length();
|
||||
}
|
||||
|
||||
BluetoothRemoteName(const BluetoothRemoteName&) = default;
|
||||
|
||||
BluetoothRemoteName& operator=(const BluetoothRemoteName&) = default;
|
||||
|
||||
bool operator==(const BluetoothRemoteName& aRhs) const
|
||||
{
|
||||
MOZ_ASSERT(mLength <= MOZ_ARRAY_LENGTH(mName));
|
||||
return (mLength == aRhs.mLength) &&
|
||||
std::equal(aRhs.mName, aRhs.mName + aRhs.mLength, mName);
|
||||
}
|
||||
|
||||
bool operator!=(const BluetoothRemoteName& aRhs) const
|
||||
{
|
||||
return !operator==(aRhs);
|
||||
}
|
||||
|
||||
void Assign(const uint8_t* aName, size_t aLength)
|
||||
{
|
||||
MOZ_ASSERT(aLength <= MOZ_ARRAY_LENGTH(mName));
|
||||
memcpy(mName, aName, aLength);
|
||||
mLength = aLength;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
bool IsCleared() const
|
||||
{
|
||||
return !mLength;
|
||||
}
|
||||
};
|
||||
|
||||
struct BluetoothProperty {
|
||||
|
@ -725,8 +771,10 @@ struct BluetoothProperty {
|
|||
/* PROPERTY_BDADDR */
|
||||
BluetoothAddress mBdAddress;
|
||||
|
||||
/* PROPERTY_BDNAME
|
||||
PROPERTY_REMOTE_FRIENDLY_NAME */
|
||||
/* PROPERTY_BDNAME */
|
||||
BluetoothRemoteName mRemoteName;
|
||||
|
||||
/* PROPERTY_REMOTE_FRIENDLY_NAME */
|
||||
nsString mString;
|
||||
|
||||
/* PROPERTY_UUIDS */
|
||||
|
@ -764,6 +812,12 @@ struct BluetoothProperty {
|
|||
, mBdAddress(aBdAddress)
|
||||
{ }
|
||||
|
||||
explicit BluetoothProperty(BluetoothPropertyType aType,
|
||||
const BluetoothRemoteName& aRemoteName)
|
||||
: mType(aType)
|
||||
, mRemoteName(aRemoteName)
|
||||
{ }
|
||||
|
||||
explicit BluetoothProperty(BluetoothPropertyType aType,
|
||||
const nsAString& aString)
|
||||
: mType(aType)
|
||||
|
|
|
@ -247,14 +247,11 @@ BluetoothHidManager::NotifyStatusChanged()
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsAutoString deviceAddressStr;
|
||||
AddressToString(mDeviceAddress, deviceAddressStr);
|
||||
|
||||
NS_NAMED_LITERAL_STRING(type, BLUETOOTH_HID_STATUS_CHANGED_ID);
|
||||
InfallibleTArray<BluetoothNamedValue> parameters;
|
||||
|
||||
AppendNamedValue(parameters, "connected", mConnected);
|
||||
AppendNamedValue(parameters, "address", deviceAddressStr);
|
||||
AppendNamedValue(parameters, "address", mDeviceAddress);
|
||||
|
||||
BT_ENSURE_TRUE_VOID_BROADCAST_SYSMSG(type, parameters);
|
||||
}
|
||||
|
|
|
@ -150,12 +150,12 @@ NamedValueToProperty(const BluetoothNamedValue& aValue,
|
|||
|
||||
switch (aProperty.mType) {
|
||||
case PROPERTY_BDNAME:
|
||||
if (aValue.value().type() != BluetoothValue::TnsString) {
|
||||
BT_LOGR("Bluetooth property value is not a string");
|
||||
if (aValue.value().type() != BluetoothValue::TBluetoothRemoteName) {
|
||||
BT_LOGR("Bluetooth property value is not a remote name");
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
// Set name
|
||||
aProperty.mString = aValue.value().get_nsString();
|
||||
aProperty.mRemoteName = aValue.value().get_BluetoothRemoteName();
|
||||
break;
|
||||
|
||||
case PROPERTY_ADAPTER_SCAN_MODE:
|
||||
|
@ -191,13 +191,14 @@ NamedValueToProperty(const BluetoothNamedValue& aValue,
|
|||
void
|
||||
RemoteNameToString(const BluetoothRemoteName& aRemoteName, nsAString& aString)
|
||||
{
|
||||
MOZ_ASSERT(aRemoteName.mLength <= sizeof(aRemoteName.mName));
|
||||
|
||||
auto name = reinterpret_cast<const char*>(aRemoteName.mName);
|
||||
|
||||
/* The content in |BluetoothRemoteName| is not a C string and not
|
||||
* terminated by \0. We use |strnlen| to limit its length.
|
||||
* terminated by \0. We use |mLength| to limit its length.
|
||||
*/
|
||||
aString =
|
||||
NS_ConvertUTF8toUTF16(name, strnlen(name, sizeof(aRemoteName.mName)));
|
||||
aString = NS_ConvertUTF8toUTF16(name, aRemoteName.mLength);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -517,7 +518,18 @@ SetJsObject(JSContext* aContext,
|
|||
const BluetoothValue& v = arr[i].value();
|
||||
|
||||
switch(v.type()) {
|
||||
case BluetoothValue::TnsString: {
|
||||
case BluetoothValue::TBluetoothAddress: {
|
||||
nsAutoString addressStr;
|
||||
AddressToString(v.get_BluetoothAddress(), addressStr);
|
||||
|
||||
JSString* jsData = JS_NewUCStringCopyN(aContext,
|
||||
addressStr.BeginReading(),
|
||||
addressStr.Length());
|
||||
NS_ENSURE_TRUE(jsData, false);
|
||||
val.setString(jsData);
|
||||
break;
|
||||
}
|
||||
case BluetoothValue::TnsString: {
|
||||
JSString* jsData = JS_NewUCStringCopyN(aContext,
|
||||
v.get_nsString().BeginReading(),
|
||||
v.get_nsString().Length());
|
||||
|
@ -673,13 +685,13 @@ DispatchReplyError(BluetoothReplyRunnable* aRunnable,
|
|||
|
||||
void
|
||||
DispatchStatusChangedEvent(const nsAString& aType,
|
||||
const nsAString& aAddress,
|
||||
const BluetoothAddress& aAddress,
|
||||
bool aStatus)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> data;
|
||||
AppendNamedValue(data, "address", nsString(aAddress));
|
||||
AppendNamedValue(data, "address", aAddress);
|
||||
AppendNamedValue(data, "status", aStatus);
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
|
|
|
@ -313,7 +313,7 @@ DispatchReplyError(BluetoothReplyRunnable* aRunnable,
|
|||
|
||||
void
|
||||
DispatchStatusChangedEvent(const nsAString& aType,
|
||||
const nsAString& aDeviceAddress,
|
||||
const BluetoothAddress& aDeviceAddress,
|
||||
bool aStatus);
|
||||
|
||||
//
|
||||
|
|
|
@ -406,9 +406,6 @@ void
|
|||
BluetoothAdapter::GetPairedDeviceProperties(
|
||||
const nsTArray<nsString>& aDeviceAddresses)
|
||||
{
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
NS_ENSURE_TRUE_VOID(bs);
|
||||
|
||||
nsTArray<BluetoothAddress> deviceAddresses;
|
||||
deviceAddresses.SetLength(aDeviceAddresses.Length());
|
||||
|
||||
|
@ -420,10 +417,20 @@ BluetoothAdapter::GetPairedDeviceProperties(
|
|||
}
|
||||
}
|
||||
|
||||
GetPairedDeviceProperties(deviceAddresses);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothAdapter::GetPairedDeviceProperties(
|
||||
const nsTArray<BluetoothAddress>& aDeviceAddresses)
|
||||
{
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
NS_ENSURE_TRUE_VOID(bs);
|
||||
|
||||
RefPtr<BluetoothVoidReplyRunnable> results =
|
||||
new BluetoothVoidReplyRunnable(nullptr);
|
||||
|
||||
auto rv = bs->GetPairedDevicePropertiesInternal(deviceAddresses, results);
|
||||
auto rv = bs->GetPairedDevicePropertiesInternal(aDeviceAddresses, results);
|
||||
if (NS_FAILED(rv)) {
|
||||
BT_WARNING("GetPairedDeviceProperties failed");
|
||||
return;
|
||||
|
@ -449,9 +456,9 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
|
|||
}
|
||||
}
|
||||
} else if (name.EqualsLiteral("Name")) {
|
||||
mName = value.get_nsString();
|
||||
RemoteNameToString(value.get_BluetoothRemoteName(), mName);
|
||||
} else if (name.EqualsLiteral("Address")) {
|
||||
mAddress = value.get_nsString();
|
||||
AddressToString(value.get_BluetoothAddress(), mAddress);
|
||||
} else if (name.EqualsLiteral("Discoverable")) {
|
||||
mDiscoverable = value.get_bool();
|
||||
} else if (name.EqualsLiteral("Discovering")) {
|
||||
|
@ -461,11 +468,14 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
|
|||
SetDiscoveryHandleInUse(nullptr);
|
||||
}
|
||||
} else if (name.EqualsLiteral("PairedDevices")) {
|
||||
const InfallibleTArray<nsString>& pairedDeviceAddresses
|
||||
= value.get_ArrayOfnsString();
|
||||
const InfallibleTArray<BluetoothAddress>& pairedDeviceAddresses
|
||||
= value.get_ArrayOfBluetoothAddress();
|
||||
|
||||
for (uint32_t i = 0; i < pairedDeviceAddresses.Length(); i++) {
|
||||
if (mDevices.Contains(pairedDeviceAddresses[i])) {
|
||||
nsString pairedDeviceAddressStr;
|
||||
AddressToString(pairedDeviceAddresses[i], pairedDeviceAddressStr);
|
||||
|
||||
if (mDevices.Contains(pairedDeviceAddressStr)) {
|
||||
// Existing paired devices handle 'PropertyChanged' signal
|
||||
// in BluetoothDevice::Notify()
|
||||
continue;
|
||||
|
@ -535,15 +545,15 @@ BluetoothAdapter::Notify(const BluetoothSignal& aData)
|
|||
v.get_ArrayOfBluetoothNamedValue();
|
||||
|
||||
MOZ_ASSERT(arr.Length() == 2 &&
|
||||
arr[0].value().type() == BluetoothValue::TnsString &&
|
||||
arr[0].value().type() == BluetoothValue::TBluetoothAddress &&
|
||||
arr[1].value().type() == BluetoothValue::Tbool);
|
||||
nsString address = arr[0].value().get_nsString();
|
||||
BluetoothAddress address = arr[0].value().get_BluetoothAddress();
|
||||
bool status = arr[1].value().get_bool();
|
||||
|
||||
BluetoothStatusChangedEventInit init;
|
||||
init.mBubbles = false;
|
||||
init.mCancelable = false;
|
||||
init.mAddress = address;
|
||||
AddressToString(address, init.mAddress);
|
||||
init.mStatus = status;
|
||||
RefPtr<BluetoothStatusChangedEvent> event =
|
||||
BluetoothStatusChangedEvent::Constructor(this, aData.name(), init);
|
||||
|
@ -778,9 +788,10 @@ BluetoothAdapter::SetName(const nsAString& aName, ErrorResult& aRv)
|
|||
BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// Wrap property to set and runnable to handle result
|
||||
nsString name(aName);
|
||||
BluetoothNamedValue property(NS_LITERAL_STRING("Name"),
|
||||
BluetoothValue(name));
|
||||
BluetoothValue(
|
||||
BluetoothRemoteName(
|
||||
NS_ConvertUTF16toUTF8(aName))));
|
||||
BT_ENSURE_SUCCESS_REJECT(
|
||||
bs->SetProperty(BluetoothObjectType::TYPE_ADAPTER, property,
|
||||
new BluetoothVoidReplyRunnable(nullptr, promise)),
|
||||
|
@ -1025,12 +1036,18 @@ BluetoothAdapter::IsAdapterAttributeChanged(BluetoothAdapterAttribute aType,
|
|||
MOZ_ASSERT(aValue.type() == BluetoothValue::Tbool);
|
||||
return aValue.get_bool() ? mState != BluetoothAdapterState::Enabled
|
||||
: mState != BluetoothAdapterState::Disabled;
|
||||
case BluetoothAdapterAttribute::Name:
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TnsString);
|
||||
return !mName.Equals(aValue.get_nsString());
|
||||
case BluetoothAdapterAttribute::Address:
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TnsString);
|
||||
return !mAddress.Equals(aValue.get_nsString());
|
||||
case BluetoothAdapterAttribute::Name: {
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TBluetoothRemoteName);
|
||||
nsAutoString name;
|
||||
RemoteNameToString(aValue.get_BluetoothRemoteName(), name);
|
||||
return !name.Equals(mName);
|
||||
}
|
||||
case BluetoothAdapterAttribute::Address: {
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TBluetoothAddress);
|
||||
BluetoothAddress address;
|
||||
StringToAddress(mAddress, address);
|
||||
return address != aValue.get_BluetoothAddress();
|
||||
}
|
||||
case BluetoothAdapterAttribute::Discoverable:
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::Tbool);
|
||||
return mDiscoverable != aValue.get_bool();
|
||||
|
@ -1207,14 +1224,16 @@ BluetoothAdapter::HandleDevicePaired(const BluetoothValue& aValue)
|
|||
aValue.get_ArrayOfBluetoothNamedValue();
|
||||
|
||||
MOZ_ASSERT(arr.Length() == 3 &&
|
||||
arr[0].value().type() == BluetoothValue::TnsString && // Address
|
||||
arr[1].value().type() == BluetoothValue::TnsString && // Name
|
||||
arr[0].value().type() == BluetoothValue::TBluetoothAddress && // Address
|
||||
arr[1].value().type() == BluetoothValue::TBluetoothRemoteName && // Name
|
||||
arr[2].value().type() == BluetoothValue::Tbool); // Paired
|
||||
MOZ_ASSERT(!arr[0].value().get_nsString().IsEmpty() &&
|
||||
MOZ_ASSERT(!arr[0].value().get_BluetoothAddress().IsCleared() &&
|
||||
arr[2].value().get_bool());
|
||||
|
||||
// Append the paired device if it doesn't exist in adapter's devices array
|
||||
size_t index = mDevices.IndexOf(arr[0].value().get_nsString());
|
||||
nsString addressStr;
|
||||
AddressToString(arr[0].value().get_BluetoothAddress(), addressStr);
|
||||
size_t index = mDevices.IndexOf(addressStr);
|
||||
if (index == mDevices.NoIndex) {
|
||||
index = mDevices.Length(); // the new device's index
|
||||
mDevices.AppendElement(
|
||||
|
@ -1240,13 +1259,14 @@ BluetoothAdapter::HandleDeviceUnpaired(const BluetoothValue& aValue)
|
|||
aValue.get_ArrayOfBluetoothNamedValue();
|
||||
|
||||
MOZ_ASSERT(arr.Length() == 2 &&
|
||||
arr[0].value().type() == BluetoothValue::TnsString && // Address
|
||||
arr[1].value().type() == BluetoothValue::Tbool); // Paired
|
||||
MOZ_ASSERT(!arr[0].value().get_nsString().IsEmpty() &&
|
||||
arr[0].value().type() == BluetoothValue::TBluetoothAddress && // Address
|
||||
arr[1].value().type() == BluetoothValue::Tbool); // Paired
|
||||
MOZ_ASSERT(!arr[0].value().get_BluetoothAddress().IsCleared() &&
|
||||
!arr[1].value().get_bool());
|
||||
|
||||
// Remove the device with the same address
|
||||
nsString deviceAddress = arr[0].value().get_nsString();
|
||||
nsString deviceAddress;
|
||||
AddressToString(arr[0].value().get_BluetoothAddress(), deviceAddress);
|
||||
mDevices.RemoveElement(deviceAddress);
|
||||
|
||||
// Notify application of unpaired device
|
||||
|
|
|
@ -193,6 +193,9 @@ public:
|
|||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
virtual void DisconnectFromOwner() override;
|
||||
|
||||
void GetPairedDeviceProperties(
|
||||
const nsTArray<BluetoothAddress>& aDeviceAddresses);
|
||||
|
||||
/**
|
||||
* Set this adapter's discovery handle in use (mDiscoveryHandleInUse).
|
||||
*
|
||||
|
|
|
@ -146,18 +146,27 @@ BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue)
|
|||
const nsString& name = aValue.name();
|
||||
const BluetoothValue& value = aValue.value();
|
||||
if (name.EqualsLiteral("Name")) {
|
||||
mName = value.get_nsString();
|
||||
RemoteNameToString(value.get_BluetoothRemoteName(), mName);
|
||||
} else if (name.EqualsLiteral("Address")) {
|
||||
mAddress = value.get_nsString();
|
||||
AddressToString(value.get_BluetoothAddress(), mAddress);
|
||||
} else if (name.EqualsLiteral("Cod")) {
|
||||
mCod->Update(value.get_uint32_t());
|
||||
} else if (name.EqualsLiteral("Paired")) {
|
||||
mPaired = value.get_bool();
|
||||
} else if (name.EqualsLiteral("UUIDs")) {
|
||||
// We assume the received uuids array is sorted without duplicate items.
|
||||
// If it's not, we require additional processing before assigning it
|
||||
// directly.
|
||||
mUuids = value.get_ArrayOfnsString();
|
||||
// While converting to strings, we sort the received UUIDs and remove
|
||||
// any duplicates.
|
||||
const nsTArray<BluetoothUuid>& uuids = value.get_ArrayOfBluetoothUuid();
|
||||
nsTArray<nsString> uuidStrs;
|
||||
for (uint32_t index = 0; index < uuids.Length(); ++index) {
|
||||
nsAutoString uuidStr;
|
||||
UuidToString(uuids[index], uuidStr);
|
||||
|
||||
if (!uuidStrs.Contains(uuidStr)) { // filter out duplicate UUIDs
|
||||
uuidStrs.InsertElementSorted(uuidStr);
|
||||
}
|
||||
}
|
||||
mUuids = Move(uuidStrs);
|
||||
BluetoothDeviceBinding::ClearCachedUuidsValue(this);
|
||||
} else if (name.EqualsLiteral("Type")) {
|
||||
mType = ConvertUint32ToDeviceType(value.get_uint32_t());
|
||||
|
@ -250,19 +259,35 @@ BluetoothDevice::IsDeviceAttributeChanged(BluetoothDeviceAttribute aType,
|
|||
case BluetoothDeviceAttribute::Cod:
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::Tuint32_t);
|
||||
return !mCod->Equals(aValue.get_uint32_t());
|
||||
case BluetoothDeviceAttribute::Name:
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TnsString);
|
||||
return !mName.Equals(aValue.get_nsString());
|
||||
case BluetoothDeviceAttribute::Name: {
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TBluetoothRemoteName);
|
||||
nsAutoString remoteNameStr;
|
||||
RemoteNameToString(aValue.get_BluetoothRemoteName(), remoteNameStr);
|
||||
return !mName.Equals(remoteNameStr);
|
||||
}
|
||||
case BluetoothDeviceAttribute::Paired:
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::Tbool);
|
||||
return mPaired != aValue.get_bool();
|
||||
case BluetoothDeviceAttribute::Uuids: {
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfnsString);
|
||||
const InfallibleTArray<nsString>& uuids = aValue.get_ArrayOfnsString();
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothUuid);
|
||||
const auto& uuids = aValue.get_ArrayOfBluetoothUuid();
|
||||
|
||||
nsTArray<nsString> uuidStrs;
|
||||
|
||||
// Construct a sorted uuid set
|
||||
for (size_t index = 0; index < uuids.Length(); ++index) {
|
||||
nsAutoString uuidStr;
|
||||
UuidToString(uuids[index], uuidStr);
|
||||
|
||||
if (!uuidStrs.Contains(uuidStr)) { // filter out duplicate uuids
|
||||
uuidStrs.InsertElementSorted(uuidStr);
|
||||
}
|
||||
}
|
||||
|
||||
// We assume the received uuids array is sorted without duplicate items.
|
||||
// If it's not, we require additional processing before comparing it
|
||||
// directly.
|
||||
return mUuids != uuids;
|
||||
return mUuids != uuidStrs;
|
||||
}
|
||||
default:
|
||||
BT_WARNING("Type %d is not handled", uint32_t(aType));
|
||||
|
|
|
@ -89,11 +89,11 @@ void BluetoothGattServer::HandleConnectionStateChanged(
|
|||
|
||||
MOZ_ASSERT(arr.Length() == 2 &&
|
||||
arr[0].value().type() == BluetoothValue::Tbool &&
|
||||
arr[1].value().type() == BluetoothValue::TnsString);
|
||||
arr[1].value().type() == BluetoothValue::TBluetoothAddress);
|
||||
|
||||
BluetoothStatusChangedEventInit init;
|
||||
init.mStatus = arr[0].value().get_bool();
|
||||
init.mAddress = arr[1].value().get_nsString();
|
||||
AddressToString(arr[1].value().get_BluetoothAddress(), init.mAddress);
|
||||
|
||||
RefPtr<BluetoothStatusChangedEvent> event =
|
||||
BluetoothStatusChangedEvent::Constructor(
|
||||
|
@ -190,14 +190,15 @@ BluetoothGattServer::HandleReadWriteRequest(const BluetoothValue& aValue,
|
|||
MOZ_ASSERT(arr.Length() == 5 &&
|
||||
arr[0].value().type() == BluetoothValue::Tint32_t &&
|
||||
arr[1].value().type() == BluetoothValue::TBluetoothAttributeHandle &&
|
||||
arr[2].value().type() == BluetoothValue::TnsString &&
|
||||
arr[2].value().type() == BluetoothValue::TBluetoothAddress &&
|
||||
arr[3].value().type() == BluetoothValue::Tbool &&
|
||||
arr[4].value().type() == BluetoothValue::TArrayOfuint8_t);
|
||||
|
||||
int32_t requestId = arr[0].value().get_int32_t();
|
||||
BluetoothAttributeHandle handle =
|
||||
arr[1].value().get_BluetoothAttributeHandle();
|
||||
nsString address = arr[2].value().get_nsString();
|
||||
nsString address;
|
||||
AddressToString(arr[2].value().get_BluetoothAddress(), address);
|
||||
bool needResponse = arr[3].value().get_bool();
|
||||
nsTArray<uint8_t> value;
|
||||
value = arr[4].value().get_ArrayOfuint8_t();
|
||||
|
|
|
@ -196,11 +196,12 @@ BluetoothManager::HandleAdapterAdded(const BluetoothValue& aValue)
|
|||
void
|
||||
BluetoothManager::HandleAdapterRemoved(const BluetoothValue& aValue)
|
||||
{
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TnsString);
|
||||
MOZ_ASSERT(aValue.type() == BluetoothValue::TBluetoothAddress);
|
||||
MOZ_ASSERT(DefaultAdapterExists());
|
||||
|
||||
// Remove the adapter of given address from adapters array
|
||||
nsString addressToRemove = aValue.get_nsString();
|
||||
nsString addressToRemove;
|
||||
AddressToString(aValue.get_BluetoothAddress(), addressToRemove);
|
||||
|
||||
uint32_t i;
|
||||
for (i = 0; i < mAdapters.Length(); i++) {
|
||||
|
|
|
@ -48,21 +48,29 @@ BluetoothPairingListener::~BluetoothPairingListener()
|
|||
}
|
||||
|
||||
void
|
||||
BluetoothPairingListener::DispatchPairingEvent(const nsAString& aName,
|
||||
const nsAString& aAddress,
|
||||
const nsAString& aPasskey,
|
||||
const nsAString& aType)
|
||||
BluetoothPairingListener::DispatchPairingEvent(
|
||||
const BluetoothRemoteName& aName,
|
||||
const BluetoothAddress& aAddress,
|
||||
const nsAString& aPasskey,
|
||||
const nsAString& aType)
|
||||
{
|
||||
MOZ_ASSERT(!aName.IsEmpty() && !aAddress.IsEmpty() && !aType.IsEmpty());
|
||||
MOZ_ASSERT(!aAddress.IsCleared());
|
||||
MOZ_ASSERT(!aName.IsCleared() && !aType.IsEmpty());
|
||||
|
||||
nsString nameStr;
|
||||
RemoteNameToString(aName, nameStr);
|
||||
|
||||
nsString addressStr;
|
||||
AddressToString(aAddress, addressStr);
|
||||
|
||||
RefPtr<BluetoothPairingHandle> handle =
|
||||
BluetoothPairingHandle::Create(GetOwner(),
|
||||
aAddress,
|
||||
addressStr,
|
||||
aType,
|
||||
aPasskey);
|
||||
|
||||
BluetoothPairingEventInit init;
|
||||
init.mDeviceName = aName;
|
||||
init.mDeviceName = nameStr;
|
||||
init.mHandle = handle;
|
||||
|
||||
RefPtr<BluetoothPairingEvent> event =
|
||||
|
@ -87,13 +95,13 @@ BluetoothPairingListener::Notify(const BluetoothSignal& aData)
|
|||
value.get_ArrayOfBluetoothNamedValue();
|
||||
|
||||
MOZ_ASSERT(arr.Length() == 4 &&
|
||||
arr[0].value().type() == BluetoothValue::TnsString && // address
|
||||
arr[1].value().type() == BluetoothValue::TnsString && // name
|
||||
arr[0].value().type() == BluetoothValue::TBluetoothAddress && // address
|
||||
arr[1].value().type() == BluetoothValue::TBluetoothRemoteName && // name
|
||||
arr[2].value().type() == BluetoothValue::TnsString && // passkey
|
||||
arr[3].value().type() == BluetoothValue::TnsString); // type
|
||||
|
||||
nsString address = arr[0].value().get_nsString();
|
||||
nsString name = arr[1].value().get_nsString();
|
||||
BluetoothAddress address = arr[0].value().get_BluetoothAddress();
|
||||
const BluetoothRemoteName& name = arr[1].value().get_BluetoothRemoteName();
|
||||
nsString passkey = arr[2].value().get_nsString();
|
||||
nsString type = arr[3].value().get_nsString();
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ public:
|
|||
static already_AddRefed<BluetoothPairingListener>
|
||||
Create(nsPIDOMWindow* aWindow);
|
||||
|
||||
void DispatchPairingEvent(const nsAString& aName,
|
||||
const nsAString& aAddress,
|
||||
void DispatchPairingEvent(const BluetoothRemoteName& aName,
|
||||
const BluetoothAddress& aAddress,
|
||||
const nsAString& aPasskey,
|
||||
const nsAString& aType);
|
||||
|
||||
|
|
|
@ -79,6 +79,36 @@ struct ParamTraits<mozilla::dom::bluetooth::BluetoothPinCode>
|
|||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::dom::bluetooth::BluetoothRemoteName>
|
||||
{
|
||||
typedef mozilla::dom::bluetooth::BluetoothRemoteName paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.mLength);
|
||||
for (size_t i = 0; i < aParam.mLength; ++i) {
|
||||
WriteParam(aMsg, aParam.mName[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
if (!ReadParam(aMsg, aIter, &aResult->mLength)) {
|
||||
return false;
|
||||
}
|
||||
if (aResult->mLength > MOZ_ARRAY_LENGTH(aResult->mName)) {
|
||||
return false;
|
||||
}
|
||||
for (uint8_t i = 0; i < aResult->mLength; ++i) {
|
||||
if (!ReadParam(aMsg, aIter, aResult->mName + i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ParamTraits<mozilla::dom::bluetooth::BluetoothSspVariant>
|
||||
: public ContiguousEnumSerializer<
|
||||
|
|
|
@ -4,6 +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/. */
|
||||
|
||||
using mozilla::dom::bluetooth::BluetoothAddress
|
||||
from "mozilla/dom/bluetooth/BluetoothCommon.h";
|
||||
using mozilla::dom::bluetooth::BluetoothAttributeHandle
|
||||
from "mozilla/dom/bluetooth/BluetoothCommon.h";
|
||||
using mozilla::dom::bluetooth::BluetoothGattAttrPerm
|
||||
|
@ -20,6 +22,8 @@ using mozilla::dom::bluetooth::BluetoothGattServiceId
|
|||
from "mozilla/dom/bluetooth/BluetoothCommon.h";
|
||||
using mozilla::dom::bluetooth::BluetoothGattWriteType
|
||||
from "mozilla/dom/bluetooth/BluetoothCommon.h";
|
||||
using mozilla::dom::bluetooth::BluetoothRemoteName
|
||||
from "mozilla/dom/bluetooth/BluetoothCommon.h";
|
||||
using mozilla::dom::bluetooth::BluetoothSspVariant
|
||||
from "mozilla/dom/bluetooth/BluetoothCommon.h";
|
||||
using mozilla::dom::bluetooth::BluetoothStatus
|
||||
|
@ -52,8 +56,12 @@ union BluetoothValue
|
|||
BluetoothGattServiceId;
|
||||
BluetoothGattServiceId[];
|
||||
BluetoothGattCharAttribute[];
|
||||
BluetoothAddress;
|
||||
BluetoothAddress[];
|
||||
BluetoothAttributeHandle;
|
||||
BluetoothRemoteName;
|
||||
BluetoothUuid;
|
||||
BluetoothUuid[];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1303,7 +1303,8 @@ public:
|
|||
nsLayoutUtils::SurfaceFromElementResult
|
||||
SurfaceFromElement(dom::Element* elem)
|
||||
{
|
||||
uint32_t flags = nsLayoutUtils::SFE_WANT_IMAGE_SURFACE;
|
||||
uint32_t flags = nsLayoutUtils::SFE_WANT_IMAGE_SURFACE |
|
||||
nsLayoutUtils::SFE_USE_ELEMENT_SIZE_IF_VECTOR;
|
||||
|
||||
if (mPixelStore_ColorspaceConversion == LOCAL_GL_NONE)
|
||||
flags |= nsLayoutUtils::SFE_NO_COLORSPACE_CONVERSION;
|
||||
|
|
|
@ -75,7 +75,11 @@ TextDecoder::Decode(const char* aInput, const int32_t aLength,
|
|||
rv = mDecoder->Convert(aInput, &length, buf, &outLen);
|
||||
MOZ_ASSERT(mFatal || rv != NS_ERROR_ILLEGAL_INPUT);
|
||||
buf[outLen] = 0;
|
||||
aOutDecodedString.Append(buf, outLen);
|
||||
|
||||
if (!aOutDecodedString.Append(buf, outLen, fallible)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the internal streaming flag of the decoder object is not set,
|
||||
// then reset the encoding algorithm state to the default values
|
||||
|
|
|
@ -57,7 +57,7 @@ this.Keyboard = {
|
|||
'RemoveFocus',
|
||||
'SetSelectionRange', 'ReplaceSurroundingText', 'ShowInputMethodPicker',
|
||||
'SwitchToNextInputMethod', 'HideInputMethod',
|
||||
'GetText', 'SendKey', 'GetContext',
|
||||
'SendKey', 'GetContext',
|
||||
'SetComposition', 'EndComposition',
|
||||
'RegisterSync', 'Unregister'
|
||||
],
|
||||
|
@ -162,8 +162,6 @@ this.Keyboard = {
|
|||
mm.addMessageListener('Forms:Focus', this);
|
||||
mm.addMessageListener('Forms:Blur', this);
|
||||
mm.addMessageListener('Forms:SelectionChange', this);
|
||||
mm.addMessageListener('Forms:GetText:Result:OK', this);
|
||||
mm.addMessageListener('Forms:GetText:Result:Error', this);
|
||||
mm.addMessageListener('Forms:SetSelectionRange:Result:OK', this);
|
||||
mm.addMessageListener('Forms:SetSelectionRange:Result:Error', this);
|
||||
mm.addMessageListener('Forms:ReplaceSurroundingText:Result:OK', this);
|
||||
|
@ -226,8 +224,6 @@ this.Keyboard = {
|
|||
this.handleBlur(msg);
|
||||
break;
|
||||
case 'Forms:SelectionChange':
|
||||
case 'Forms:GetText:Result:OK':
|
||||
case 'Forms:GetText:Result:Error':
|
||||
case 'Forms:SetSelectionRange:Result:OK':
|
||||
case 'Forms:ReplaceSurroundingText:Result:OK':
|
||||
case 'Forms:SendKey:Result:OK':
|
||||
|
@ -288,9 +284,6 @@ this.Keyboard = {
|
|||
case 'Keyboard:ShowInputMethodPicker':
|
||||
this.showInputMethodPicker();
|
||||
break;
|
||||
case 'Keyboard:GetText':
|
||||
this.getText(msg);
|
||||
break;
|
||||
case 'Keyboard:SendKey':
|
||||
this.sendKey(msg);
|
||||
break;
|
||||
|
@ -423,10 +416,6 @@ this.Keyboard = {
|
|||
});
|
||||
},
|
||||
|
||||
getText: function keyboardGetText(msg) {
|
||||
this.sendToForm('Forms:GetText', msg.data);
|
||||
},
|
||||
|
||||
sendKey: function keyboardSendKey(msg) {
|
||||
this.sendToForm('Forms:Input:SendKey', msg.data);
|
||||
},
|
||||
|
|
|
@ -739,24 +739,67 @@ InputContextDOMRequestIpcHelper.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
function MozInputContextSelectionChangeEventDetail(ctx, ownAction) {
|
||||
this._ctx = ctx;
|
||||
this.ownAction = ownAction;
|
||||
}
|
||||
|
||||
MozInputContextSelectionChangeEventDetail.prototype = {
|
||||
classID: Components.ID("ef35443e-a400-4ae3-9170-c2f4e05f7aed"),
|
||||
QueryInterface: XPCOMUtils.generateQI([]),
|
||||
|
||||
ownAction: false,
|
||||
|
||||
get selectionStart() {
|
||||
return this._ctx.selectionStart;
|
||||
},
|
||||
|
||||
get selectionEnd() {
|
||||
return this._ctx.selectionEnd;
|
||||
}
|
||||
};
|
||||
|
||||
function MozInputContextSurroundingTextChangeEventDetail(ctx, ownAction) {
|
||||
this._ctx = ctx;
|
||||
this.ownAction = ownAction;
|
||||
}
|
||||
|
||||
MozInputContextSurroundingTextChangeEventDetail.prototype = {
|
||||
classID: Components.ID("1c50fdaf-74af-4b2e-814f-792caf65a168"),
|
||||
QueryInterface: XPCOMUtils.generateQI([]),
|
||||
|
||||
ownAction: false,
|
||||
|
||||
get text() {
|
||||
return this._ctx.text;
|
||||
},
|
||||
|
||||
get textBeforeCursor() {
|
||||
return this._ctx.textBeforeCursor;
|
||||
},
|
||||
|
||||
get textAfterCursor() {
|
||||
return this._ctx.textAfterCursor;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* ==============================================
|
||||
* InputContext
|
||||
* ==============================================
|
||||
*/
|
||||
function MozInputContext(ctx) {
|
||||
function MozInputContext(data) {
|
||||
this._context = {
|
||||
type: ctx.type,
|
||||
inputType: ctx.inputType,
|
||||
inputMode: ctx.inputMode,
|
||||
lang: ctx.lang,
|
||||
selectionStart: ctx.selectionStart,
|
||||
selectionEnd: ctx.selectionEnd,
|
||||
textBeforeCursor: ctx.textBeforeCursor,
|
||||
textAfterCursor: ctx.textAfterCursor
|
||||
type: data.type,
|
||||
inputType: data.inputType,
|
||||
inputMode: data.inputMode,
|
||||
lang: data.lang,
|
||||
selectionStart: data.selectionStart,
|
||||
selectionEnd: data.selectionEnd,
|
||||
text: data.value
|
||||
};
|
||||
|
||||
this._contextId = ctx.contextId;
|
||||
this._contextId = data.contextId;
|
||||
}
|
||||
|
||||
MozInputContext.prototype = {
|
||||
|
@ -849,48 +892,45 @@ MozInputContext.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
updateSelectionContext: function ic_updateSelectionContext(ctx, ownAction) {
|
||||
updateSelectionContext: function ic_updateSelectionContext(data, ownAction) {
|
||||
if (!this._context) {
|
||||
return;
|
||||
}
|
||||
|
||||
let selectionDirty = this._context.selectionStart !== ctx.selectionStart ||
|
||||
this._context.selectionEnd !== ctx.selectionEnd;
|
||||
let surroundDirty = this._context.textBeforeCursor !== ctx.textBeforeCursor ||
|
||||
this._context.textAfterCursor !== ctx.textAfterCursor;
|
||||
let selectionDirty =
|
||||
this._context.selectionStart !== data.selectionStart ||
|
||||
this._context.selectionEnd !== data.selectionEnd;
|
||||
let surroundDirty = selectionDirty || data.text !== this._contextId.text;
|
||||
|
||||
this._context.selectionStart = ctx.selectionStart;
|
||||
this._context.selectionEnd = ctx.selectionEnd;
|
||||
this._context.textBeforeCursor = ctx.textBeforeCursor;
|
||||
this._context.textAfterCursor = ctx.textAfterCursor;
|
||||
this._context.text = data.text;
|
||||
this._context.selectionStart = data.selectionStart;
|
||||
this._context.selectionEnd = data.selectionEnd;
|
||||
|
||||
if (selectionDirty) {
|
||||
this._fireEvent("selectionchange", {
|
||||
selectionStart: ctx.selectionStart,
|
||||
selectionEnd: ctx.selectionEnd,
|
||||
ownAction: ownAction
|
||||
});
|
||||
let selectionChangeDetail =
|
||||
new MozInputContextSelectionChangeEventDetail(this, ownAction);
|
||||
let wrappedSelectionChangeDetail =
|
||||
this._window.MozInputContextSelectionChangeEventDetail
|
||||
._create(this._window, selectionChangeDetail);
|
||||
let selectionChangeEvent = new this._window.CustomEvent("selectionchange",
|
||||
{ cancelable: false, detail: wrappedSelectionChangeDetail });
|
||||
|
||||
this.__DOM_IMPL__.dispatchEvent(selectionChangeEvent);
|
||||
}
|
||||
|
||||
if (surroundDirty) {
|
||||
this._fireEvent("surroundingtextchange", {
|
||||
beforeString: ctx.textBeforeCursor,
|
||||
afterString: ctx.textAfterCursor,
|
||||
ownAction: ownAction
|
||||
});
|
||||
let surroundingTextChangeDetail =
|
||||
new MozInputContextSurroundingTextChangeEventDetail(this, ownAction);
|
||||
let wrappedSurroundingTextChangeDetail =
|
||||
this._window.MozInputContextSurroundingTextChangeEventDetail
|
||||
._create(this._window, surroundingTextChangeDetail);
|
||||
let selectionChangeEvent = new this._window.CustomEvent("surroundingtextchange",
|
||||
{ cancelable: false, detail: wrappedSurroundingTextChangeDetail });
|
||||
|
||||
this.__DOM_IMPL__.dispatchEvent(selectionChangeEvent);
|
||||
}
|
||||
},
|
||||
|
||||
_fireEvent: function ic_fireEvent(eventName, aDetail) {
|
||||
let detail = {
|
||||
detail: aDetail
|
||||
};
|
||||
|
||||
let event = new this._window.CustomEvent(eventName,
|
||||
Cu.cloneInto(detail, this._window));
|
||||
this.__DOM_IMPL__.dispatchEvent(event);
|
||||
},
|
||||
|
||||
// tag name of the input field
|
||||
get type() {
|
||||
return this._context.type;
|
||||
|
@ -910,15 +950,16 @@ MozInputContext.prototype = {
|
|||
},
|
||||
|
||||
getText: function ic_getText(offset, length) {
|
||||
let self = this;
|
||||
return this._sendPromise(function(resolverId) {
|
||||
cpmmSendAsyncMessageWithKbID(self, 'Keyboard:GetText', {
|
||||
contextId: self._contextId,
|
||||
requestId: resolverId,
|
||||
offset: offset,
|
||||
length: length
|
||||
});
|
||||
});
|
||||
let text;
|
||||
if (offset && length) {
|
||||
text = this._context.text.substr(offset, length);
|
||||
} else if (offset) {
|
||||
text = this._context.text.substr(offset);
|
||||
} else {
|
||||
text = this._context.text;
|
||||
}
|
||||
|
||||
return this._window.Promise.resolve(text);
|
||||
},
|
||||
|
||||
get selectionStart() {
|
||||
|
@ -929,12 +970,23 @@ MozInputContext.prototype = {
|
|||
return this._context.selectionEnd;
|
||||
},
|
||||
|
||||
get text() {
|
||||
return this._context.text;
|
||||
},
|
||||
|
||||
get textBeforeCursor() {
|
||||
return this._context.textBeforeCursor;
|
||||
let text = this._context.text;
|
||||
let start = this._context.selectionStart;
|
||||
return (start < 100) ?
|
||||
text.substr(0, start) :
|
||||
text.substr(start - 100, 100);
|
||||
},
|
||||
|
||||
get textAfterCursor() {
|
||||
return this._context.textAfterCursor;
|
||||
let text = this._context.text;
|
||||
let start = this._context.selectionStart;
|
||||
let end = this._context.selectionEnd;
|
||||
return text.substr(start, end - start + 100);
|
||||
},
|
||||
|
||||
setSelectionRange: function ic_setSelectionRange(start, length) {
|
||||
|
|
|
@ -423,7 +423,6 @@ var FormAssistant = {
|
|||
addMessageListener("Forms:Select:Blur", this);
|
||||
addMessageListener("Forms:SetSelectionRange", this);
|
||||
addMessageListener("Forms:ReplaceSurroundingText", this);
|
||||
addMessageListener("Forms:GetText", this);
|
||||
addMessageListener("Forms:Input:SendKey", this);
|
||||
addMessageListener("Forms:GetContext", this);
|
||||
addMessageListener("Forms:SetComposition", this);
|
||||
|
@ -438,8 +437,8 @@ var FormAssistant = {
|
|||
isHandlingFocus: false,
|
||||
selectionStart: -1,
|
||||
selectionEnd: -1,
|
||||
textBeforeCursor: "",
|
||||
textAfterCursor: "",
|
||||
text: "",
|
||||
|
||||
scrollIntoViewTimeout: null,
|
||||
_focusedElement: null,
|
||||
_focusCounter: 0, // up one for every time we focus a new element
|
||||
|
@ -524,8 +523,6 @@ var FormAssistant = {
|
|||
});
|
||||
if (del && element === self.focusedElement) {
|
||||
self.unhandleFocus();
|
||||
self.selectionStart = -1;
|
||||
self.selectionEnd = -1;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -626,8 +623,6 @@ var FormAssistant = {
|
|||
case "blur":
|
||||
if (this.focusedElement) {
|
||||
this.unhandleFocus();
|
||||
this.selectionStart = -1;
|
||||
this.selectionEnd = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -696,14 +691,6 @@ var FormAssistant = {
|
|||
}
|
||||
|
||||
if (!target) {
|
||||
switch (msg.name) {
|
||||
case "Forms:GetText":
|
||||
sendAsyncMessage("Forms:GetText:Result:Error", {
|
||||
requestId: json.requestId,
|
||||
error: "No focused element"
|
||||
});
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -935,24 +922,6 @@ var FormAssistant = {
|
|||
break;
|
||||
}
|
||||
|
||||
case "Forms:GetText": {
|
||||
let value = isContentEditable(target) ? getContentEditableText(target)
|
||||
: target.value;
|
||||
|
||||
if (json.offset && json.length) {
|
||||
value = value.substr(json.offset, json.length);
|
||||
}
|
||||
else if (json.offset) {
|
||||
value = value.substr(json.offset);
|
||||
}
|
||||
|
||||
sendAsyncMessage("Forms:GetText:Result:OK", {
|
||||
requestId: json.requestId,
|
||||
text: value
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case "Forms:GetContext": {
|
||||
let obj = getJSON(target, this._focusCounter);
|
||||
sendAsyncMessage("Forms:GetContext:Result:OK", obj);
|
||||
|
@ -997,6 +966,9 @@ var FormAssistant = {
|
|||
unhandleFocus: function fa_unhandleFocus() {
|
||||
this.setFocusedElement(null);
|
||||
this.isHandlingFocus = false;
|
||||
this.selectionStart = -1;
|
||||
this.selectionEnd = -1;
|
||||
this.text = "";
|
||||
sendAsyncMessage("Forms:Blur", {});
|
||||
},
|
||||
|
||||
|
@ -1036,23 +1008,18 @@ var FormAssistant = {
|
|||
let text = isContentEditable(element) ? getContentEditableText(element)
|
||||
: element.value;
|
||||
|
||||
let textAround = getTextAroundCursor(text, range);
|
||||
|
||||
let changed = this.selectionStart !== range[0] ||
|
||||
this.selectionEnd !== range[1] ||
|
||||
this.textBeforeCursor !== textAround.before ||
|
||||
this.textAfterCursor !== textAround.after;
|
||||
this.text !== text;
|
||||
|
||||
this.selectionStart = range[0];
|
||||
this.selectionEnd = range[1];
|
||||
this.textBeforeCursor = textAround.before;
|
||||
this.textAfterCursor = textAround.after;
|
||||
this.text = text;
|
||||
|
||||
return {
|
||||
selectionStart: range[0],
|
||||
selectionEnd: range[1],
|
||||
textBeforeCursor: textAround.before,
|
||||
textAfterCursor: textAround.after,
|
||||
text: text,
|
||||
changed: changed
|
||||
};
|
||||
},
|
||||
|
@ -1157,7 +1124,6 @@ function getJSON(element, focusCounter) {
|
|||
}
|
||||
|
||||
let range = getSelectionRange(element);
|
||||
let textAround = getTextAroundCursor(value, range);
|
||||
|
||||
return {
|
||||
"contextId": focusCounter,
|
||||
|
@ -1172,24 +1138,7 @@ function getJSON(element, focusCounter) {
|
|||
"selectionEnd": range[1],
|
||||
"max": max,
|
||||
"min": min,
|
||||
"lang": element.lang || "",
|
||||
"textBeforeCursor": textAround.before,
|
||||
"textAfterCursor": textAround.after
|
||||
};
|
||||
}
|
||||
|
||||
function getTextAroundCursor(value, range) {
|
||||
let textBeforeCursor = range[0] < 100 ?
|
||||
value.substr(0, range[0]) :
|
||||
value.substr(range[0] - 100, 100);
|
||||
|
||||
let textAfterCursor = range[1] + 100 > value.length ?
|
||||
value.substr(range[0], value.length) :
|
||||
value.substr(range[0], range[1] - range[0] + 100);
|
||||
|
||||
return {
|
||||
before: textBeforeCursor,
|
||||
after: textAfterCursor
|
||||
"lang": element.lang || ""
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ function runTest() {
|
|||
is(gContext.inputType, 'text', 'The inputType should match.');
|
||||
is(gContext.inputMode, 'verbatim', 'The inputMode should match.');
|
||||
is(gContext.lang, 'zh', 'The language should match.');
|
||||
is(gContext.text, 'Yuan', 'Should get the text.');
|
||||
is(gContext.textBeforeCursor + gContext.textAfterCursor, 'Yuan',
|
||||
'Should get the text around the cursor.');
|
||||
|
||||
|
@ -65,6 +66,7 @@ function test_setSelectionRange() {
|
|||
test_sendKey();
|
||||
}, function(e) {
|
||||
ok(false, 'setSelectionRange failed:' + e.name);
|
||||
console.error(e);
|
||||
inputmethod_cleanup();
|
||||
});
|
||||
}
|
||||
|
@ -72,6 +74,8 @@ function test_setSelectionRange() {
|
|||
function test_sendKey() {
|
||||
// Add '-' to current cursor posistion and move the cursor position to 3.
|
||||
gContext.sendKey(0, '-'.charCodeAt(0), 0).then(function() {
|
||||
is(gContext.text, 'Yu-an',
|
||||
'sendKey should changed the input field correctly.');
|
||||
is(gContext.textBeforeCursor + gContext.textAfterCursor, 'Yu-an',
|
||||
'sendKey should changed the input field correctly.');
|
||||
test_deleteSurroundingText();
|
||||
|
@ -86,6 +90,8 @@ function test_deleteSurroundingText() {
|
|||
// position back to 2.
|
||||
gContext.deleteSurroundingText(-1, 1).then(function() {
|
||||
ok(true, 'deleteSurroundingText finished');
|
||||
is(gContext.text, 'Yuan',
|
||||
'deleteSurroundingText should changed the input field correctly.');
|
||||
is(gContext.textBeforeCursor + gContext.textAfterCursor, 'Yuan',
|
||||
'deleteSurroundingText should changed the input field correctly.');
|
||||
test_replaceSurroundingText();
|
||||
|
@ -99,6 +105,8 @@ function test_replaceSurroundingText() {
|
|||
// Replace 'Yuan' with 'Xulei'.
|
||||
gContext.replaceSurroundingText('Xulei', -2, 4).then(function() {
|
||||
ok(true, 'replaceSurroundingText finished');
|
||||
is(gContext.text, 'Xulei',
|
||||
'replaceSurroundingText changed the input field correctly.');
|
||||
is(gContext.textBeforeCursor + gContext.textAfterCursor, 'Xulei',
|
||||
'replaceSurroundingText changed the input field correctly.');
|
||||
test_setComposition();
|
||||
|
@ -120,6 +128,8 @@ function test_setComposition() {
|
|||
|
||||
function test_endComposition() {
|
||||
gContext.endComposition('2013').then(function() {
|
||||
is(gContext.text, 'Xulei2013',
|
||||
'endComposition changed the input field correctly.');
|
||||
is(gContext.textBeforeCursor + gContext.textAfterCursor, 'Xulei2013',
|
||||
'endComposition changed the input field correctly.');
|
||||
test_onSelectionChange();
|
||||
|
@ -181,8 +191,9 @@ function test_onSurroundingTextChange() {
|
|||
|
||||
gContext.onsurroundingtextchange = function(evt) {
|
||||
ok(true, 'onsurroundingtextchange fired');
|
||||
is(evt.detail.beforeString, 'Xulei2013jj');
|
||||
is(evt.detail.afterString, '');
|
||||
is(evt.detail.text, 'Xulei2013jj');
|
||||
is(evt.detail.textBeforeCursor, 'Xulei2013jj');
|
||||
is(evt.detail.textAfterCursor, '');
|
||||
ok(evt.detail.ownAction);
|
||||
};
|
||||
|
||||
|
|
|
@ -14,13 +14,14 @@ class CPOWManager;
|
|||
} /* namespace jsipc */
|
||||
|
||||
namespace dom {
|
||||
|
||||
class CPOWManagerGetter
|
||||
{
|
||||
public:
|
||||
virtual mozilla::jsipc::CPOWManager* GetCPOWManager() = 0;
|
||||
};
|
||||
} /* namespace dom */
|
||||
|
||||
} /* namespace dom */
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif /* mozilla_dom_CPOWManagerGetter_h */
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
void DeferredDestroy();
|
||||
virtual bool IsContentBridgeParent() override { return true; }
|
||||
virtual bool IsContentBridgeParent() const override { return true; }
|
||||
void NotifyTabDestroyed();
|
||||
|
||||
static ContentBridgeParent*
|
||||
|
@ -48,15 +48,15 @@ public:
|
|||
|
||||
jsipc::CPOWManager* GetCPOWManager() override;
|
||||
|
||||
virtual ContentParentId ChildID() override
|
||||
virtual ContentParentId ChildID() const override
|
||||
{
|
||||
return mChildID;
|
||||
}
|
||||
virtual bool IsForApp() override
|
||||
virtual bool IsForApp() const override
|
||||
{
|
||||
return mIsForApp;
|
||||
}
|
||||
virtual bool IsForBrowser() override
|
||||
virtual bool IsForBrowser() const override
|
||||
{
|
||||
return mIsForBrowser;
|
||||
}
|
||||
|
@ -68,27 +68,32 @@ protected:
|
|||
{
|
||||
mChildID = aId;
|
||||
}
|
||||
|
||||
void SetIsForApp(bool aIsForApp)
|
||||
{
|
||||
mIsForApp = aIsForApp;
|
||||
}
|
||||
|
||||
void SetIsForBrowser(bool aIsForBrowser)
|
||||
{
|
||||
mIsForBrowser = aIsForBrowser;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual bool RecvSyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<StructuredCloneData>* aRetvals) override;
|
||||
virtual bool
|
||||
RecvSyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal,
|
||||
nsTArray<StructuredCloneData>* aRetvals) override;
|
||||
|
||||
virtual bool RecvAsyncMessage(const nsString& aMsg,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal) override;
|
||||
|
||||
virtual jsipc::PJavaScriptParent* AllocPJavaScriptParent() override;
|
||||
|
||||
virtual bool
|
||||
DeallocPJavaScriptParent(jsipc::PJavaScriptParent*) override;
|
||||
|
||||
|
@ -99,6 +104,7 @@ protected:
|
|||
const ContentParentId& aCpID,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) override;
|
||||
|
||||
virtual bool DeallocPBrowserParent(PBrowserParent*) override;
|
||||
|
||||
virtual PBlobParent*
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -20,26 +20,26 @@ namespace dom {
|
|||
*/
|
||||
class ContentProcess : public mozilla::ipc::ProcessChild
|
||||
{
|
||||
typedef mozilla::ipc::ProcessChild ProcessChild;
|
||||
typedef mozilla::ipc::ProcessChild ProcessChild;
|
||||
|
||||
public:
|
||||
explicit ContentProcess(ProcessId aParentPid)
|
||||
: ProcessChild(aParentPid)
|
||||
{ }
|
||||
explicit ContentProcess(ProcessId aParentPid)
|
||||
: ProcessChild(aParentPid)
|
||||
{ }
|
||||
|
||||
~ContentProcess()
|
||||
{ }
|
||||
~ContentProcess()
|
||||
{ }
|
||||
|
||||
virtual bool Init() override;
|
||||
virtual void CleanUp() override;
|
||||
virtual bool Init() override;
|
||||
virtual void CleanUp() override;
|
||||
|
||||
void SetAppDir(const nsACString& aPath);
|
||||
void SetAppDir(const nsACString& aPath);
|
||||
|
||||
private:
|
||||
ContentChild mContent;
|
||||
mozilla::ipc::ScopedXREEmbed mXREEmbed;
|
||||
ContentChild mContent;
|
||||
mozilla::ipc::ScopedXREEmbed mXREEmbed;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ContentProcess);
|
||||
DISALLOW_EVIL_CONSTRUCTORS(ContentProcess);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -74,8 +74,9 @@ public:
|
|||
/**
|
||||
* Allocate a tab id for the given content process's id.
|
||||
* Used when a content process wants to create a new tab. aOpenerTabId and
|
||||
* aContext are saved in RemoteFrameInfo, which is a part of ContentProcessInfo.
|
||||
* We can use the tab id and process id to locate the TabContext for future use.
|
||||
* aContext are saved in RemoteFrameInfo, which is a part of
|
||||
* ContentProcessInfo. We can use the tab id and process id to locate the
|
||||
* TabContext for future use.
|
||||
*/
|
||||
TabId AllocateTabId(const TabId& aOpenerTabId,
|
||||
const IPCTabContext& aContext,
|
||||
|
@ -162,4 +163,4 @@ private:
|
|||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
#endif // mozilla_dom_ContentProcessManager_h
|
||||
|
|
|
@ -11,18 +11,19 @@
|
|||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class CrashReporterChild :
|
||||
public PCrashReporterChild
|
||||
{
|
||||
public:
|
||||
CrashReporterChild() {
|
||||
MOZ_COUNT_CTOR(CrashReporterChild);
|
||||
}
|
||||
~CrashReporterChild() {
|
||||
MOZ_COUNT_DTOR(CrashReporterChild);
|
||||
}
|
||||
|
||||
static PCrashReporterChild* GetCrashReporter();
|
||||
class CrashReporterChild :
|
||||
public PCrashReporterChild
|
||||
{
|
||||
public:
|
||||
CrashReporterChild() {
|
||||
MOZ_COUNT_CTOR(CrashReporterChild);
|
||||
}
|
||||
~CrashReporterChild() {
|
||||
MOZ_COUNT_DTOR(CrashReporterChild);
|
||||
}
|
||||
|
||||
static PCrashReporterChild* GetCrashReporter();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -26,7 +26,7 @@ CrashReporterParent::AnnotateCrashReport(const nsCString& key,
|
|||
const nsCString& data)
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
mNotes.Put(key, data);
|
||||
mNotes.Put(key, data);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,8 @@ CrashReporterParent::ActorDestroy(ActorDestroyReason aWhy)
|
|||
bool
|
||||
CrashReporterParent::RecvAppendAppNotes(const nsCString& data)
|
||||
{
|
||||
mAppNotes.Append(data);
|
||||
return true;
|
||||
mAppNotes.Append(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IProtocol*
|
||||
|
@ -48,186 +48,188 @@ CrashReporterParent::CloneProtocol(Channel* aChannel,
|
|||
mozilla::ipc::ProtocolCloneContext* aCtx)
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
ContentParent* contentParent = aCtx->GetContentParent();
|
||||
CrashReporter::ThreadId childThreadId = contentParent->Pid();
|
||||
GeckoProcessType childProcessType =
|
||||
contentParent->Process()->GetProcessType();
|
||||
ContentParent* contentParent = aCtx->GetContentParent();
|
||||
CrashReporter::ThreadId childThreadId = contentParent->Pid();
|
||||
GeckoProcessType childProcessType =
|
||||
contentParent->Process()->GetProcessType();
|
||||
|
||||
nsAutoPtr<PCrashReporterParent> actor(
|
||||
contentParent->AllocPCrashReporterParent(childThreadId,
|
||||
childProcessType)
|
||||
);
|
||||
if (!actor ||
|
||||
!contentParent->RecvPCrashReporterConstructor(actor,
|
||||
childThreadId,
|
||||
childThreadId)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return actor.forget();
|
||||
#else
|
||||
MOZ_CRASH("Not Implemented");
|
||||
nsAutoPtr<PCrashReporterParent> actor(
|
||||
contentParent->AllocPCrashReporterParent(childThreadId,
|
||||
childProcessType)
|
||||
);
|
||||
if (!actor ||
|
||||
!contentParent->RecvPCrashReporterConstructor(actor,
|
||||
childThreadId,
|
||||
childThreadId)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return actor.forget();
|
||||
#else
|
||||
MOZ_CRASH("Not Implemented");
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
CrashReporterParent::CrashReporterParent()
|
||||
:
|
||||
:
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
mNotes(4),
|
||||
mNotes(4),
|
||||
#endif
|
||||
mStartTime(::time(nullptr))
|
||||
, mInitialized(false)
|
||||
mStartTime(::time(nullptr))
|
||||
, mInitialized(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(CrashReporterParent);
|
||||
MOZ_COUNT_CTOR(CrashReporterParent);
|
||||
}
|
||||
|
||||
CrashReporterParent::~CrashReporterParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(CrashReporterParent);
|
||||
MOZ_COUNT_DTOR(CrashReporterParent);
|
||||
}
|
||||
|
||||
void
|
||||
CrashReporterParent::SetChildData(const NativeThreadId& tid,
|
||||
const uint32_t& processType)
|
||||
{
|
||||
mInitialized = true;
|
||||
mMainThread = tid;
|
||||
mProcessType = processType;
|
||||
mInitialized = true;
|
||||
mMainThread = tid;
|
||||
mProcessType = processType;
|
||||
}
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
bool
|
||||
CrashReporterParent::GenerateCrashReportForMinidump(nsIFile* minidump,
|
||||
const AnnotationTable* processNotes)
|
||||
const AnnotationTable* processNotes)
|
||||
{
|
||||
if (!CrashReporter::GetIDFromMinidump(minidump, mChildDumpID))
|
||||
return false;
|
||||
bool result = GenerateChildData(processNotes);
|
||||
FinalizeChildData();
|
||||
return result;
|
||||
if (!CrashReporter::GetIDFromMinidump(minidump, mChildDumpID)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = GenerateChildData(processNotes);
|
||||
FinalizeChildData();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
CrashReporterParent::GenerateChildData(const AnnotationTable* processNotes)
|
||||
{
|
||||
MOZ_ASSERT(mInitialized);
|
||||
MOZ_ASSERT(mInitialized);
|
||||
|
||||
if (mChildDumpID.IsEmpty()) {
|
||||
NS_WARNING("problem with GenerateChildData: no child dump id yet!");
|
||||
return false;
|
||||
}
|
||||
if (mChildDumpID.IsEmpty()) {
|
||||
NS_WARNING("problem with GenerateChildData: no child dump id yet!");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoCString type;
|
||||
switch (mProcessType) {
|
||||
case GeckoProcessType_Content:
|
||||
type = NS_LITERAL_CSTRING("content");
|
||||
break;
|
||||
case GeckoProcessType_Plugin:
|
||||
case GeckoProcessType_GMPlugin:
|
||||
type = NS_LITERAL_CSTRING("plugin");
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("unknown process type");
|
||||
break;
|
||||
}
|
||||
mNotes.Put(NS_LITERAL_CSTRING("ProcessType"), type);
|
||||
nsAutoCString type;
|
||||
switch (mProcessType) {
|
||||
case GeckoProcessType_Content:
|
||||
type = NS_LITERAL_CSTRING("content");
|
||||
break;
|
||||
case GeckoProcessType_Plugin:
|
||||
case GeckoProcessType_GMPlugin:
|
||||
type = NS_LITERAL_CSTRING("plugin");
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("unknown process type");
|
||||
break;
|
||||
}
|
||||
mNotes.Put(NS_LITERAL_CSTRING("ProcessType"), type);
|
||||
|
||||
char startTime[32];
|
||||
snprintf_literal(startTime, "%lld", static_cast<long long>(mStartTime));
|
||||
mNotes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime));
|
||||
char startTime[32];
|
||||
snprintf_literal(startTime, "%lld", static_cast<long long>(mStartTime));
|
||||
mNotes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime));
|
||||
|
||||
if (!mAppNotes.IsEmpty()) {
|
||||
mNotes.Put(NS_LITERAL_CSTRING("Notes"), mAppNotes);
|
||||
}
|
||||
if (!mAppNotes.IsEmpty()) {
|
||||
mNotes.Put(NS_LITERAL_CSTRING("Notes"), mAppNotes);
|
||||
}
|
||||
|
||||
// Append these notes to the end of the extra file based on the current
|
||||
// dump id we obtained from CreatePairedMinidumps.
|
||||
bool ret = CrashReporter::AppendExtraData(mChildDumpID, mNotes);
|
||||
if (ret && processNotes) {
|
||||
ret = CrashReporter::AppendExtraData(mChildDumpID, *processNotes);
|
||||
}
|
||||
// Append these notes to the end of the extra file based on the current
|
||||
// dump id we obtained from CreatePairedMinidumps.
|
||||
bool ret = CrashReporter::AppendExtraData(mChildDumpID, mNotes);
|
||||
if (ret && processNotes) {
|
||||
ret = CrashReporter::AppendExtraData(mChildDumpID, *processNotes);
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
NS_WARNING("problem appending child data to .extra");
|
||||
}
|
||||
return ret;
|
||||
if (!ret) {
|
||||
NS_WARNING("problem appending child data to .extra");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
CrashReporterParent::FinalizeChildData()
|
||||
{
|
||||
MOZ_ASSERT(mInitialized);
|
||||
MOZ_ASSERT(mInitialized);
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
// Inline, this is the main thread. Get this done.
|
||||
NotifyCrashService();
|
||||
return;
|
||||
if (NS_IsMainThread()) {
|
||||
// Inline, this is the main thread. Get this done.
|
||||
NotifyCrashService();
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
class NotifyOnMainThread : public nsRunnable
|
||||
{
|
||||
public:
|
||||
explicit NotifyOnMainThread(CrashReporterParent* aCR)
|
||||
: mCR(aCR)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
mCR->NotifyCrashService();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
|
||||
class NotifyOnMainThread : public nsRunnable
|
||||
{
|
||||
public:
|
||||
explicit NotifyOnMainThread(CrashReporterParent* aCR)
|
||||
: mCR(aCR)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
mCR->NotifyCrashService();
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
CrashReporterParent* mCR;
|
||||
};
|
||||
SyncRunnable::DispatchToThread(mainThread, new NotifyOnMainThread(this));
|
||||
private:
|
||||
CrashReporterParent* mCR;
|
||||
};
|
||||
SyncRunnable::DispatchToThread(mainThread, new NotifyOnMainThread(this));
|
||||
}
|
||||
|
||||
void
|
||||
CrashReporterParent::NotifyCrashService()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mChildDumpID.IsEmpty());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!mChildDumpID.IsEmpty());
|
||||
|
||||
nsCOMPtr<nsICrashService> crashService =
|
||||
do_GetService("@mozilla.org/crashservice;1");
|
||||
if (!crashService) {
|
||||
return;
|
||||
nsCOMPtr<nsICrashService> crashService =
|
||||
do_GetService("@mozilla.org/crashservice;1");
|
||||
if (!crashService) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t processType;
|
||||
int32_t crashType = nsICrashService::CRASH_TYPE_CRASH;
|
||||
|
||||
nsCString telemetryKey;
|
||||
|
||||
switch (mProcessType) {
|
||||
case GeckoProcessType_Content:
|
||||
processType = nsICrashService::PROCESS_TYPE_CONTENT;
|
||||
telemetryKey.AssignLiteral("content");
|
||||
break;
|
||||
case GeckoProcessType_Plugin: {
|
||||
processType = nsICrashService::PROCESS_TYPE_PLUGIN;
|
||||
telemetryKey.AssignLiteral("plugin");
|
||||
nsAutoCString val;
|
||||
if (mNotes.Get(NS_LITERAL_CSTRING("PluginHang"), &val) &&
|
||||
val.Equals(NS_LITERAL_CSTRING("1"))) {
|
||||
crashType = nsICrashService::CRASH_TYPE_HANG;
|
||||
telemetryKey.AssignLiteral("pluginhang");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GeckoProcessType_GMPlugin:
|
||||
processType = nsICrashService::PROCESS_TYPE_GMPLUGIN;
|
||||
telemetryKey.AssignLiteral("gmplugin");
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("unknown process type");
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t processType;
|
||||
int32_t crashType = nsICrashService::CRASH_TYPE_CRASH;
|
||||
|
||||
nsCString telemetryKey;
|
||||
|
||||
switch (mProcessType) {
|
||||
case GeckoProcessType_Content:
|
||||
processType = nsICrashService::PROCESS_TYPE_CONTENT;
|
||||
telemetryKey.AssignLiteral("content");
|
||||
break;
|
||||
case GeckoProcessType_Plugin: {
|
||||
processType = nsICrashService::PROCESS_TYPE_PLUGIN;
|
||||
telemetryKey.AssignLiteral("plugin");
|
||||
nsAutoCString val;
|
||||
if (mNotes.Get(NS_LITERAL_CSTRING("PluginHang"), &val) &&
|
||||
val.Equals(NS_LITERAL_CSTRING("1"))) {
|
||||
crashType = nsICrashService::CRASH_TYPE_HANG;
|
||||
telemetryKey.AssignLiteral("pluginhang");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GeckoProcessType_GMPlugin:
|
||||
processType = nsICrashService::PROCESS_TYPE_GMPLUGIN;
|
||||
telemetryKey.AssignLiteral("gmplugin");
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("unknown process type");
|
||||
return;
|
||||
}
|
||||
|
||||
crashService->AddCrash(processType, crashType, mChildDumpID);
|
||||
Telemetry::Accumulate(Telemetry::SUBPROCESS_CRASHES_WITH_DUMP, telemetryKey, 1);
|
||||
mNotes.Clear();
|
||||
crashService->AddCrash(processType, crashType, mChildDumpID);
|
||||
Telemetry::Accumulate(Telemetry::SUBPROCESS_CRASHES_WITH_DUMP, telemetryKey, 1);
|
||||
mNotes.Clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class CrashReporterParent :
|
||||
public PCrashReporterParent
|
||||
class CrashReporterParent : public PCrashReporterParent
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
typedef CrashReporter::AnnotationTable AnnotationTable;
|
||||
|
@ -137,7 +136,7 @@ public:
|
|||
* Returns the ID of the child minidump.
|
||||
* GeneratePairedMinidump or GenerateCrashReport must be called first.
|
||||
*/
|
||||
const nsString& ChildDumpID() {
|
||||
const nsString& ChildDumpID() const {
|
||||
return mChildDumpID;
|
||||
}
|
||||
|
||||
|
@ -147,18 +146,20 @@ public:
|
|||
* the notes will get dropped.
|
||||
*/
|
||||
void
|
||||
AnnotateCrashReport(const nsCString& key, const nsCString& data);
|
||||
AnnotateCrashReport(const nsCString& aKey, const nsCString& aData);
|
||||
|
||||
protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
virtual bool
|
||||
RecvAnnotateCrashReport(const nsCString& key, const nsCString& data) override {
|
||||
AnnotateCrashReport(key, data);
|
||||
virtual bool RecvAnnotateCrashReport(const nsCString& aKey,
|
||||
const nsCString& aData) override
|
||||
{
|
||||
AnnotateCrashReport(aKey, aData);
|
||||
return true;
|
||||
}
|
||||
virtual bool
|
||||
RecvAppendAppNotes(const nsCString& data) override;
|
||||
|
||||
virtual bool RecvAppendAppNotes(const nsCString& aData) override;
|
||||
|
||||
virtual mozilla::ipc::IProtocol*
|
||||
CloneProtocol(Channel* aChannel,
|
||||
mozilla::ipc::ProtocolCloneContext *aCtx) override;
|
||||
|
@ -217,7 +218,8 @@ CrashReporterParent::GenerateMinidumpAndPair(Toplevel* aTopLevel,
|
|||
#ifdef XP_MACOSX
|
||||
childHandle = aTopLevel->Process()->GetChildTask();
|
||||
#else
|
||||
if (!base::OpenPrivilegedProcessHandle(aTopLevel->OtherPid(), &childHandle.rwget())) {
|
||||
if (!base::OpenPrivilegedProcessHandle(aTopLevel->OtherPid(),
|
||||
&childHandle.rwget())) {
|
||||
NS_WARNING("Failed to open child process handle.");
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -68,7 +68,8 @@ class FilePickerParent : public PFilePickerParent
|
|||
nsCOMPtr<nsIEventTarget> mEventTarget;
|
||||
|
||||
public:
|
||||
FileSizeAndDateRunnable(FilePickerParent *aFPParent, nsTArray<RefPtr<BlobImpl>>& aBlobs);
|
||||
FileSizeAndDateRunnable(FilePickerParent *aFPParent,
|
||||
nsTArray<RefPtr<BlobImpl>>& aBlobs);
|
||||
bool Dispatch();
|
||||
NS_IMETHOD Run();
|
||||
void Destroy();
|
||||
|
@ -86,4 +87,4 @@ class FilePickerParent : public PFilePickerParent
|
|||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
#endif // mozilla_dom_FilePickerParent_h
|
||||
|
|
|
@ -22,7 +22,6 @@ class TabParent;
|
|||
template<typename T>
|
||||
class IdType
|
||||
{
|
||||
|
||||
friend struct IPC::ParamTraits<IdType<T>>;
|
||||
|
||||
public:
|
||||
|
@ -71,4 +70,4 @@ struct ParamTraits<mozilla::dom::IdType<T>>
|
|||
|
||||
} // namespace IPC
|
||||
|
||||
#endif
|
||||
#endif // mozilla_dom_IdType_h
|
||||
|
|
|
@ -30,5 +30,4 @@ private:
|
|||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
#endif // mozilla_dom_NuwaChild_h
|
||||
|
|
|
@ -70,4 +70,4 @@ private:
|
|||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
#endif // mozilla_dom_NuwaParent_h
|
||||
|
|
|
@ -13,12 +13,19 @@
|
|||
|
||||
namespace IPC {
|
||||
|
||||
class Principal {
|
||||
class Principal
|
||||
{
|
||||
friend struct ParamTraits<Principal>;
|
||||
|
||||
public:
|
||||
Principal() : mPrincipal(nullptr) {}
|
||||
explicit Principal(nsIPrincipal* aPrincipal) : mPrincipal(aPrincipal) {}
|
||||
Principal()
|
||||
: mPrincipal(nullptr)
|
||||
{}
|
||||
|
||||
explicit Principal(nsIPrincipal* aPrincipal)
|
||||
: mPrincipal(aPrincipal)
|
||||
{}
|
||||
|
||||
operator nsIPrincipal*() const { return mPrincipal.get(); }
|
||||
|
||||
private:
|
||||
|
|
|
@ -344,7 +344,6 @@ public:
|
|||
private:
|
||||
static uint32_t sBackgroundPerceivableGracePeriodMS;
|
||||
static uint32_t sBackgroundGracePeriodMS;
|
||||
static uint32_t sMemoryPressureGracePeriodMS;
|
||||
|
||||
void FireTestOnlyObserverNotification(
|
||||
const char* aTopic,
|
||||
|
@ -369,7 +368,6 @@ private:
|
|||
nsAutoCString mNameWithComma;
|
||||
|
||||
nsCOMPtr<nsITimer> mResetPriorityTimer;
|
||||
nsCOMPtr<nsITimer> mMemoryPressureTimer;
|
||||
};
|
||||
|
||||
/* static */ bool ProcessPriorityManagerImpl::sInitialized = false;
|
||||
|
@ -382,7 +380,6 @@ private:
|
|||
ProcessPriorityManagerImpl::sSingleton;
|
||||
/* static */ uint32_t ParticularProcessPriorityManager::sBackgroundPerceivableGracePeriodMS = 0;
|
||||
/* static */ uint32_t ParticularProcessPriorityManager::sBackgroundGracePeriodMS = 0;
|
||||
/* static */ uint32_t ParticularProcessPriorityManager::sMemoryPressureGracePeriodMS = 0;
|
||||
|
||||
NS_IMPL_ISUPPORTS(ProcessPriorityManagerImpl,
|
||||
nsIObserver,
|
||||
|
@ -702,8 +699,6 @@ ParticularProcessPriorityManager::StaticInit()
|
|||
"dom.ipc.processPriorityManager.backgroundPerceivableGracePeriodMS");
|
||||
Preferences::AddUintVarCache(&sBackgroundGracePeriodMS,
|
||||
"dom.ipc.processPriorityManager.backgroundGracePeriodMS");
|
||||
Preferences::AddUintVarCache(&sMemoryPressureGracePeriodMS,
|
||||
"dom.ipc.processPriorityManager.memoryPressureGracePeriodMS");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1010,28 +1005,17 @@ ParticularProcessPriorityManager::ScheduleResetPriority(TimeoutPref aTimeoutPref
|
|||
}
|
||||
|
||||
LOGP("Scheduling reset timer to fire in %dms.", timeout);
|
||||
mResetPriorityTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
mResetPriorityTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
mResetPriorityTimer->InitWithCallback(this, timeout, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ParticularProcessPriorityManager::Notify(nsITimer* aTimer)
|
||||
{
|
||||
if (mResetPriorityTimer == aTimer) {
|
||||
LOGP("Reset priority timer callback; about to ResetPriorityNow.");
|
||||
ResetPriorityNow();
|
||||
mResetPriorityTimer = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mContentParent && mMemoryPressureTimer == aTimer) {
|
||||
Unused << mContentParent->SendFlushMemory(NS_LITERAL_STRING("lowering-priority"));
|
||||
mMemoryPressureTimer = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_WARNING("Unexpected timer!");
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
LOGP("Reset priority timer callback; about to ResetPriorityNow.");
|
||||
ResetPriorityNow();
|
||||
mResetPriorityTimer = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1156,18 +1140,6 @@ ParticularProcessPriorityManager::SetPriorityNow(ProcessPriority aPriority,
|
|||
NotifyProcessPriorityChanged(this, oldPriority);
|
||||
|
||||
Unused << mContentParent->SendNotifyProcessPriorityChanged(mPriority);
|
||||
|
||||
if (mMemoryPressureTimer) {
|
||||
mMemoryPressureTimer->Cancel();
|
||||
mMemoryPressureTimer = nullptr;
|
||||
}
|
||||
|
||||
if (aPriority < PROCESS_PRIORITY_FOREGROUND) {
|
||||
mMemoryPressureTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
mMemoryPressureTimer->InitWithCallback(this,
|
||||
sMemoryPressureGracePeriodMS,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
}
|
||||
|
||||
FireTestOnlyObserverNotification("process-priority-set",
|
||||
|
|
|
@ -1210,7 +1210,7 @@ TabChild::SetProcessNameToAppName()
|
|||
}
|
||||
|
||||
bool
|
||||
TabChild::IsRootContentDocument()
|
||||
TabChild::IsRootContentDocument() const
|
||||
{
|
||||
// A TabChild is a "root content document" if it's
|
||||
//
|
||||
|
|
|
@ -162,56 +162,56 @@ protected:
|
|||
TabChild* mTabChild;
|
||||
};
|
||||
|
||||
// This is base clase which helps to share Viewport and touch related functionality
|
||||
// between b2g/android FF/embedlite clients implementation.
|
||||
// It make sense to place in this class all helper functions, and functionality which could be shared between
|
||||
// Cross-process/Cross-thread implmentations.
|
||||
// This is base clase which helps to share Viewport and touch related
|
||||
// functionality between b2g/android FF/embedlite clients implementation.
|
||||
// It make sense to place in this class all helper functions, and functionality
|
||||
// which could be shared between Cross-process/Cross-thread implmentations.
|
||||
class TabChildBase : public nsISupports,
|
||||
public nsMessageManagerScriptExecutor,
|
||||
public ipc::MessageManagerCallback
|
||||
{
|
||||
protected:
|
||||
typedef mozilla::widget::PuppetWidget PuppetWidget;
|
||||
typedef mozilla::widget::PuppetWidget PuppetWidget;
|
||||
|
||||
public:
|
||||
TabChildBase();
|
||||
TabChildBase();
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TabChildBase)
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TabChildBase)
|
||||
|
||||
virtual nsIWebNavigation* WebNavigation() const = 0;
|
||||
virtual PuppetWidget* WebWidget() = 0;
|
||||
nsIPrincipal* GetPrincipal() { return mPrincipal; }
|
||||
virtual bool DoUpdateZoomConstraints(const uint32_t& aPresShellId,
|
||||
const mozilla::layers::FrameMetrics::ViewID& aViewId,
|
||||
const Maybe<mozilla::layers::ZoomConstraints>& aConstraints) = 0;
|
||||
virtual nsIWebNavigation* WebNavigation() const = 0;
|
||||
virtual PuppetWidget* WebWidget() = 0;
|
||||
nsIPrincipal* GetPrincipal() { return mPrincipal; }
|
||||
virtual bool DoUpdateZoomConstraints(const uint32_t& aPresShellId,
|
||||
const mozilla::layers::FrameMetrics::ViewID& aViewId,
|
||||
const Maybe<mozilla::layers::ZoomConstraints>& aConstraints) = 0;
|
||||
|
||||
virtual ScreenIntSize GetInnerSize() = 0;
|
||||
virtual ScreenIntSize GetInnerSize() = 0;
|
||||
|
||||
// Get the Document for the top-level window in this tab.
|
||||
already_AddRefed<nsIDocument> GetDocument() const;
|
||||
// Get the Document for the top-level window in this tab.
|
||||
already_AddRefed<nsIDocument> GetDocument() const;
|
||||
|
||||
protected:
|
||||
virtual ~TabChildBase();
|
||||
virtual ~TabChildBase();
|
||||
|
||||
// Get the pres-shell of the document for the top-level window in this tab.
|
||||
already_AddRefed<nsIPresShell> GetPresShell() const;
|
||||
// Get the pres-shell of the document for the top-level window in this tab.
|
||||
already_AddRefed<nsIPresShell> GetPresShell() const;
|
||||
|
||||
// Wraps up a JSON object as a structured clone and sends it to the browser
|
||||
// chrome script.
|
||||
//
|
||||
// XXX/bug 780335: Do the work the browser chrome script does in C++ instead
|
||||
// so we don't need things like this.
|
||||
void DispatchMessageManagerMessage(const nsAString& aMessageName,
|
||||
const nsAString& aJSONData);
|
||||
// Wraps up a JSON object as a structured clone and sends it to the browser
|
||||
// chrome script.
|
||||
//
|
||||
// XXX/bug 780335: Do the work the browser chrome script does in C++ instead
|
||||
// so we don't need things like this.
|
||||
void DispatchMessageManagerMessage(const nsAString& aMessageName,
|
||||
const nsAString& aJSONData);
|
||||
|
||||
void ProcessUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
|
||||
void ProcessUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
|
||||
|
||||
bool UpdateFrameHandler(const mozilla::layers::FrameMetrics& aFrameMetrics);
|
||||
bool UpdateFrameHandler(const mozilla::layers::FrameMetrics& aFrameMetrics);
|
||||
|
||||
protected:
|
||||
RefPtr<TabChildGlobal> mTabChildGlobal;
|
||||
nsCOMPtr<nsIWebBrowserChrome3> mWebBrowserChrome;
|
||||
RefPtr<TabChildGlobal> mTabChildGlobal;
|
||||
nsCOMPtr<nsIWebBrowserChrome3> mWebBrowserChrome;
|
||||
};
|
||||
|
||||
class TabChild final : public TabChildBase,
|
||||
|
@ -227,415 +227,499 @@ class TabChild final : public TabChildBase,
|
|||
public TabContext,
|
||||
public nsITooltipListener
|
||||
{
|
||||
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
|
||||
typedef mozilla::layout::RenderFrameChild RenderFrameChild;
|
||||
typedef mozilla::layers::APZEventState APZEventState;
|
||||
typedef mozilla::layers::SetAllowedTouchBehaviorCallback SetAllowedTouchBehaviorCallback;
|
||||
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
|
||||
typedef mozilla::layout::RenderFrameChild RenderFrameChild;
|
||||
typedef mozilla::layers::APZEventState APZEventState;
|
||||
typedef mozilla::layers::SetAllowedTouchBehaviorCallback SetAllowedTouchBehaviorCallback;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Find TabChild of aTabId in the same content process of the
|
||||
* caller.
|
||||
*/
|
||||
static already_AddRefed<TabChild> FindTabChild(const TabId& aTabId);
|
||||
/**
|
||||
* Find TabChild of aTabId in the same content process of the
|
||||
* caller.
|
||||
*/
|
||||
static already_AddRefed<TabChild> FindTabChild(const TabId& aTabId);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create a new TabChild object.
|
||||
*/
|
||||
TabChild(nsIContentChild* aManager,
|
||||
const TabId& aTabId,
|
||||
const TabContext& aContext,
|
||||
uint32_t aChromeFlags);
|
||||
/**
|
||||
* Create a new TabChild object.
|
||||
*/
|
||||
TabChild(nsIContentChild* aManager,
|
||||
const TabId& aTabId,
|
||||
const TabContext& aContext,
|
||||
uint32_t aChromeFlags);
|
||||
|
||||
nsresult Init();
|
||||
nsresult Init();
|
||||
|
||||
/**
|
||||
* This is expected to be called off the critical path to content
|
||||
* startup. This is an opportunity to load things that are slow
|
||||
* on the critical path.
|
||||
*/
|
||||
static void PreloadSlowThings();
|
||||
/**
|
||||
* This is expected to be called off the critical path to content
|
||||
* startup. This is an opportunity to load things that are slow
|
||||
* on the critical path.
|
||||
*/
|
||||
static void PreloadSlowThings();
|
||||
|
||||
/** Return a TabChild with the given attributes. */
|
||||
static already_AddRefed<TabChild>
|
||||
Create(nsIContentChild* aManager, const TabId& aTabId, const TabContext& aContext, uint32_t aChromeFlags);
|
||||
/** Return a TabChild with the given attributes. */
|
||||
static already_AddRefed<TabChild>
|
||||
Create(nsIContentChild* aManager, const TabId& aTabId,
|
||||
const TabContext& aContext, uint32_t aChromeFlags);
|
||||
|
||||
bool IsRootContentDocument();
|
||||
// Let managees query if it is safe to send messages.
|
||||
bool IsDestroyed() { return mDestroyed; }
|
||||
const TabId GetTabId() const {
|
||||
MOZ_ASSERT(mUniqueId != 0);
|
||||
return mUniqueId;
|
||||
}
|
||||
bool IsRootContentDocument() const;
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIWEBBROWSERCHROME
|
||||
NS_DECL_NSIWEBBROWSERCHROME2
|
||||
NS_DECL_NSIEMBEDDINGSITEWINDOW
|
||||
NS_DECL_NSIWEBBROWSERCHROMEFOCUS
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSIWINDOWPROVIDER
|
||||
NS_DECL_NSITABCHILD
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSITOOLTIPLISTENER
|
||||
// Let managees query if it is safe to send messages.
|
||||
bool IsDestroyed() const{ return mDestroyed; }
|
||||
|
||||
/**
|
||||
* MessageManagerCallback methods that we override.
|
||||
*/
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync) override;
|
||||
virtual nsresult DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
virtual bool DoUpdateZoomConstraints(const uint32_t& aPresShellId,
|
||||
const ViewID& aViewId,
|
||||
const Maybe<ZoomConstraints>& aConstraints) override;
|
||||
virtual bool RecvLoadURL(const nsCString& aURI,
|
||||
const BrowserConfiguration& aConfiguration,
|
||||
const ShowInfo& aInfo) override;
|
||||
virtual bool RecvOpenURI(const URIParams& aURI,
|
||||
const uint32_t& aFlags) override;
|
||||
virtual bool RecvCacheFileDescriptor(const nsString& aPath,
|
||||
const FileDescriptor& aFileDescriptor)
|
||||
override;
|
||||
virtual bool RecvShow(const ScreenIntSize& aSize,
|
||||
const ShowInfo& aInfo,
|
||||
const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
||||
const uint64_t& aLayersId,
|
||||
PRenderFrameChild* aRenderFrame,
|
||||
const bool& aParentIsActive) override;
|
||||
virtual bool RecvUpdateDimensions(const CSSRect& rect,
|
||||
const CSSSize& size,
|
||||
const nsSizeMode& sizeMode,
|
||||
const ScreenOrientationInternal& orientation,
|
||||
const LayoutDeviceIntPoint& chromeDisp) override;
|
||||
virtual bool RecvUpdateFrame(const layers::FrameMetrics& aFrameMetrics) override;
|
||||
virtual bool RecvRequestFlingSnap(const ViewID& aScrollId,
|
||||
const CSSPoint& aDestination) override;
|
||||
virtual bool RecvAcknowledgeScrollUpdate(const ViewID& aScrollId,
|
||||
const uint32_t& aScrollGeneration) override;
|
||||
virtual bool RecvHandleDoubleTap(const CSSPoint& aPoint,
|
||||
const Modifiers& aModifiers,
|
||||
const mozilla::layers::ScrollableLayerGuid& aGuid) override;
|
||||
virtual bool RecvHandleSingleTap(const CSSPoint& aPoint,
|
||||
const Modifiers& aModifiers,
|
||||
const mozilla::layers::ScrollableLayerGuid& aGuid) override;
|
||||
virtual bool RecvHandleLongTap(const CSSPoint& aPoint,
|
||||
const Modifiers& aModifiers,
|
||||
const mozilla::layers::ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
virtual bool RecvNotifyAPZStateChange(const ViewID& aViewId,
|
||||
const APZStateChange& aChange,
|
||||
const int& aArg) override;
|
||||
virtual bool RecvNotifyFlushComplete() override;
|
||||
virtual bool RecvActivate() override;
|
||||
virtual bool RecvDeactivate() override;
|
||||
virtual bool RecvMouseEvent(const nsString& aType,
|
||||
const float& aX,
|
||||
const float& aY,
|
||||
const int32_t& aButton,
|
||||
const int32_t& aClickCount,
|
||||
const int32_t& aModifiers,
|
||||
const bool& aIgnoreRootScrollFrame) override;
|
||||
virtual bool RecvRealMouseMoveEvent(const mozilla::WidgetMouseEvent& event,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
virtual bool RecvSynthMouseMoveEvent(const mozilla::WidgetMouseEvent& event,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
virtual bool RecvRealMouseButtonEvent(const mozilla::WidgetMouseEvent& event,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
virtual bool RecvRealDragEvent(const WidgetDragEvent& aEvent,
|
||||
const uint32_t& aDragAction,
|
||||
const uint32_t& aDropEffect) override;
|
||||
virtual bool RecvRealKeyEvent(const mozilla::WidgetKeyboardEvent& event,
|
||||
const MaybeNativeKeyBinding& aBindings) override;
|
||||
virtual bool RecvMouseWheelEvent(const mozilla::WidgetWheelEvent& event,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
virtual bool RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsEventStatus& aApzResponse) override;
|
||||
virtual bool RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsEventStatus& aApzResponse) override;
|
||||
virtual bool RecvKeyEvent(const nsString& aType,
|
||||
const int32_t& aKeyCode,
|
||||
const int32_t& aCharCode,
|
||||
const int32_t& aModifiers,
|
||||
const bool& aPreventDefault) override;
|
||||
virtual bool RecvMouseScrollTestEvent(const FrameMetrics::ViewID& aScrollId,
|
||||
const nsString& aEvent) override;
|
||||
virtual bool RecvNativeSynthesisResponse(const uint64_t& aObserverId,
|
||||
const nsCString& aResponse) override;
|
||||
virtual bool RecvPluginEvent(const WidgetPluginEvent& aEvent) override;
|
||||
virtual bool RecvCompositionEvent(const mozilla::WidgetCompositionEvent& event) override;
|
||||
virtual bool RecvSelectionEvent(const mozilla::WidgetSelectionEvent& event) override;
|
||||
virtual bool RecvActivateFrameEvent(const nsString& aType, const bool& capture) override;
|
||||
virtual bool RecvLoadRemoteScript(const nsString& aURL,
|
||||
const bool& aRunInGlobalScope) override;
|
||||
virtual bool RecvAsyncMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal) override;
|
||||
const TabId GetTabId() const
|
||||
{
|
||||
MOZ_ASSERT(mUniqueId != 0);
|
||||
return mUniqueId;
|
||||
}
|
||||
|
||||
virtual bool RecvAppOfflineStatus(const uint32_t& aId, const bool& aOffline) override;
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIWEBBROWSERCHROME
|
||||
NS_DECL_NSIWEBBROWSERCHROME2
|
||||
NS_DECL_NSIEMBEDDINGSITEWINDOW
|
||||
NS_DECL_NSIWEBBROWSERCHROMEFOCUS
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSIWINDOWPROVIDER
|
||||
NS_DECL_NSITABCHILD
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSITOOLTIPLISTENER
|
||||
|
||||
virtual bool RecvSwappedWithOtherRemoteLoader() override;
|
||||
/**
|
||||
* MessageManagerCallback methods that we override.
|
||||
*/
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync) override;
|
||||
|
||||
virtual PDocAccessibleChild* AllocPDocAccessibleChild(PDocAccessibleChild*,
|
||||
const uint64_t&)
|
||||
override;
|
||||
virtual bool DeallocPDocAccessibleChild(PDocAccessibleChild*) override;
|
||||
virtual PDocumentRendererChild*
|
||||
AllocPDocumentRendererChild(const nsRect& documentRect, const gfx::Matrix& transform,
|
||||
const nsString& bgcolor,
|
||||
const uint32_t& renderFlags, const bool& flushLayout,
|
||||
const nsIntSize& renderSize) override;
|
||||
virtual bool DeallocPDocumentRendererChild(PDocumentRendererChild* actor) override;
|
||||
virtual bool RecvPDocumentRendererConstructor(PDocumentRendererChild* actor,
|
||||
const nsRect& documentRect,
|
||||
const gfx::Matrix& transform,
|
||||
const nsString& bgcolor,
|
||||
const uint32_t& renderFlags,
|
||||
const bool& flushLayout,
|
||||
const nsIntSize& renderSize) override;
|
||||
virtual nsresult DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
|
||||
virtual PColorPickerChild*
|
||||
AllocPColorPickerChild(const nsString& title, const nsString& initialColor) override;
|
||||
virtual bool DeallocPColorPickerChild(PColorPickerChild* actor) override;
|
||||
virtual bool
|
||||
DoUpdateZoomConstraints(const uint32_t& aPresShellId,
|
||||
const ViewID& aViewId,
|
||||
const Maybe<ZoomConstraints>& aConstraints) override;
|
||||
|
||||
virtual PFilePickerChild*
|
||||
AllocPFilePickerChild(const nsString& aTitle, const int16_t& aMode) override;
|
||||
virtual bool
|
||||
DeallocPFilePickerChild(PFilePickerChild* actor) override;
|
||||
virtual bool RecvLoadURL(const nsCString& aURI,
|
||||
const BrowserConfiguration& aConfiguration,
|
||||
const ShowInfo& aInfo) override;
|
||||
|
||||
virtual PIndexedDBPermissionRequestChild*
|
||||
AllocPIndexedDBPermissionRequestChild(const Principal& aPrincipal)
|
||||
override;
|
||||
virtual bool RecvOpenURI(const URIParams& aURI,
|
||||
const uint32_t& aFlags) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPIndexedDBPermissionRequestChild(
|
||||
PIndexedDBPermissionRequestChild* aActor)
|
||||
virtual bool RecvCacheFileDescriptor(const nsString& aPath,
|
||||
const FileDescriptor& aFileDescriptor)
|
||||
override;
|
||||
|
||||
virtual nsIWebNavigation* WebNavigation() const override { return mWebNav; }
|
||||
virtual PuppetWidget* WebWidget() override { return mPuppetWidget; }
|
||||
virtual bool
|
||||
RecvShow(const ScreenIntSize& aSize,
|
||||
const ShowInfo& aInfo,
|
||||
const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
||||
const uint64_t& aLayersId,
|
||||
PRenderFrameChild* aRenderFrame,
|
||||
const bool& aParentIsActive) override;
|
||||
|
||||
/** Return the DPI of the widget this TabChild draws to. */
|
||||
void GetDPI(float* aDPI);
|
||||
void GetDefaultScale(double *aScale);
|
||||
virtual bool
|
||||
RecvUpdateDimensions(const CSSRect& aRect,
|
||||
const CSSSize& aSize,
|
||||
const nsSizeMode& aSizeMode,
|
||||
const ScreenOrientationInternal& aOrientation,
|
||||
const LayoutDeviceIntPoint& aChromeDisp) override;
|
||||
|
||||
void GetMaxTouchPoints(uint32_t* aTouchPoints);
|
||||
virtual bool
|
||||
RecvUpdateFrame(const layers::FrameMetrics& aFrameMetrics) override;
|
||||
|
||||
ScreenOrientationInternal GetOrientation() const { return mOrientation; }
|
||||
virtual bool
|
||||
RecvRequestFlingSnap(const ViewID& aScrollId,
|
||||
const CSSPoint& aDestination) override;
|
||||
|
||||
void SetBackgroundColor(const nscolor& aColor);
|
||||
virtual bool
|
||||
RecvAcknowledgeScrollUpdate(const ViewID& aScrollId,
|
||||
const uint32_t& aScrollGeneration) override;
|
||||
|
||||
void NotifyPainted();
|
||||
virtual bool
|
||||
RecvHandleDoubleTap(const CSSPoint& aPoint,
|
||||
const Modifiers& aModifiers,
|
||||
const mozilla::layers::ScrollableLayerGuid& aGuid) override;
|
||||
|
||||
void RequestNativeKeyBindings(mozilla::widget::AutoCacheNativeKeyCommands* aAutoCache,
|
||||
WidgetKeyboardEvent* aEvent);
|
||||
virtual bool
|
||||
RecvHandleSingleTap(const CSSPoint& aPoint,
|
||||
const Modifiers& aModifiers,
|
||||
const mozilla::layers::ScrollableLayerGuid& aGuid) override;
|
||||
|
||||
/**
|
||||
* Signal to this TabChild that it should be made visible:
|
||||
* activated widget, retained layer tree, etc. (Respectively,
|
||||
* made not visible.)
|
||||
*/
|
||||
void MakeVisible();
|
||||
void MakeHidden();
|
||||
virtual bool
|
||||
RecvHandleLongTap(const CSSPoint& aPoint,
|
||||
const Modifiers& aModifiers,
|
||||
const mozilla::layers::ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
|
||||
// Returns true if the file descriptor was found in the cache, false
|
||||
// otherwise.
|
||||
bool GetCachedFileDescriptor(const nsAString& aPath,
|
||||
nsICachedFileDescriptorListener* aCallback);
|
||||
virtual bool RecvNotifyAPZStateChange(const ViewID& aViewId,
|
||||
const APZStateChange& aChange,
|
||||
const int& aArg) override;
|
||||
|
||||
void CancelCachedFileDescriptorCallback(
|
||||
const nsAString& aPath,
|
||||
nsICachedFileDescriptorListener* aCallback);
|
||||
virtual bool RecvNotifyFlushComplete() override;
|
||||
|
||||
nsIContentChild* Manager() { return mManager; }
|
||||
virtual bool RecvActivate() override;
|
||||
|
||||
bool GetUpdateHitRegion() { return mUpdateHitRegion; }
|
||||
virtual bool RecvDeactivate() override;
|
||||
|
||||
void UpdateHitRegion(const nsRegion& aRegion);
|
||||
virtual bool RecvMouseEvent(const nsString& aType,
|
||||
const float& aX,
|
||||
const float& aY,
|
||||
const int32_t& aButton,
|
||||
const int32_t& aClickCount,
|
||||
const int32_t& aModifiers,
|
||||
const bool& aIgnoreRootScrollFrame) override;
|
||||
|
||||
static inline TabChild*
|
||||
GetFrom(nsIDocShell* aDocShell)
|
||||
{
|
||||
nsCOMPtr<nsITabChild> tc = do_GetInterface(aDocShell);
|
||||
return static_cast<TabChild*>(tc.get());
|
||||
}
|
||||
virtual bool RecvRealMouseMoveEvent(const mozilla::WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
|
||||
static TabChild* GetFrom(nsIPresShell* aPresShell);
|
||||
static TabChild* GetFrom(uint64_t aLayersId);
|
||||
virtual bool RecvSynthMouseMoveEvent(const mozilla::WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
|
||||
void DidComposite(uint64_t aTransactionId,
|
||||
const TimeStamp& aCompositeStart,
|
||||
const TimeStamp& aCompositeEnd);
|
||||
void DidRequestComposite(const TimeStamp& aCompositeReqStart,
|
||||
const TimeStamp& aCompositeReqEnd);
|
||||
virtual bool RecvRealMouseButtonEvent(const mozilla::WidgetMouseEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
|
||||
void ClearCachedResources();
|
||||
virtual bool RecvRealDragEvent(const WidgetDragEvent& aEvent,
|
||||
const uint32_t& aDragAction,
|
||||
const uint32_t& aDropEffect) override;
|
||||
|
||||
static inline TabChild*
|
||||
GetFrom(nsIDOMWindow* aWindow)
|
||||
{
|
||||
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(webNav);
|
||||
return GetFrom(docShell);
|
||||
}
|
||||
virtual bool
|
||||
RecvRealKeyEvent(const mozilla::WidgetKeyboardEvent& aEvent,
|
||||
const MaybeNativeKeyBinding& aBindings) override;
|
||||
|
||||
virtual bool RecvUIResolutionChanged(const float& aDpi, const double& aScale) override;
|
||||
virtual bool RecvMouseWheelEvent(const mozilla::WidgetWheelEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId) override;
|
||||
|
||||
virtual bool RecvThemeChanged(nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache) override;
|
||||
virtual bool RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsEventStatus& aApzResponse) override;
|
||||
|
||||
virtual bool RecvHandleAccessKey(nsTArray<uint32_t>&& aCharCodes,
|
||||
const bool& aIsTrusted,
|
||||
const int32_t& aModifierMask) override;
|
||||
virtual bool
|
||||
RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent,
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
const uint64_t& aInputBlockId,
|
||||
const nsEventStatus& aApzResponse) override;
|
||||
|
||||
virtual bool RecvAudioChannelChangeNotification(const uint32_t& aAudioChannel,
|
||||
const float& aVolume,
|
||||
const bool& aMuted) override;
|
||||
virtual bool RecvKeyEvent(const nsString& aType,
|
||||
const int32_t& aKeyCode,
|
||||
const int32_t& aCharCode,
|
||||
const int32_t& aModifiers,
|
||||
const bool& aPreventDefault) override;
|
||||
|
||||
/**
|
||||
* Native widget remoting protocol for use with windowed plugins with e10s.
|
||||
*/
|
||||
PPluginWidgetChild* AllocPPluginWidgetChild() override;
|
||||
bool DeallocPPluginWidgetChild(PPluginWidgetChild* aActor) override;
|
||||
nsresult CreatePluginWidget(nsIWidget* aParent, nsIWidget** aOut);
|
||||
virtual bool RecvMouseScrollTestEvent(const FrameMetrics::ViewID& aScrollId,
|
||||
const nsString& aEvent) override;
|
||||
|
||||
LayoutDeviceIntPoint GetChromeDisplacement() { return mChromeDisp; };
|
||||
virtual bool RecvNativeSynthesisResponse(const uint64_t& aObserverId,
|
||||
const nsCString& aResponse) override;
|
||||
|
||||
bool IPCOpen() { return mIPCOpen; }
|
||||
virtual bool RecvPluginEvent(const WidgetPluginEvent& aEvent) override;
|
||||
|
||||
bool ParentIsActive()
|
||||
{
|
||||
return mParentIsActive;
|
||||
}
|
||||
bool AsyncPanZoomEnabled() { return mAsyncPanZoomEnabled; }
|
||||
virtual bool
|
||||
RecvCompositionEvent(const mozilla::WidgetCompositionEvent& aEvent) override;
|
||||
|
||||
virtual ScreenIntSize GetInnerSize() override;
|
||||
virtual bool
|
||||
RecvSelectionEvent(const mozilla::WidgetSelectionEvent& aEvent) override;
|
||||
|
||||
// Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
|
||||
void DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
||||
const uint64_t& aLayersId,
|
||||
PRenderFrameChild* aRenderFrame,
|
||||
const ShowInfo& aShowInfo);
|
||||
virtual bool
|
||||
RecvActivateFrameEvent(const nsString& aType, const bool& aCapture) override;
|
||||
|
||||
virtual bool RecvLoadRemoteScript(const nsString& aURL,
|
||||
const bool& aRunInGlobalScope) override;
|
||||
|
||||
virtual bool RecvAsyncMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
const IPC::Principal& aPrincipal) override;
|
||||
|
||||
virtual bool RecvAppOfflineStatus(const uint32_t& aId,
|
||||
const bool& aOffline) override;
|
||||
|
||||
virtual bool RecvSwappedWithOtherRemoteLoader() override;
|
||||
|
||||
virtual PDocAccessibleChild*
|
||||
AllocPDocAccessibleChild(PDocAccessibleChild*, const uint64_t&) override;
|
||||
|
||||
virtual bool DeallocPDocAccessibleChild(PDocAccessibleChild*) override;
|
||||
|
||||
virtual PDocumentRendererChild*
|
||||
AllocPDocumentRendererChild(const nsRect& aDocumentRect,
|
||||
const gfx::Matrix& aTransform,
|
||||
const nsString& aBggcolor,
|
||||
const uint32_t& aRenderFlags,
|
||||
const bool& aFlushLayout,
|
||||
const nsIntSize& arenderSize) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPDocumentRendererChild(PDocumentRendererChild* aCctor) override;
|
||||
|
||||
virtual bool
|
||||
RecvPDocumentRendererConstructor(PDocumentRendererChild* aActor,
|
||||
const nsRect& aDocumentRect,
|
||||
const gfx::Matrix& aTransform,
|
||||
const nsString& aBgcolor,
|
||||
const uint32_t& aRenderFlags,
|
||||
const bool& aFlushLayout,
|
||||
const nsIntSize& aRenderSize) override;
|
||||
|
||||
virtual PColorPickerChild*
|
||||
AllocPColorPickerChild(const nsString& aTitle,
|
||||
const nsString& aInitialColor) override;
|
||||
|
||||
virtual bool DeallocPColorPickerChild(PColorPickerChild* aActor) override;
|
||||
|
||||
virtual PFilePickerChild*
|
||||
AllocPFilePickerChild(const nsString& aTitle, const int16_t& aMode) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPFilePickerChild(PFilePickerChild* aActor) override;
|
||||
|
||||
virtual PIndexedDBPermissionRequestChild*
|
||||
AllocPIndexedDBPermissionRequestChild(const Principal& aPrincipal) override;
|
||||
|
||||
virtual bool
|
||||
DeallocPIndexedDBPermissionRequestChild(PIndexedDBPermissionRequestChild* aActor) override;
|
||||
|
||||
virtual nsIWebNavigation* WebNavigation() const override
|
||||
{
|
||||
return mWebNav;
|
||||
}
|
||||
|
||||
virtual PuppetWidget* WebWidget() override { return mPuppetWidget; }
|
||||
|
||||
/** Return the DPI of the widget this TabChild draws to. */
|
||||
void GetDPI(float* aDPI);
|
||||
|
||||
void GetDefaultScale(double *aScale);
|
||||
|
||||
void GetMaxTouchPoints(uint32_t* aTouchPoints);
|
||||
|
||||
ScreenOrientationInternal GetOrientation() const { return mOrientation; }
|
||||
|
||||
void SetBackgroundColor(const nscolor& aColor);
|
||||
|
||||
void NotifyPainted();
|
||||
|
||||
void RequestNativeKeyBindings(mozilla::widget::AutoCacheNativeKeyCommands* aAutoCache,
|
||||
WidgetKeyboardEvent* aEvent);
|
||||
|
||||
/**
|
||||
* Signal to this TabChild that it should be made visible:
|
||||
* activated widget, retained layer tree, etc. (Respectively,
|
||||
* made not visible.)
|
||||
*/
|
||||
void MakeVisible();
|
||||
void MakeHidden();
|
||||
|
||||
// Returns true if the file descriptor was found in the cache, false
|
||||
// otherwise.
|
||||
bool GetCachedFileDescriptor(const nsAString& aPath,
|
||||
nsICachedFileDescriptorListener* aCallback);
|
||||
|
||||
void CancelCachedFileDescriptorCallback(
|
||||
const nsAString& aPath,
|
||||
nsICachedFileDescriptorListener* aCallback);
|
||||
|
||||
nsIContentChild* Manager() const { return mManager; }
|
||||
|
||||
bool GetUpdateHitRegion() const { return mUpdateHitRegion; }
|
||||
|
||||
void UpdateHitRegion(const nsRegion& aRegion);
|
||||
|
||||
static inline TabChild*
|
||||
GetFrom(nsIDocShell* aDocShell)
|
||||
{
|
||||
nsCOMPtr<nsITabChild> tc = do_GetInterface(aDocShell);
|
||||
return static_cast<TabChild*>(tc.get());
|
||||
}
|
||||
|
||||
static TabChild* GetFrom(nsIPresShell* aPresShell);
|
||||
static TabChild* GetFrom(uint64_t aLayersId);
|
||||
|
||||
void DidComposite(uint64_t aTransactionId,
|
||||
const TimeStamp& aCompositeStart,
|
||||
const TimeStamp& aCompositeEnd);
|
||||
|
||||
void DidRequestComposite(const TimeStamp& aCompositeReqStart,
|
||||
const TimeStamp& aCompositeReqEnd);
|
||||
|
||||
void ClearCachedResources();
|
||||
|
||||
static inline TabChild* GetFrom(nsIDOMWindow* aWindow)
|
||||
{
|
||||
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(webNav);
|
||||
return GetFrom(docShell);
|
||||
}
|
||||
|
||||
virtual bool RecvUIResolutionChanged(const float& aDpi,
|
||||
const double& aScale) override;
|
||||
|
||||
virtual bool
|
||||
RecvThemeChanged(nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache) override;
|
||||
|
||||
virtual bool RecvHandleAccessKey(nsTArray<uint32_t>&& aCharCodes,
|
||||
const bool& aIsTrusted,
|
||||
const int32_t& aModifierMask) override;
|
||||
|
||||
virtual bool RecvAudioChannelChangeNotification(const uint32_t& aAudioChannel,
|
||||
const float& aVolume,
|
||||
const bool& aMuted) override;
|
||||
|
||||
/**
|
||||
* Native widget remoting protocol for use with windowed plugins with e10s.
|
||||
*/
|
||||
PPluginWidgetChild* AllocPPluginWidgetChild() override;
|
||||
|
||||
bool DeallocPPluginWidgetChild(PPluginWidgetChild* aActor) override;
|
||||
|
||||
nsresult CreatePluginWidget(nsIWidget* aParent, nsIWidget** aOut);
|
||||
|
||||
LayoutDeviceIntPoint GetChromeDisplacement() const { return mChromeDisp; };
|
||||
|
||||
bool IPCOpen() const { return mIPCOpen; }
|
||||
|
||||
bool ParentIsActive() const
|
||||
{
|
||||
return mParentIsActive;
|
||||
}
|
||||
|
||||
bool AsyncPanZoomEnabled() const { return mAsyncPanZoomEnabled; }
|
||||
|
||||
virtual ScreenIntSize GetInnerSize() override;
|
||||
|
||||
// Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
|
||||
void DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
||||
const uint64_t& aLayersId,
|
||||
PRenderFrameChild* aRenderFrame,
|
||||
const ShowInfo& aShowInfo);
|
||||
|
||||
protected:
|
||||
virtual ~TabChild();
|
||||
virtual ~TabChild();
|
||||
|
||||
virtual PRenderFrameChild* AllocPRenderFrameChild() override;
|
||||
virtual bool DeallocPRenderFrameChild(PRenderFrameChild* aFrame) override;
|
||||
virtual bool RecvDestroy() override;
|
||||
virtual bool RecvSetUpdateHitRegion(const bool& aEnabled) override;
|
||||
virtual bool RecvSetDocShellIsActive(const bool& aIsActive, const bool& aIsHidden) override;
|
||||
virtual bool RecvNavigateByKey(const bool& aForward, const bool& aForDocumentNavigation) override;
|
||||
virtual PRenderFrameChild* AllocPRenderFrameChild() override;
|
||||
|
||||
virtual bool RecvRequestNotifyAfterRemotePaint() override;
|
||||
virtual bool DeallocPRenderFrameChild(PRenderFrameChild* aFrame) override;
|
||||
|
||||
virtual bool RecvSuppressDisplayport(const bool& aEnabled) override;
|
||||
virtual bool RecvDestroy() override;
|
||||
|
||||
virtual bool RecvParentActivated(const bool& aActivated) override;
|
||||
virtual bool RecvSetUpdateHitRegion(const bool& aEnabled) override;
|
||||
|
||||
virtual bool RecvStopIMEStateManagement() override;
|
||||
virtual bool RecvMenuKeyboardListenerInstalled(
|
||||
const bool& aInstalled) override;
|
||||
virtual bool RecvSetDocShellIsActive(const bool& aIsActive,
|
||||
const bool& aIsHidden) override;
|
||||
|
||||
virtual bool RecvNavigateByKey(const bool& aForward,
|
||||
const bool& aForDocumentNavigation) override;
|
||||
|
||||
virtual bool RecvRequestNotifyAfterRemotePaint() override;
|
||||
|
||||
virtual bool RecvSuppressDisplayport(const bool& aEnabled) override;
|
||||
|
||||
virtual bool RecvParentActivated(const bool& aActivated) override;
|
||||
|
||||
virtual bool RecvStopIMEStateManagement() override;
|
||||
|
||||
virtual bool RecvMenuKeyboardListenerInstalled(
|
||||
const bool& aInstalled) override;
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
void MaybeRequestPreinitCamera();
|
||||
void MaybeRequestPreinitCamera();
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Notify others that our TabContext has been updated. (At the moment, this
|
||||
// sets the appropriate app-id and is-browser flags on our docshell.)
|
||||
//
|
||||
// You should call this after calling TabContext::SetTabContext(). We also
|
||||
// call this during Init().
|
||||
void NotifyTabContextUpdated();
|
||||
// Notify others that our TabContext has been updated. (At the moment, this
|
||||
// sets the appropriate app-id and is-browser flags on our docshell.)
|
||||
//
|
||||
// You should call this after calling TabContext::SetTabContext(). We also
|
||||
// call this during Init().
|
||||
void NotifyTabContextUpdated();
|
||||
|
||||
void ActorDestroy(ActorDestroyReason why) override;
|
||||
void ActorDestroy(ActorDestroyReason why) override;
|
||||
|
||||
enum FrameScriptLoading { DONT_LOAD_SCRIPTS, DEFAULT_LOAD_SCRIPTS };
|
||||
bool InitTabChildGlobal(FrameScriptLoading aScriptLoading = DEFAULT_LOAD_SCRIPTS);
|
||||
bool InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
||||
const uint64_t& aLayersId,
|
||||
PRenderFrameChild* aRenderFrame);
|
||||
void DestroyWindow();
|
||||
void SetProcessNameToAppName();
|
||||
enum FrameScriptLoading { DONT_LOAD_SCRIPTS, DEFAULT_LOAD_SCRIPTS };
|
||||
|
||||
void ApplyShowInfo(const ShowInfo& aInfo);
|
||||
bool InitTabChildGlobal(FrameScriptLoading aScriptLoading = DEFAULT_LOAD_SCRIPTS);
|
||||
|
||||
bool HasValidInnerSize();
|
||||
bool InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
||||
const uint64_t& aLayersId,
|
||||
PRenderFrameChild* aRenderFrame);
|
||||
|
||||
void SetTabId(const TabId& aTabId);
|
||||
void DestroyWindow();
|
||||
|
||||
ScreenIntRect GetOuterRect();
|
||||
void SetProcessNameToAppName();
|
||||
|
||||
void SetUnscaledInnerSize(const CSSSize& aSize) {
|
||||
mUnscaledInnerSize = aSize;
|
||||
}
|
||||
void ApplyShowInfo(const ShowInfo& aInfo);
|
||||
|
||||
class CachedFileDescriptorInfo;
|
||||
class CachedFileDescriptorCallbackRunnable;
|
||||
class DelayedDeleteRunnable;
|
||||
bool HasValidInnerSize();
|
||||
|
||||
TextureFactoryIdentifier mTextureFactoryIdentifier;
|
||||
nsCOMPtr<nsIWebNavigation> mWebNav;
|
||||
RefPtr<PuppetWidget> mPuppetWidget;
|
||||
nsCOMPtr<nsIURI> mLastURI;
|
||||
RenderFrameChild* mRemoteFrame;
|
||||
RefPtr<nsIContentChild> mManager;
|
||||
uint32_t mChromeFlags;
|
||||
int32_t mActiveSuppressDisplayport;
|
||||
uint64_t mLayersId;
|
||||
CSSRect mUnscaledOuterRect;
|
||||
// Whether we have already received a FileDescriptor for the app package.
|
||||
bool mAppPackageFileDescriptorRecved;
|
||||
// At present only 1 of these is really expected.
|
||||
nsAutoTArray<nsAutoPtr<CachedFileDescriptorInfo>, 1>
|
||||
mCachedFileDescriptorInfos;
|
||||
nscolor mLastBackgroundColor;
|
||||
bool mDidFakeShow;
|
||||
bool mNotified;
|
||||
bool mTriedBrowserInit;
|
||||
ScreenOrientationInternal mOrientation;
|
||||
bool mUpdateHitRegion;
|
||||
void SetTabId(const TabId& aTabId);
|
||||
|
||||
bool mIgnoreKeyPressEvent;
|
||||
RefPtr<APZEventState> mAPZEventState;
|
||||
SetAllowedTouchBehaviorCallback mSetAllowedTouchBehaviorCallback;
|
||||
bool mHasValidInnerSize;
|
||||
bool mDestroyed;
|
||||
// Position of tab, relative to parent widget (typically the window)
|
||||
LayoutDeviceIntPoint mChromeDisp;
|
||||
TabId mUniqueId;
|
||||
ScreenIntRect GetOuterRect();
|
||||
|
||||
friend class ContentChild;
|
||||
float mDPI;
|
||||
double mDefaultScale;
|
||||
void SetUnscaledInnerSize(const CSSSize& aSize)
|
||||
{
|
||||
mUnscaledInnerSize = aSize;
|
||||
}
|
||||
|
||||
bool mIPCOpen;
|
||||
bool mParentIsActive;
|
||||
bool mAsyncPanZoomEnabled;
|
||||
CSSSize mUnscaledInnerSize;
|
||||
bool mDidSetRealShowInfo;
|
||||
class CachedFileDescriptorInfo;
|
||||
class CachedFileDescriptorCallbackRunnable;
|
||||
class DelayedDeleteRunnable;
|
||||
|
||||
nsAutoTArray<bool, NUMBER_OF_AUDIO_CHANNELS> mAudioChannelsActive;
|
||||
TextureFactoryIdentifier mTextureFactoryIdentifier;
|
||||
nsCOMPtr<nsIWebNavigation> mWebNav;
|
||||
RefPtr<PuppetWidget> mPuppetWidget;
|
||||
nsCOMPtr<nsIURI> mLastURI;
|
||||
RenderFrameChild* mRemoteFrame;
|
||||
RefPtr<nsIContentChild> mManager;
|
||||
uint32_t mChromeFlags;
|
||||
int32_t mActiveSuppressDisplayport;
|
||||
uint64_t mLayersId;
|
||||
CSSRect mUnscaledOuterRect;
|
||||
// Whether we have already received a FileDescriptor for the app package.
|
||||
bool mAppPackageFileDescriptorRecved;
|
||||
// At present only 1 of these is really expected.
|
||||
nsAutoTArray<nsAutoPtr<CachedFileDescriptorInfo>, 1>
|
||||
mCachedFileDescriptorInfos;
|
||||
nscolor mLastBackgroundColor;
|
||||
bool mDidFakeShow;
|
||||
bool mNotified;
|
||||
bool mTriedBrowserInit;
|
||||
ScreenOrientationInternal mOrientation;
|
||||
bool mUpdateHitRegion;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
|
||||
bool mIgnoreKeyPressEvent;
|
||||
RefPtr<APZEventState> mAPZEventState;
|
||||
SetAllowedTouchBehaviorCallback mSetAllowedTouchBehaviorCallback;
|
||||
bool mHasValidInnerSize;
|
||||
bool mDestroyed;
|
||||
// Position of tab, relative to parent widget (typically the window)
|
||||
LayoutDeviceIntPoint mChromeDisp;
|
||||
TabId mUniqueId;
|
||||
|
||||
friend class ContentChild;
|
||||
float mDPI;
|
||||
double mDefaultScale;
|
||||
|
||||
bool mIPCOpen;
|
||||
bool mParentIsActive;
|
||||
bool mAsyncPanZoomEnabled;
|
||||
CSSSize mUnscaledInnerSize;
|
||||
bool mDidSetRealShowInfo;
|
||||
|
||||
nsAutoTArray<bool, NUMBER_OF_AUDIO_CHANNELS> mAudioChannelsActive;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -104,8 +104,8 @@ public:
|
|||
bool HasOwnOrContainingApp() const;
|
||||
|
||||
/**
|
||||
* OriginAttributesRef() returns the DocShellOriginAttributes of this frame to the
|
||||
* caller. This is used to store any attribute associated with the frame's
|
||||
* OriginAttributesRef() returns the DocShellOriginAttributes of this frame to
|
||||
* the caller. This is used to store any attribute associated with the frame's
|
||||
* docshell, such as the AppId.
|
||||
*/
|
||||
const DocShellOriginAttributes& OriginAttributesRef() const;
|
||||
|
@ -196,10 +196,11 @@ public:
|
|||
return TabContext::SetTabContext(aContext);
|
||||
}
|
||||
|
||||
bool SetTabContext(mozIApplication* aOwnApp,
|
||||
mozIApplication* aAppFrameOwnerApp,
|
||||
const DocShellOriginAttributes& aOriginAttributes,
|
||||
const nsACString& aSignedPkgOriginNoSuffix = EmptyCString())
|
||||
bool
|
||||
SetTabContext(mozIApplication* aOwnApp,
|
||||
mozIApplication* aAppFrameOwnerApp,
|
||||
const DocShellOriginAttributes& aOriginAttributes,
|
||||
const nsACString& aSignedPkgOriginNoSuffix = EmptyCString())
|
||||
{
|
||||
return TabContext::SetTabContext(aOwnApp,
|
||||
aAppFrameOwnerApp,
|
||||
|
|
|
@ -64,16 +64,19 @@ struct ParamTraits<mozilla::dom::AudioChannel>
|
|||
{
|
||||
typedef mozilla::dom::AudioChannel paramType;
|
||||
|
||||
static bool IsLegalValue(const paramType &aValue) {
|
||||
static bool IsLegalValue(const paramType &aValue)
|
||||
{
|
||||
return aValue <= mozilla::dom::AudioChannel::Publicnotification;
|
||||
}
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aValue) {
|
||||
static void Write(Message* aMsg, const paramType& aValue)
|
||||
{
|
||||
MOZ_ASSERT(IsLegalValue(aValue));
|
||||
WriteParam(aMsg, (uint32_t)aValue);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult) {
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
uint32_t value;
|
||||
if(!ReadParam(aMsg, aIter, &value) ||
|
||||
!IsLegalValue(paramType(value))) {
|
||||
|
@ -84,8 +87,7 @@ struct ParamTraits<mozilla::dom::AudioChannel>
|
|||
}
|
||||
|
||||
static void Log(const paramType& aParam, std::wstring* aLog)
|
||||
{
|
||||
}
|
||||
{}
|
||||
};
|
||||
|
||||
template <>
|
||||
|
@ -93,15 +95,15 @@ struct ParamTraits<nsEventStatus>
|
|||
: public ContiguousEnumSerializer<nsEventStatus,
|
||||
nsEventStatus_eIgnore,
|
||||
nsEventStatus_eSentinel>
|
||||
{ };
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<nsSizeMode>
|
||||
: public ContiguousEnumSerializer<nsSizeMode,
|
||||
nsSizeMode_Normal,
|
||||
nsSizeMode_Invalid>
|
||||
{ };
|
||||
{};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif
|
||||
#endif // TABMESSAGE_UTILS_H
|
||||
|
|
|
@ -438,7 +438,7 @@ TabParent::GetAppType(nsAString& aOut)
|
|||
}
|
||||
|
||||
bool
|
||||
TabParent::IsVisible()
|
||||
TabParent::IsVisible() const
|
||||
{
|
||||
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
|
||||
if (!frameLoader) {
|
||||
|
|
1150
dom/ipc/TabParent.h
1150
dom/ipc/TabParent.h
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -51,9 +51,9 @@ public:
|
|||
BlobChild* GetOrCreateActorForBlob(Blob* aBlob);
|
||||
BlobChild* GetOrCreateActorForBlobImpl(BlobImpl* aImpl);
|
||||
|
||||
virtual PBlobChild* SendPBlobConstructor(
|
||||
PBlobChild* aActor,
|
||||
const BlobConstructorParams& aParams) = 0;
|
||||
virtual PBlobChild*
|
||||
SendPBlobConstructor(PBlobChild* aActor,
|
||||
const BlobConstructorParams& aParams) = 0;
|
||||
|
||||
virtual bool
|
||||
SendPBrowserConstructor(PBrowserChild* aActor,
|
||||
|
|
|
@ -55,28 +55,29 @@ public:
|
|||
BlobParent* GetOrCreateActorForBlob(Blob* aBlob);
|
||||
BlobParent* GetOrCreateActorForBlobImpl(BlobImpl* aImpl);
|
||||
|
||||
virtual ContentParentId ChildID() = 0;
|
||||
virtual bool IsForApp() = 0;
|
||||
virtual bool IsForBrowser() = 0;
|
||||
virtual ContentParentId ChildID() const = 0;
|
||||
virtual bool IsForApp() const = 0;
|
||||
virtual bool IsForBrowser() const = 0;
|
||||
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
virtual PBlobParent* SendPBlobConstructor(
|
||||
PBlobParent* aActor,
|
||||
const BlobConstructorParams& aParams) = 0;
|
||||
MOZ_WARN_UNUSED_RESULT virtual PBlobParent*
|
||||
SendPBlobConstructor(PBlobParent* aActor,
|
||||
const BlobConstructorParams& aParams) = 0;
|
||||
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
virtual PBrowserParent* SendPBrowserConstructor(
|
||||
PBrowserParent* actor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& context,
|
||||
const uint32_t& chromeFlags,
|
||||
const ContentParentId& aCpId,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) = 0;
|
||||
MOZ_WARN_UNUSED_RESULT virtual PBrowserParent*
|
||||
SendPBrowserConstructor(PBrowserParent* actor,
|
||||
const TabId& aTabId,
|
||||
const IPCTabContext& context,
|
||||
const uint32_t& chromeFlags,
|
||||
const ContentParentId& aCpId,
|
||||
const bool& aIsForApp,
|
||||
const bool& aIsForBrowser) = 0;
|
||||
|
||||
virtual bool IsContentParent() const { return false; }
|
||||
|
||||
virtual bool IsContentParent() { return false; }
|
||||
ContentParent* AsContentParent();
|
||||
virtual bool IsContentBridgeParent() { return false; }
|
||||
|
||||
virtual bool IsContentBridgeParent() const { return false; }
|
||||
|
||||
ContentBridgeParent* AsContentBridgeParent();
|
||||
|
||||
protected: // methods
|
||||
|
|
|
@ -245,7 +245,12 @@ AudioBlockPanStereoToStereo(const float aInputL[WEBAUDIO_BLOCK_SIZE],
|
|||
float aOutputR[WEBAUDIO_BLOCK_SIZE])
|
||||
{
|
||||
#ifdef BUILD_ARM_NEON
|
||||
// No NEON version yet: bug 1105513
|
||||
if (mozilla::supports_neon()) {
|
||||
AudioBlockPanStereoToStereo_NEON(aInputL, aInputR,
|
||||
aGainL, aGainR, aIsOnTheLeft,
|
||||
aOutputL, aOutputR);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t i;
|
||||
|
|
|
@ -222,4 +222,97 @@ AudioBlockPanStereoToStereo_NEON(const float aInputL[WEBAUDIO_BLOCK_SIZE],
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AudioBlockPanStereoToStereo_NEON(const float aInputL[WEBAUDIO_BLOCK_SIZE],
|
||||
const float aInputR[WEBAUDIO_BLOCK_SIZE],
|
||||
float aGainL[WEBAUDIO_BLOCK_SIZE],
|
||||
float aGainR[WEBAUDIO_BLOCK_SIZE],
|
||||
const bool aIsOnTheLeft[WEBAUDIO_BLOCK_SIZE],
|
||||
float aOutputL[WEBAUDIO_BLOCK_SIZE],
|
||||
float aOutputR[WEBAUDIO_BLOCK_SIZE])
|
||||
{
|
||||
ASSERT_ALIGNED(aInputL);
|
||||
ASSERT_ALIGNED(aInputR);
|
||||
ASSERT_ALIGNED(aGainL);
|
||||
ASSERT_ALIGNED(aGainR);
|
||||
ASSERT_ALIGNED(aIsOnTheLeft);
|
||||
ASSERT_ALIGNED(aOutputL);
|
||||
ASSERT_ALIGNED(aOutputR);
|
||||
|
||||
float32x4_t vinL0, vinL1;
|
||||
float32x4_t vinR0, vinR1;
|
||||
float32x4_t voutL0, voutL1;
|
||||
float32x4_t voutR0, voutR1;
|
||||
float32x4_t vscaleL0, vscaleL1;
|
||||
float32x4_t vscaleR0, vscaleR1;
|
||||
float32x4_t onleft0, onleft1, notonleft0, notonleft1;
|
||||
|
||||
float32x4_t zero = {0, 0, 0, 0};
|
||||
uint8x8_t isOnTheLeft;
|
||||
|
||||
for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; i+=8) {
|
||||
vinL0 = vld1q_f32(ADDRESS_OF(aInputL, i));
|
||||
vinL1 = vld1q_f32(ADDRESS_OF(aInputL, i+4));
|
||||
|
||||
vinR0 = vld1q_f32(ADDRESS_OF(aInputR, i));
|
||||
vinR1 = vld1q_f32(ADDRESS_OF(aInputR, i+4));
|
||||
|
||||
vscaleL0 = vld1q_f32(ADDRESS_OF(aGainL, i));
|
||||
vscaleL1 = vld1q_f32(ADDRESS_OF(aGainL, i+4));
|
||||
|
||||
vscaleR0 = vld1q_f32(ADDRESS_OF(aGainR, i));
|
||||
vscaleR1 = vld1q_f32(ADDRESS_OF(aGainR, i+4));
|
||||
|
||||
// Load output with boolean "on the left" values. This assumes that
|
||||
// bools are stored as a single byte.
|
||||
isOnTheLeft = vld1_u8((uint8_t *)&aIsOnTheLeft[i]);
|
||||
voutL0 = vsetq_lane_f32(vget_lane_u8(isOnTheLeft, 0), voutL0, 0);
|
||||
voutL0 = vsetq_lane_f32(vget_lane_u8(isOnTheLeft, 1), voutL0, 1);
|
||||
voutL0 = vsetq_lane_f32(vget_lane_u8(isOnTheLeft, 2), voutL0, 2);
|
||||
voutL0 = vsetq_lane_f32(vget_lane_u8(isOnTheLeft, 3), voutL0, 3);
|
||||
voutL1 = vsetq_lane_f32(vget_lane_u8(isOnTheLeft, 4), voutL1, 0);
|
||||
voutL1 = vsetq_lane_f32(vget_lane_u8(isOnTheLeft, 5), voutL1, 1);
|
||||
voutL1 = vsetq_lane_f32(vget_lane_u8(isOnTheLeft, 6), voutL1, 2);
|
||||
voutL1 = vsetq_lane_f32(vget_lane_u8(isOnTheLeft, 7), voutL1, 3);
|
||||
|
||||
// Convert the boolean values into masks by setting all bits to 1
|
||||
// if true.
|
||||
voutL0 = (float32x4_t)vcgtq_f32(voutL0, zero);
|
||||
voutL1 = (float32x4_t)vcgtq_f32(voutL1, zero);
|
||||
|
||||
// The right output masks are the same as the left masks
|
||||
voutR0 = voutL0;
|
||||
voutR1 = voutL1;
|
||||
|
||||
// Calculate left channel assuming isOnTheLeft
|
||||
onleft0 = vmlaq_f32(vinL0, vinR0, vscaleL0);
|
||||
onleft1 = vmlaq_f32(vinL1, vinR1, vscaleL0);
|
||||
|
||||
// Calculate left channel assuming not isOnTheLeft
|
||||
notonleft0 = vmulq_f32(vinL0, vscaleL0);
|
||||
notonleft1 = vmulq_f32(vinL1, vscaleL1);
|
||||
|
||||
// Write results using previously stored masks
|
||||
voutL0 = vbslq_f32((uint32x4_t)voutL0, onleft0, notonleft0);
|
||||
voutL1 = vbslq_f32((uint32x4_t)voutL1, onleft1, notonleft1);
|
||||
|
||||
// Calculate right channel assuming isOnTheLeft
|
||||
onleft0 = vmulq_f32(vinR0, vscaleR0);
|
||||
onleft1 = vmulq_f32(vinR1, vscaleR1);
|
||||
|
||||
// Calculate right channel assuming not isOnTheLeft
|
||||
notonleft0 = vmlaq_f32(vinR0, vinL0, vscaleR0);
|
||||
notonleft1 = vmlaq_f32(vinR1, vinL1, vscaleR1);
|
||||
|
||||
// Write results using previously stored masks
|
||||
voutR0 = vbslq_f32((uint32x4_t)voutR0, onleft0, notonleft0);
|
||||
voutR1 = vbslq_f32((uint32x4_t)voutR1, onleft1, notonleft1);
|
||||
|
||||
vst1q_f32(ADDRESS_OF(aOutputL, i), voutL0);
|
||||
vst1q_f32(ADDRESS_OF(aOutputL, i+4), voutL1);
|
||||
vst1q_f32(ADDRESS_OF(aOutputR, i), voutR0);
|
||||
vst1q_f32(ADDRESS_OF(aOutputR, i+4), voutR1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,15 @@ AudioBlockPanStereoToStereo_NEON(const float aInputL[WEBAUDIO_BLOCK_SIZE],
|
|||
float aGainL, float aGainR, bool aIsOnTheLeft,
|
||||
float aOutputL[WEBAUDIO_BLOCK_SIZE],
|
||||
float aOutputR[WEBAUDIO_BLOCK_SIZE]);
|
||||
|
||||
void
|
||||
AudioBlockPanStereoToStereo_NEON(const float aInputL[WEBAUDIO_BLOCK_SIZE],
|
||||
const float aInputR[WEBAUDIO_BLOCK_SIZE],
|
||||
float aGainL[WEBAUDIO_BLOCK_SIZE],
|
||||
float aGainR[WEBAUDIO_BLOCK_SIZE],
|
||||
const bool aIsOnTheLeft[WEBAUDIO_BLOCK_SIZE],
|
||||
float aOutputL[WEBAUDIO_BLOCK_SIZE],
|
||||
float aOutputR[WEBAUDIO_BLOCK_SIZE]);
|
||||
}
|
||||
|
||||
#endif /* MOZILLA_AUDIONODEENGINENEON_H_ */
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче