Merge m-c to inbound, a=merge CLOSED TREE

--HG--
extra : commitid : 4JS7aaOzaVD
extra : amend_source : 249ac0feaf4a6ea8ad5d2ef9de63d4c5baee012b
This commit is contained in:
Wes Kocher 2016-01-05 16:52:09 -08:00
commit e0dc3b7265
107 changed files with 1654 additions and 651 deletions

View File

@ -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

View File

@ -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;

View File

@ -66,23 +66,36 @@ AlertsService.prototype = {
},
// nsIAlertsService
showAlert: function(aAlert, aAlertListener) {
if (!aAlert) {
return;
}
cpmm.sendAsyncMessage(kMessageAlertNotificationSend, {
imageURL: aAlert.imageURL,
title: aAlert.title,
text: aAlert.text,
clickable: aAlert.textClickable,
cookie: aAlert.cookie,
listener: aAlertListener,
id: aAlert.name,
dir: aAlert.dir,
lang: aAlert.lang,
dataStr: aAlert.data,
inPrivateBrowsing: aAlert.inPrivateBrowsing
});
},
showAlertNotification: function(aImageUrl, aTitle, aText, aTextClickable,
aCookie, aAlertListener, aName, aBidi,
aLang, aDataStr, aPrincipal,
aInPrivateBrowsing) {
cpmm.sendAsyncMessage(kMessageAlertNotificationSend, {
imageURL: aImageUrl,
title: aTitle,
text: aText,
clickable: aTextClickable,
cookie: aCookie,
listener: aAlertListener,
id: aName,
dir: aBidi,
lang: aLang,
dataStr: aDataStr,
inPrivateBrowsing: aInPrivateBrowsing
});
let alert = Cc["@mozilla.org/alert-notification;1"].
createInstance(Ci.nsIAlertNotification);
alert.init(aName, aImageUrl, aTitle, aText, aTextClickable, aCookie,
aBidi, aLang, aDataStr, aPrincipal, aInPrivateBrowsing);
this.showAlert(alert, aAlertListener);
},
closeAlert: function(aName) {

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"
}

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -739,8 +739,6 @@ HistoryMenu.prototype = {
return;
}
let enabled = PlacesUIUtils.shouldEnableTabsFromOtherComputersMenuitem();
menuitem.setAttribute("disabled", !enabled);
menuitem.setAttribute("hidden", false);
},

View File

@ -803,6 +803,15 @@ BrowserGlue.prototype = {
this._sanitizer.onStartup();
// check if we're in safe mode
if (Services.appinfo.inSafeMode) {
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1231112#c7 . We need to
// register the observer early if we have to migrate tab groups
let currentUIVersion = 0;
try {
currentUIVersion = Services.prefs.getIntPref("browser.migration.version");
} catch(ex) {}
if (currentUIVersion < 35) {
this._maybeMigrateTabGroups();
}
Services.ww.openWindow(null, "chrome://browser/content/safeMode.xul",
"_blank", "chrome,centerscreen,modal,resizable=no", null);
}
@ -2241,7 +2250,8 @@ BrowserGlue.prototype = {
this._notifyNotificationsUpgrade().catch(Cu.reportError);
}
if (currentUIVersion < 35) {
// Only do this outside of safe mode, because in safe mode we do this earlier.
if (currentUIVersion < 35 && !Services.appinfo.inSafeMode) {
this._maybeMigrateTabGroups();
}

View File

@ -556,7 +556,8 @@ var WindowListener = {
buttonNode.accessKey = paused ? this._getString("infobar_button_resume_accesskey") :
this._getString("infobar_button_pause_accesskey");
return true;
}
},
type: "pause"
},
{
label: this._getString("infobar_button_stop_label"),
@ -565,7 +566,8 @@ var WindowListener = {
callback: () => {
this._hideBrowserSharingInfoBar();
LoopUI.MozLoopService.hangupAllChatWindows();
}
},
type: "stop"
}]
);

View File

@ -21,6 +21,11 @@
border-radius: 0;
}
/* Hide Pause/Resume button until the functionality is complete */
notification[value="loop-sharing-notification"] .notification-button[type="pause"] {
display:none;
}
notification[value="loop-sharing-notification"].paused .notification-button {
background: #57bd35;
}

View File

@ -192,6 +192,11 @@
text-shadow: none;
}
/* Hide Pause/Resume button until the functionality is complete */
notification[value="loop-sharing-notification"] .notification-button[type="pause"] {
display:none;
}
notification[value="loop-sharing-notification"].paused .notification-button {
background-color: #57bd35;
color: #fff;

View File

@ -1440,6 +1440,10 @@ richlistitem[type~="action"][actiontype$="tab"] > .ac-url-box > .ac-action-icon
background-color: Window;
}
#sidebar-header > .close-icon:not(:hover):-moz-lwtheme-brighttext {
background-image: -moz-image-rect(url("chrome://global/skin/icons/close.svg"), 0, 80, 16, 64);
}
.browserContainer > findbar {
background-color: -moz-dialog;
color: -moz-DialogText;

View File

@ -4,6 +4,8 @@
%include ../shared/devedition.inc.css
:root[devtoolstheme="dark"] .findbar-closebutton:not(:hover),
:root[devtoolstheme="dark"] #sidebar-header > .close-icon:not(:hover),
.tab-close-button[visuallyselected]:not(:hover) {
background-image: -moz-image-rect(url("chrome://global/skin/icons/close.svg"), 0, 80, 16, 64);
}
@ -76,8 +78,9 @@
border-top-width: 0 !important;
}
/* Prevent devedition foreground color from seeping into the sidebar-box (since
* its background colors aren't affected by the devedition theme) */
#sidebar-box {
color: initial;
/* Fix the bad-looking text-shadow in the sidebar header: */
.sidebar-header,
#sidebar-header {
text-shadow: none;
}

View File

@ -52,8 +52,8 @@
@media (-moz-os-version: windows-vista),
(-moz-os-version: windows-win7) {
.sidebar-header,
#sidebar-header {
.sidebar-header:not(:-moz-lwtheme),
#sidebar-header:not(:-moz-lwtheme) {
background-color: #EEF3FA;
}

View File

@ -1872,6 +1872,18 @@ richlistitem[type~="action"][actiontype$="tab"] > .ac-url-box > .ac-action-icon
border: none;
}
@media not all and (min-resolution: 1.1dppx) {
#sidebar-header > .close-icon:-moz-lwtheme-brighttext {
list-style-image: url("chrome://global/skin/icons/close-inverted.png");
}
}
@media (min-resolution: 1.1dppx) {
#sidebar-header > .close-icon:-moz-lwtheme-brighttext {
list-style-image: url("chrome://global/skin/icons/close-inverted@2x.png");
}
}
@media (-moz-os-version: windows-xp),
(-moz-os-version: windows-vista),
(-moz-os-version: windows-win7) {

View File

@ -107,6 +107,7 @@
}
:root[devtoolstheme="dark"] .findbar-closebutton,
:root[devtoolstheme="dark"] #sidebar-header > .close-icon,
/* Tab styling - make sure to use an inverted icon for the selected tab
(brighttext only covers the unselected tabs) */
.tab-close-button[visuallyselected=true] {
@ -115,6 +116,7 @@
@media (min-resolution: 1.1dppx) {
:root[devtoolstheme="dark"] .findbar-closebutton,
:root[devtoolstheme="dark"] #sidebar-header > .close-icon,
.tab-close-button[visuallyselected=true] {
list-style-image: url("chrome://global/skin/icons/close-inverted@2x.png");
}
@ -254,6 +256,14 @@
border-right: none !important;
}
/* The sidebar header has no background now that the background of the #browser-panel
* has no image and is transparent. Fix: */
.sidebar-header:-moz-lwtheme,
#sidebar-header {
background-color: var(--chrome-background-color);
color: var(--chrome-color);
}
@media (-moz-os-version: windows-vista),
(-moz-os-version: windows-win7),
(-moz-os-version: windows-win8) {

99
devtools/bootstrap.js vendored Normal file
View File

@ -0,0 +1,99 @@
/* 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/. */
"use strict";
const Cu = Components.utils;
const Ci = Components.interfaces;
const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
// Helper to listen to a key on all windows
function MultiWindowKeyListener({ keyCode, ctrlKey, altKey, callback }) {
let keyListener = function (event) {
if (event.ctrlKey == !!ctrlKey &&
event.altKey == !!altKey &&
event.keyCode === keyCode) {
callback(event);
// Call preventDefault to avoid duplicated events when
// doing the key stroke within a tab.
event.preventDefault();
}
};
let observer = function (window, topic, data) {
// Listen on keyup to call keyListener only once per stroke
if (topic === "domwindowopened") {
window.addEventListener("keyup", keyListener);
} else {
window.removeEventListener("keyup", keyListener);
}
};
return {
start: function () {
// Automatically process already opened windows
let e = Services.ww.getWindowEnumerator();
while (e.hasMoreElements()) {
let window = e.getNext();
observer(window, "domwindowopened", null);
}
// And listen for new ones to come
Services.ww.registerNotification(observer);
},
stop: function () {
Services.ww.unregisterNotification(observer);
let e = Services.ww.getWindowEnumerator();
while (e.hasMoreElements()) {
let window = e.getNext();
observer(window, "domwindowclosed", null);
}
}
};
};
let getTopLevelWindow = function (window) {
return window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
};
function reload(event) {
// We automatically reload the toolbox if we are on a browser tab
// with a toolbox already opened
let top = getTopLevelWindow(event.view)
let isBrowser = top.location.href.includes("/browser.xul") && top.gDevToolsBrowser;
let reloadToolbox = false;
if (isBrowser && top.gDevToolsBrowser.hasToolboxOpened) {
reloadToolbox = top.gDevToolsBrowser.hasToolboxOpened(top);
}
dump("Reload DevTools. (reload-toolbox:"+reloadToolbox+")\n");
// Invalidate xul cache in order to see changes made to chrome:// files
Services.obs.notifyObservers(null, "startupcache-invalidate", null);
// Ask the loader to update itself and reopen the toolbox if needed
const {devtools} = Cu.import("resource://devtools/shared/Loader.jsm", {});
devtools.reload(reloadToolbox);
}
let listener;
function startup() {
dump("DevTools addon started.\n");
listener = new MultiWindowKeyListener({
keyCode: Ci.nsIDOMKeyEvent.DOM_VK_R, ctrlKey: true, altKey: true,
callback: reload
});
listener.start();
}
function shutdown() {
listener.stop();
listener = null;
}
function install() {}
function uninstall() {}

6
devtools/chrome.manifest Normal file
View File

@ -0,0 +1,6 @@
content devtools client/
skin devtools classic/1.0 client/themes/
resource devtools .
content webide client/webide/content/
skin webide classic/1.0 client/webide/themes/

View File

@ -18,7 +18,7 @@ const CALL_STACK_PAGE_SIZE = 25; // frames
const EVENTS = {
// When the debugger's source editor instance finishes loading or unloading.
EDITOR_LOADED: "Debugger:EditorLoaded",
EDITOR_UNLOADED: "Debugger:EditorUnoaded",
EDITOR_UNLOADED: "Debugger:EditorUnloaded",
// When new sources are received from the debugger server.
NEW_SOURCE: "Debugger:NewSource",

View File

@ -1161,6 +1161,16 @@ var gDevToolsBrowser = {
};
},
hasToolboxOpened: function(win) {
let tab = win.gBrowser.selectedTab;
for (let [target, toolbox] of gDevTools._toolboxes) {
if (target.tab == tab) {
return true;
}
}
return false;
},
/**
* Update the "Toggle Tools" checkbox in the developer tools menu. This is
* called when a toolbox is created or destroyed.
@ -1168,13 +1178,7 @@ var gDevToolsBrowser = {
_updateMenuCheckbox: function DT_updateMenuCheckbox() {
for (let win of gDevToolsBrowser._trackedBrowserWindows) {
let hasToolbox = false;
if (TargetFactory.isKnownTab(win.gBrowser.selectedTab)) {
let target = TargetFactory.forTab(win.gBrowser.selectedTab);
if (gDevTools._toolboxes.has(target)) {
hasToolbox = true;
}
}
let hasToolbox = gDevToolsBrowser.hasToolboxOpened(win);
let broadcaster = win.document.getElementById("devtoolsMenuBroadcaster_DevToolbox");
if (hasToolbox) {

View File

@ -51,9 +51,8 @@ var TreeView = React.createClass({
}
return (
DOM.div({className: "domTable", cellPadding: 0, cellSpacing: 0,
onClick: this.onClick},
children
DOM.div({className: "domTable", cellPadding: 0, cellSpacing: 0},
children
)
);
},
@ -151,8 +150,9 @@ var TreeNode = React.createFactory(React.createClass({
}
return (
DOM.div({className: classNames.join(" "), onClick: this.onClick},
DOM.span({className: "memberLabelCell"},
DOM.div({className: classNames.join(" ")},
DOM.span({className: "memberLabelCell", onClick: this.onClick},
DOM.span({className: "memberIcon"}),
DOM.span({className: "memberLabel " + member.type + "Label"},
member.name)
),

View File

@ -22,7 +22,6 @@ const CONTRACT_ID = "@mozilla.org/devtools/jsonview-sniffer;1";
const CLASS_ID = "{4148c488-dca1-49fc-a621-2a0097a62422}";
const JSON_VIEW_MIME_TYPE = "application/vnd.mozilla.json.view";
const JSON_VIEW_TYPE = "JSON View";
const JSON_EXTENSION = "json";
const CONTENT_SNIFFER_CATEGORY = "net-content-sniffers";
/**
@ -64,10 +63,6 @@ var Sniffer = Class({
if (aRequest.contentType == JSON_TYPE) {
return JSON_VIEW_MIME_TYPE;
}
if (NetworkHelper.getFileExtension(aRequest.name) == JSON_EXTENSION) {
return JSON_VIEW_MIME_TYPE;
}
}
return "";

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -20,7 +20,6 @@
.memberLabelCell {
padding: 2px 0 2px 0px;
vertical-align: top;
}
.memberValueCell {
@ -31,7 +30,6 @@
.memberLabel {
cursor: default;
overflow: hidden;
padding-left: 18px;
white-space: nowrap;
}
@ -60,6 +58,11 @@
/******************************************************************************/
.memberRow.hasChildren > .memberLabelCell > .memberIcon:hover,
.memberRow.cropped > .memberLabelCell > .memberIcon:hover {
cursor: pointer;
}
.memberRow.hasChildren > .memberLabelCell > .memberLabel:hover,
.memberRow.cropped > .memberLabelCell > .memberLabel:hover {
cursor: pointer;
@ -71,6 +74,10 @@
background-color: #EFEFEF;
}
.memberRow {
padding: 3px 0 3px 0;
}
.panelNode-dom .memberRow td,
.panelNode-domSide .memberRow td {
border-bottom: 1px solid #EFEFEF;
@ -116,19 +123,38 @@
/******************************************************************************/
/* Twisties */
.memberRow.hasChildren > .memberLabelCell > .memberLabel,
.memberRow.cropped > .memberLabelCell > .memberLabel {
background-image: url(twisty-closed.svg);
background-repeat: no-repeat;
background-position: 2px calc(0.5em - 3px);
min-height: 12px;
.memberRow > .memberLabelCell > .memberIcon {
height: 14px;
width: 14px;
display: inline-block;
line-height: 15px;
vertical-align: bottom;
padding-right: 2px;
margin-left: 3px;
}
.memberRow.hasChildren.opened > .memberLabelCell > .memberLabel,
.memberRow.cropped.opened > .memberLabelCell > .memberLabel {
background-image: url(twisty-open.svg);
.memberRow.hasChildren > .memberLabelCell > .memberIcon,
.memberRow.cropped > .memberLabelCell > .memberIcon {
background-image: url("./twisty-closed.svg");
background-repeat: no-repeat;
min-height: 12px;
}
.memberRow.hasChildren.opened > .memberLabelCell > .memberIcon,
.memberRow.cropped.opened > .memberLabelCell > .memberIcon {
background-image: url("./twisty-open.svg");
background-repeat: no-repeat;
}
@media (min-resolution: 1.1dppx) {
.memberRow.hasChildren > .memberLabelCell > .memberIcon,
.memberRow.cropped > .memberLabelCell > .memberIcon {
background-image: url("./controls@2x.png");
}
.memberRow.hasChildren.opened > .memberLabelCell > .memberIcon,
.memberRow.cropped.opened > .memberLabelCell > .memberIcon {
background-image: url("./controls@2x.png");
}
}
/******************************************************************************/
@ -140,7 +166,6 @@
.memberLabelCell,
.memberValueCell {
display: table-cell;
}
.memberLabelCell {
@ -150,3 +175,42 @@
.memberRow:hover {
background-color: transparent !important;
}
/******************************************************************************/
/* Themes */
.theme-light .memberRow.hasChildren > .memberLabelCell > .memberIcon,
.theme-light .memberRow.cropped > .memberLabelCell > .memberIcon {
background-image: url("./controls.png");
background-size: 56px 28px;
background-repeat: no-repeat;
background-position: 0 -14px;
}
.theme-light .memberRow.hasChildren.opened > .memberLabelCell > .memberIcon,
.theme-light .memberRow.cropped.opened > .memberLabelCell > .memberIcon {
background-image: url("./controls.png");
background-size: 56px 28px;
background-repeat: no-repeat;
background-position: -14px -14px;
}
.theme-dark .memberRow.hasChildren > .memberLabelCell > .memberIcon,
.theme-dark .memberRow.cropped > .memberLabelCell > .memberIcon {
background-image: url("./controls.png");
background-size: 56px 28px;
background-repeat: no-repeat;
background-position: -28px -14px;
}
.theme-dark .memberRow.hasChildren.opened > .memberLabelCell > .memberIcon,
.theme-dark .memberRow.cropped.opened > .memberLabelCell > .memberIcon {
background-image: url("./controls.png");
background-size: 56px 28px;
background-repeat: no-repeat;
background-position: -42px -14px;
}
.theme-dark .memberRow:hover {
background-color: var(--theme-selection-background-semitransparent);
}

View File

@ -6,6 +6,8 @@
DevToolsModules(
'controls.png',
'controls@2x.png',
'dom-tree.css',
'general.css',
'headers-panel.css',

View File

@ -175,7 +175,7 @@
.theme-dark .domLabel,
.theme-light .domLabel {
color: var(--theme-highlight-bluegrey);
color: var(--theme-highlight-blue);
}
.theme-dark .objectBox-array .length,
@ -207,7 +207,7 @@
.theme-light .objectBox-object {
font-family: Lucida Grande, sans-serif;
font-weight: normal;
color: var(--theme-highlight-bluegrey);
color: var(--theme-highlight-blue);
white-space: pre-wrap;
}
@ -215,5 +215,5 @@
.theme-light .caption {
font-family: Lucida Grande, Tahoma, sans-serif;
font-weight: normal;
color: var(--theme-highlight-bluegrey);
color: var(--theme-highlight-blue);
}

View File

@ -20,10 +20,10 @@ Services.prefs.setBoolPref("devtools.memory.enabled", true);
var { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
var { require } = Cu.import("resource://gre/modules/devtools/shared/Loader.jsm", {});
var { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
var { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
var { DebuggerClient } = Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {});
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
var { BrowserLoader } = Cu.import("resource://devtools/client/shared/browser-loader.js", {});
var { DebuggerServer } = require("devtools/server/main");
var { DebuggerClient } = require("devtools/shared/client/main");
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
var { TargetFactory } = require("devtools/client/framework/target");
var { Toolbox } = require("devtools/client/framework/toolbox");

View File

@ -168,7 +168,7 @@ body {
.devtools-toolbar,
.devtools-sidebar-tabs tabs,
.devtools-sidebar-alltabs,
.CodeMirror-dialog { /* General toolbar styling */
.cm-s-mozilla .CodeMirror-dialog { /* General toolbar styling */
color: var(--theme-body-color-alt);
background-color: var(--theme-toolbar-background);
border-color: hsla(210,8%,5%,.6);

View File

@ -171,7 +171,7 @@ body {
.devtools-toolbar,
.devtools-sidebar-tabs tabs,
.devtools-sidebar-alltabs,
.CodeMirror-dialog { /* General toolbar styling */
.cm-s-mozilla .CodeMirror-dialog { /* General toolbar styling */
color: var(--theme-body-color-alt);
background-color: var(--theme-toolbar-background);
border-color: var(--theme-splitter-color);

27
devtools/install.rdf Normal file
View File

@ -0,0 +1,27 @@
<?xml version="1.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/.
-->
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest"
em:id="devtools@mozilla.org"
em:name="Developer Tools (local version)"
em:description="Add-on to load DevTools from local sources and easily reload them with Ctrl+Alt+r shortcut"
em:version="44.0a1"
em:type="2"
em:creator="Mozilla">
<em:bootstrap>true</em:bootstrap>
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>44.0a1</em:minVersion>
<em:maxVersion>*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>

View File

@ -803,36 +803,6 @@ var NetworkHelper = {
let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL);
aStore.set(aUrl, uri);
return uri;
},
/**
* Returns extension for file URLs (e.g. 'json').
* Not everyURL has an extension and this method works as follows:
* 1) Remove query string
* 2) Get part after the last slash (a file name)
* 3) Look for the last dot (an extension)
*/
getFileExtension: function(aUrl) {
if (!aUrl) {
return;
}
// Remove query string from the URL if any.
let queryString = aUrl.indexOf("?");
if (queryString != -1) {
aUrl = aUrl.substr(0, queryString);
}
// Look for the part after last slash
var lastSlash = aUrl.lastIndexOf("/");
var fileName = aUrl.substr(lastSlash + 1);
if (!fileName) {
return;
}
// Now get the file extension.
var lastDot = fileName.lastIndexOf(".");
return fileName.substr(lastDot + 1);
}
};

View File

@ -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

View File

@ -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)) {

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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),

View File

@ -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;

View File

@ -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)) {

View File

@ -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

View File

@ -547,7 +547,7 @@ BluetoothHfpManager::NotifyConnectionStatusChanged(const nsAString& aType)
return;
}
DispatchStatusChangedEvent(eventName, deviceAddressStr, status);
DispatchStatusChangedEvent(eventName, mDeviceAddress, status);
}
#ifdef MOZ_B2G_RIL

View File

@ -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");

View File

@ -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)

View File

@ -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);
}

View File

@ -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();

View File

@ -313,7 +313,7 @@ DispatchReplyError(BluetoothReplyRunnable* aRunnable,
void
DispatchStatusChangedEvent(const nsAString& aType,
const nsAString& aDeviceAddress,
const BluetoothAddress& aDeviceAddress,
bool aStatus);
//

View File

@ -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

View File

@ -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).
*

View File

@ -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));

View File

@ -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();

View File

@ -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++) {

View File

@ -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();

View File

@ -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);

View File

@ -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<

View File

@ -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[];
};
/**

View File

@ -4415,25 +4415,26 @@ ContentParent::HasNotificationPermission(const IPC::Principal& aPrincipal)
}
bool
ContentParent::RecvShowAlertNotification(const nsString& aImageUrl, const nsString& aTitle,
const nsString& aText, const bool& aTextClickable,
const nsString& aCookie, const nsString& aName,
const nsString& aBidi, const nsString& aLang,
const nsString& aData,
const IPC::Principal& aPrincipal,
const bool& aInPrivateBrowsing)
ContentParent::RecvShowAlert(const AlertNotificationType& aAlert)
{
if (!HasNotificationPermission(aPrincipal)) {
nsCOMPtr<nsIAlertNotification> alert(dont_AddRef(aAlert));
if (NS_WARN_IF(!alert)) {
return true;
}
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = alert->GetPrincipal(getter_AddRefs(principal));
if (NS_WARN_IF(NS_FAILED(rv)) ||
!HasNotificationPermission(IPC::Principal(principal))) {
return true;
}
nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_ALERTSERVICE_CONTRACTID));
if (sysAlerts) {
sysAlerts->ShowAlertNotification(aImageUrl, aTitle, aText, aTextClickable,
aCookie, this, aName, aBidi, aLang,
aData, aPrincipal, aInPrivateBrowsing);
}
return true;
sysAlerts->ShowAlert(alert, this);
}
return true;
}
bool

View File

@ -901,14 +901,7 @@ private:
bool HasNotificationPermission(const IPC::Principal& aPrincipal);
virtual bool
RecvShowAlertNotification(const nsString& aImageUrl, const nsString& aTitle,
const nsString& aText, const bool& aTextClickable,
const nsString& aCookie, const nsString& aName,
const nsString& aBidi, const nsString& aLang,
const nsString& aData,
const IPC::Principal& aPrincipal,
const bool& aInPrivateBrowsing) override;
virtual bool RecvShowAlert(const AlertNotificationType& aAlert) override;
virtual bool RecvCloseAlert(const nsString& aName,
const IPC::Principal& aPrincipal) override;

View File

@ -74,6 +74,7 @@ include ProfilerTypes;
include "mozilla/dom/PContentBridgeParent.h";
using GeoPosition from "nsGeoPositionIPCSerialiser.h";
using AlertNotificationType from "mozilla/AlertNotificationIPCSerializer.h";
using struct ChromePackage from "mozilla/chrome/RegistryMessageUtils.h";
using struct SubstitutionMapping from "mozilla/chrome/RegistryMessageUtils.h";
@ -881,17 +882,7 @@ parent:
CpowEntry[] aCpows, Principal aPrincipal)
returns (StructuredCloneData[] retval);
ShowAlertNotification(nsString imageUrl,
nsString title,
nsString text,
bool textClickable,
nsString cookie,
nsString name,
nsString bidi,
nsString lang,
nsString data,
Principal principal,
bool inPrivateBrowsing);
ShowAlert(AlertNotificationType alert);
CloseAlert(nsString name, Principal principal);

View File

@ -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",

View File

@ -7,6 +7,7 @@
#include "mozilla/dom/DesktopNotificationBinding.h"
#include "mozilla/dom/AppNotificationServiceOptionsBinding.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsComponentManagerUtils.h"
#include "nsContentPermissionHelper.h"
#include "nsXULAppAPI.h"
#include "mozilla/dom/PBrowserChild.h"
@ -114,16 +115,20 @@ DesktopNotification::PostDesktopNotification()
nsIPrincipal* principal = doc->NodePrincipal();
nsCOMPtr<nsILoadContext> loadContext = doc->GetLoadContext();
bool inPrivateBrowsing = loadContext && loadContext->UsePrivateBrowsing();
return alerts->ShowAlertNotification(mIconURL, mTitle, mDescription,
true,
uniqueName,
mObserver,
uniqueName,
NS_LITERAL_STRING("auto"),
EmptyString(),
EmptyString(),
principal,
inPrivateBrowsing);
nsCOMPtr<nsIAlertNotification> alert =
do_CreateInstance(ALERT_NOTIFICATION_CONTRACTID);
NS_ENSURE_TRUE(alert, NS_ERROR_FAILURE);
nsresult rv = alert->Init(uniqueName, mIconURL, mTitle,
mDescription,
true,
uniqueName,
NS_LITERAL_STRING("auto"),
EmptyString(),
EmptyString(),
principal,
inPrivateBrowsing);
NS_ENSURE_SUCCESS(rv, rv);
return alerts->ShowAlert(alert, mObserver);
}
DesktopNotification::DesktopNotification(const nsAString & title,

View File

@ -23,6 +23,7 @@
#include "mozilla/dom/ServiceWorkerGlobalScopeBinding.h"
#include "nsAlertsUtils.h"
#include "nsComponentManagerUtils.h"
#include "nsContentPermissionHelper.h"
#include "nsContentUtils.h"
#include "nsCRTGlue.h"
@ -1787,11 +1788,19 @@ Notification::ShowInternal()
nsAutoString alertName;
GetAlertName(alertName);
alertService->ShowAlertNotification(iconUrl, mTitle, mBody, true,
uniqueCookie, alertObserver, alertName,
DirectionToString(mDir), mLang,
mDataAsBase64, GetPrincipal(),
inPrivateBrowsing);
nsCOMPtr<nsIAlertNotification> alert =
do_CreateInstance(ALERT_NOTIFICATION_CONTRACTID);
NS_ENSURE_TRUE_VOID(alert);
rv = alert->Init(alertName, iconUrl, mTitle, mBody,
true,
uniqueCookie,
DirectionToString(mDir),
mLang,
mDataAsBase64,
GetPrincipal(),
inPrivateBrowsing);
NS_ENSURE_SUCCESS_VOID(rv);
alertService->ShowAlert(alert, alertObserver);
}
/* static */ bool

View File

@ -98,15 +98,15 @@ function testNonDefaultContentToolbars(toolbars) {
function testNonDefaultChromeToolbars(toolbars) {
// None of the toolbars should be visible if hidden with chrome privileges
ok(!toolbars.locationbar,
"locationbar should be visible on default window.open()");
"locationbar should not be visible with location=no");
ok(!toolbars.menubar,
"menubar be visible on default window.open()");
"menubar should not be visible with menubar=no");
ok(!toolbars.personalbar,
"personalbar should be visible on default window.open()");
"personalbar should not be visible with personalbar=no");
ok(!toolbars.statusbar,
"statusbar should be visible on default window.open()");
"statusbar should not be visible with status=no");
ok(!toolbars.toolbar,
"toolbar should be visible on default window.open()");
"toolbar should not be visible with toolbar=no");
}
/**
@ -147,7 +147,42 @@ add_task(function*() {
let popupToolbars = yield getToolbarsFromBrowserContent(popupBrowser);
testNonDefaultContentToolbars(popupToolbars);
// Cleanup
// Ensure that chrome toolbars agree with content
let chromeToolbars = getToolbarsFromWindowChrome(popupWindow);
testNonDefaultContentToolbars(chromeToolbars);
// Close the new window
yield BrowserTestUtils.closeWindow(popupWindow);
});
});
/**
* Ensure that toolbars of a window opened to about:blank in the content context
* have the correct visibility.
*
* A window opened with "location=no, personalbar=no, toolbar=no, scrollbars=no,
* menubar=no, status=no", should only have location visible.
*/
add_task(function*() {
yield BrowserTestUtils.withNewTab({
gBrowser,
url: CONTENT_PAGE,
}, function*(browser) {
// Open a blank window with toolbars hidden
let winPromise = BrowserTestUtils.waitForNewWindow();
yield BrowserTestUtils.synthesizeMouseAtCenter("#winOpenNoURLNonDefault", {}, browser);
let popupWindow = yield winPromise;
// No need to wait for this window to load, since it's loading about:blank
let popupBrowser = popupWindow.gBrowser.selectedBrowser;
let popupToolbars = yield getToolbarsFromBrowserContent(popupBrowser);
testNonDefaultContentToolbars(popupToolbars);
// Ensure that chrome toolbars agree with content
let chromeToolbars = getToolbarsFromWindowChrome(popupWindow);
testNonDefaultContentToolbars(chromeToolbars);
// Close the new window
yield BrowserTestUtils.closeWindow(popupWindow);
});
});

View File

@ -7,6 +7,7 @@
<p><a id="winOpenDefault" href="#" onclick="return openWindow();">Open a new window via window.open with default features.</a></p>
<p><a id="winOpenNonDefault" href="#" onclick="return openWindow('resizable=no, location=no, personalbar=no, toolbar=no, scrollbars=no, menubar=no, status=no, directories=no, height=100, width=500');">Open a new window via window.open with non-default features.</a></p>
<p><a id="winOpenDialog" href="#" onclick="return openWindow('dialog=yes');">Open a new window via window.open with dialog=1.</a></p>
<p><a id="winOpenNoURLNonDefault" href="#" onclick="return openBlankWindow('location=no, toolbar=no, height=100, width=100');">Open a blank new window via window.open with non-default features.</a></p>
<p><a id="targetBlank" href="about:robots" target="_blank">Open a new window via target="_blank".</a></p>
</body>
</html>
@ -16,4 +17,9 @@ function openWindow(aFeatures="") {
window.open("about:robots", "_blank", aFeatures);
return false;
}
function openBlankWindow(aFeatures="") {
window.open("", "_blank", aFeatures);
return false;
}
</script>

View File

@ -29,26 +29,34 @@ var MockServices = (function () {
});
var mockAlertsService = {
showAlertNotification: function(imageUrl, title, text, textClickable,
cookie, alertListener, name) {
showAlert: function(alert, alertListener) {
var listener = SpecialPowers.wrap(alertListener);
activeAlertNotifications[name] = {
activeAlertNotifications[alert.name] = {
listener: listener,
cookie: cookie,
title: title
cookie: alert.cookie,
title: alert.title
};
// fake async alert show event
if (listener) {
setTimeout(function () {
listener.observe(null, "alertshow", cookie);
listener.observe(null, "alertshow", alert.cookie);
}, 100);
setTimeout(function () {
listener.observe(null, "alertclickcallback", cookie);
listener.observe(null, "alertclickcallback", alert.cookie);
}, 100);
}
},
showAlertNotification: function(imageUrl, title, text, textClickable,
cookie, alertListener, name) {
this.showAlert({
name: name,
cookie: cookie,
title: title
}, alertListener);
},
showAppNotification: function(aImageUrl, aTitle, aText, aAlertListener, aDetails) {
var listener = aAlertListener || (activeAlertNotifications[aDetails.id] ? activeAlertNotifications[aDetails.id].listener : undefined);
activeAppNotifications[aDetails.id] = {

View File

@ -8,17 +8,23 @@ var registrar = SpecialPowers.wrap(SpecialPowers.Components).manager.
QueryInterface(SpecialPowers.Ci.nsIComponentRegistrar);
var mockAlertsService = {
showAlert: function(alert, alertListener) {
// probably should do this async....
SpecialPowers.wrap(alertListener).observe(null, "alertshow", alert.cookie);
if (SpecialPowers.getBoolPref("notification.prompt.testing.click_on_notification") == true) {
SpecialPowers.wrap(alertListener).observe(null, "alertclickcallback", alert.cookie);
}
SpecialPowers.wrap(alertListener).observe(null, "alertfinished", alert.cookie);
},
showAlertNotification: function(imageUrl, title, text, textClickable,
cookie, alertListener, name, bidi,
lang, data) {
// probably should do this async....
SpecialPowers.wrap(alertListener).observe(null, "alertshow", cookie);
if (SpecialPowers.getBoolPref("notification.prompt.testing.click_on_notification") == true) {
SpecialPowers.wrap(alertListener).observe(null, "alertclickcallback", cookie);
}
SpecialPowers.wrap(alertListener).observe(null, "alertfinished", cookie);
return this.showAlert({
cookie: cookie
}, alertListener);
},
showAppNotification: function(imageUrl, title, text, alertListener, details) {

View File

@ -23,15 +23,19 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=782211
const ALERTS_SERVICE_CONTRACT_ID = "@mozilla.org/alerts-service;1";
var mockAlertsService = {
showAlertNotification: function(imageUrl, title, text, textClickable,
cookie, alertListener, name, dir,
lang, data) {
notificationsCreated.push(name);
showAlert: function(alert, alertListener) {
notificationsCreated.push(alert.name);
if (notificationsCreated.length == 3) {
checkNotifications();
}
},
showAlertNotification: function(imageUrl, title, text, textClickable,
cookie, alertListener, name, dir,
lang, data) {
this.showAlert({ name: name });
},
QueryInterface: function(aIID) {
if (SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsISupports) ||
SpecialPowers.wrap(aIID).equals(SpecialPowers.Ci.nsIAlertsService)) {

View File

@ -23,13 +23,17 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=874090
const ALERTS_SERVICE_CONTRACT_ID = "@mozilla.org/alerts-service;1";
var mockAlertsService = {
showAlertNotification: function(imageUrl, title, text, textClickable,
cookie, alertListener, name, dir, lang, data) {
ok(true, "System principal was granted permission and is able to call showAlertNotification.");
showAlert: function(alert, alertListener) {
ok(true, "System principal was granted permission and is able to call showAlert.");
unregisterMock();
SimpleTest.finish();
},
showAlertNotification: function(imageUrl, title, text, textClickable,
cookie, alertListener, name, dir, lang, data) {
this.showAlert();
},
QueryInterface: function(aIID) {
if (aIID.equals(Components.interfaces.nsISupports) ||
aIID.equals(Components.interfaces.nsIAlertsService)) {

View File

@ -117,6 +117,9 @@ var AlertsService = {
"", ALERTS_SERVICE_CONTRACT_ID, null);
},
showAlert: function() {
},
showAlertNotification: function() {
},
};

View File

@ -708,27 +708,6 @@ GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo)
namespace {
/**
* RAII class to help us remember to close file descriptors.
*/
bool WriteToFile(const char *filename, const char *toWrite)
{
int fd = open(filename, O_WRONLY);
ScopedClose autoClose(fd);
if (fd < 0) {
HAL_LOG("Unable to open file %s.", filename);
return false;
}
if (write(fd, toWrite, strlen(toWrite)) < 0) {
HAL_LOG("Unable to write to file %s.", filename);
return false;
}
return true;
}
// We can write to screenEnabledFilename to enable/disable the screen, but when
// we read, we always get "mem"! So we have to keep track ourselves whether
// the screen is on or not.
@ -849,7 +828,7 @@ UpdateCpuSleepState()
sInternalLockCpuMonitor->AssertCurrentThreadOwns();
bool allowed = sCpuSleepAllowed && !sInternalLockCpuCount;
WriteToFile(allowed ? wakeUnlockFilename : wakeLockFilename, "gecko");
WriteSysFile(allowed ? wakeUnlockFilename : wakeLockFilename, "gecko");
}
static void
@ -1257,7 +1236,7 @@ public:
mRegexes(nullptr)
{
// Enable timestamps in kernel's printk
WriteToFile("/sys/module/printk/parameters/time", "Y");
WriteSysFile("/sys/module/printk/parameters/time", "Y");
}
NS_DECL_ISUPPORTS
@ -1559,16 +1538,16 @@ EnsureCpuCGroupExists(const nsACString &aGroup)
nsAutoCString pathPrefix(kDevCpuCtl + aGroup + kSlash);
nsAutoCString cpuSharesPath(pathPrefix + NS_LITERAL_CSTRING("cpu.shares"));
if (cpuShares && !WriteToFile(cpuSharesPath.get(),
nsPrintfCString("%d", cpuShares).get())) {
if (cpuShares && !WriteSysFile(cpuSharesPath.get(),
nsPrintfCString("%d", cpuShares).get())) {
HAL_LOG("Could not set the cpu share for group %s", cpuSharesPath.get());
return false;
}
nsAutoCString notifyOnMigratePath(pathPrefix
+ NS_LITERAL_CSTRING("cpu.notify_on_migrate"));
if (!WriteToFile(notifyOnMigratePath.get(),
nsPrintfCString("%d", cpuNotifyOnMigrate).get())) {
if (!WriteSysFile(notifyOnMigratePath.get(),
nsPrintfCString("%d", cpuNotifyOnMigrate).get())) {
HAL_LOG("Could not set the cpu migration notification flag for group %s",
notifyOnMigratePath.get());
return false;
@ -1616,8 +1595,8 @@ EnsureMemCGroupExists(const nsACString &aGroup)
nsAutoCString pathPrefix(kMemCtl + aGroup + kSlash);
nsAutoCString memSwappinessPath(pathPrefix + NS_LITERAL_CSTRING("memory.swappiness"));
if (!WriteToFile(memSwappinessPath.get(),
nsPrintfCString("%d", memSwappiness).get())) {
if (!WriteSysFile(memSwappinessPath.get(),
nsPrintfCString("%d", memSwappiness).get())) {
HAL_LOG("Could not set the memory.swappiness for group %s", memSwappinessPath.get());
return false;
}
@ -1809,9 +1788,9 @@ EnsureKernelLowMemKillerParamsSet()
adjParams.Cut(adjParams.Length() - 1, 1);
minfreeParams.Cut(minfreeParams.Length() - 1, 1);
if (!adjParams.IsEmpty() && !minfreeParams.IsEmpty()) {
WriteToFile("/sys/module/lowmemorykiller/parameters/adj", adjParams.get());
WriteToFile("/sys/module/lowmemorykiller/parameters/minfree",
minfreeParams.get());
WriteSysFile("/sys/module/lowmemorykiller/parameters/adj", adjParams.get());
WriteSysFile("/sys/module/lowmemorykiller/parameters/minfree",
minfreeParams.get());
}
// Set the low-memory-notification threshold.
@ -1821,7 +1800,7 @@ EnsureKernelLowMemKillerParamsSet()
&lowMemNotifyThresholdKB))) {
// notify_trigger is in pages.
WriteToFile("/sys/module/lowmemorykiller/parameters/notify_trigger",
WriteSysFile("/sys/module/lowmemorykiller/parameters/notify_trigger",
nsPrintfCString("%ld", lowMemNotifyThresholdKB * 1024 / page_size).get());
}
@ -1856,11 +1835,11 @@ SetProcessPriority(int aPid, ProcessPriority aPriority, uint32_t aLRU)
// We try the newer interface first, and fall back to the older interface
// on failure.
if (!WriteToFile(nsPrintfCString("/proc/%d/oom_score_adj", aPid).get(),
nsPrintfCString("%d", oomScoreAdj).get()))
if (!WriteSysFile(nsPrintfCString("/proc/%d/oom_score_adj", aPid).get(),
nsPrintfCString("%d", oomScoreAdj).get()))
{
WriteToFile(nsPrintfCString("/proc/%d/oom_adj", aPid).get(),
nsPrintfCString("%d", OomAdjOfOomScoreAdj(oomScoreAdj)).get());
WriteSysFile(nsPrintfCString("/proc/%d/oom_adj", aPid).get(),
nsPrintfCString("%d", OomAdjOfOomScoreAdj(oomScoreAdj)).get());
}
HAL_LOG("Assigning pid %d to cgroup %s", aPid, pc->CGroup().get());

View File

@ -2170,13 +2170,21 @@ public class BrowserApp extends GeckoApp
final Tab tab = Tabs.getInstance().getSelectedTab();
if (tab != null) {
final String userRequested = tab.getUserRequested();
final String userSearchTerm = tab.getUserRequested();
// Check to see if there's a user-entered search term,
// which we save whenever the user performs a search.
url = (TextUtils.isEmpty(userRequested) ? tab.getURL() : userRequested);
}
final String telemetryMsg;
if (!TextUtils.isEmpty(userSearchTerm)) {
url = userSearchTerm;
telemetryMsg = "urlbar-userentered";
} else {
url = tab.getURL();
telemetryMsg = url.isEmpty() ? "urlbar-empty" : "urlbar-url";
}
Telemetry.sendUIEvent(TelemetryContract.Event.SHOW, TelemetryContract.Method.ACTIONBAR, telemetryMsg);
}
enterEditingMode(url);
}
@ -2210,7 +2218,12 @@ public class BrowserApp extends GeckoApp
mBrowserToolbar.startEditing(url, animator);
showHomePagerWithAnimator(panelId, animator);
final boolean isUserSearchTerm = !TextUtils.isEmpty(selectedTab.getUserRequested());
if (isUserSearchTerm && AppConstants.NIGHTLY_BUILD) {
showBrowserSearchAfterAnimation(animator);
} else {
showHomePagerWithAnimator(panelId, animator);
}
animator.start();
Telemetry.startUISession(TelemetryContract.Session.AWESOMESCREEN);
@ -2622,6 +2635,24 @@ public class BrowserApp extends GeckoApp
refreshToolbarHeight();
}
private void showBrowserSearchAfterAnimation(PropertyAnimator animator) {
if (animator == null) {
showBrowserSearch();
return;
}
animator.addPropertyAnimationListener(new PropertyAnimator.PropertyAnimationListener() {
@Override
public void onPropertyAnimationStart() {
}
@Override
public void onPropertyAnimationEnd() {
showBrowserSearch();
}
});
}
private void showBrowserSearch() {
if (mBrowserSearch.getUserVisibleHint()) {
return;
@ -2672,7 +2703,7 @@ public class BrowserApp extends GeckoApp
// To prevent overdraw, the HomePager is hidden when BrowserSearch is displayed:
// reverse that.
mHomePagerContainer.setVisibility(View.VISIBLE);
showHomePager(Tabs.getInstance().getSelectedTab().getMostRecentHomePanel());
mBrowserSearchContainer.setVisibility(View.INVISIBLE);

View File

@ -87,6 +87,11 @@ public class DownloadAction extends BaseAction {
temporaryFile = createTemporaryFile(context, content);
if (!canWrite(temporaryFile, destinationFile)) {
throw new RecoverableDownloadContentException(RecoverableDownloadContentException.DISK_IO,
"Temporary or destination file not writeable");
}
if (!hasEnoughDiskSpace(content, destinationFile, temporaryFile)) {
Log.d(LOGTAG, "Not enough disk space to save content. Skipping download.");
continue;
@ -125,7 +130,7 @@ public class DownloadAction extends BaseAction {
temporaryFile.delete();
}
} catch (RecoverableDownloadContentException e) {
Log.w(LOGTAG, "Downloading content failed (Recoverable): " + content , e);
Log.w(LOGTAG, "Downloading content failed (Recoverable): " + content, e);
if (e.shouldBeCountedAsFailure()) {
catalog.rememberFailure(content, e.getErrorType());
@ -336,4 +341,14 @@ public class DownloadAction extends BaseAction {
return true;
}
protected boolean canWrite(File... files) {
for (File file : files) {
if (!file.canWrite()) {
return false;
}
}
return true;
}
}

View File

@ -168,6 +168,7 @@ public class TestDownloadAction {
doReturn(file).when(action).createTemporaryFile(RuntimeEnvironment.application, content);
doReturn(file).when(action).getDestinationFile(RuntimeEnvironment.application, content);
doReturn(true).when(action).canWrite(any(File.class), any(File.class));
doReturn(false).when(action).verify(eq(file), anyString());
doNothing().when(action).download(any(HttpClient.class), anyString(), eq(file));
doReturn(true).when(action).verify(eq(file), anyString());
@ -202,6 +203,7 @@ public class TestDownloadAction {
DownloadAction action = spy(new DownloadAction(null));
doReturn(false).when(action).isActiveNetworkMetered(RuntimeEnvironment.application);
doReturn(true).when(action).canWrite(any(File.class), any(File.class));
File temporaryFile = mockFileWithSize(1337L);
doReturn(temporaryFile).when(action).createTemporaryFile(RuntimeEnvironment.application, content);
@ -301,6 +303,7 @@ public class TestDownloadAction {
File destinationFile = mockNotExistingFile();
doReturn(destinationFile).when(action).getDestinationFile(RuntimeEnvironment.application, content);
doReturn(true).when(action).canWrite(any(File.class), any(File.class));
doReturn(true).when(action).verify(eq(temporaryFile), anyString());
doNothing().when(action).extract(eq(temporaryFile), eq(destinationFile), anyString());
@ -333,6 +336,7 @@ public class TestDownloadAction {
DownloadAction action = spy(new DownloadAction(null));
doReturn(false).when(action).isActiveNetworkMetered(RuntimeEnvironment.application);
doReturn(true).when(action).canWrite(any(File.class), any(File.class));
doNothing().when(action).download(any(HttpClient.class), anyString(), any(File.class));
doReturn(false).when(action).verify(any(File.class), anyString());
@ -443,6 +447,7 @@ public class TestDownloadAction {
doReturn(mockNotExistingFile()).when(action).createTemporaryFile(RuntimeEnvironment.application, content);
doReturn(mockNotExistingFile()).when(action).getDestinationFile(RuntimeEnvironment.application, content);
doReturn(true).when(action).hasEnoughDiskSpace(eq(content), any(File.class), any(File.class));
doReturn(true).when(action).canWrite(any(File.class), any(File.class));
HttpClient client = mock(HttpClient.class);
doThrow(IOException.class).when(client).execute(any(HttpUriRequest.class));
@ -499,6 +504,32 @@ public class TestDownloadAction {
verify(catalog, times(11)).rememberFailure(eq(content), anyInt());
}
/**
* Scenario: Temporary or destination file is not writable.
*
* Verify that:
* * No download is performed
* * Error is counted as failure
*/
@Test
public void testNoDownIsPerformedIfFilesAreNotWritable() throws Exception{
DownloadContent content = createFont();
DownloadContentCatalog catalog = mockCatalogWithScheduledDownloads(content);
DownloadAction action = spy(new DownloadAction(null));
doReturn(true).when(action).isConnectedToNetwork(RuntimeEnvironment.application);
doReturn(false).when(action).isActiveNetworkMetered(RuntimeEnvironment.application);
doReturn(mockNotExistingFile()).when(action).createTemporaryFile(RuntimeEnvironment.application, content);
doReturn(mockNotExistingFile()).when(action).getDestinationFile(RuntimeEnvironment.application, content);
doReturn(false).when(action).canWrite(any(File.class), any(File.class));
action.perform(RuntimeEnvironment.application, catalog);
verify(action).canWrite(any(File.class), any(File.class));
verify(action, never()).download(any(HttpClient.class), anyString(), any(File.class));
verify(catalog).rememberFailure(eq(content), anyInt());
}
private DownloadContent createFont() {
return createFontWithSize(102400L);
}

View File

@ -159,7 +159,7 @@ public class AppMenuComponent extends BaseComponent {
* This method is dependent on not having two views with equivalent contentDescription / text.
*/
private View findAppMenuItemView(String text) {
mSolo.waitForText(text, 1, MAX_WAITTIME_FOR_MENU_UPDATE_IN_MS);
mSolo.waitForText(String.format("^%s$", text), 1, MAX_WAITTIME_FOR_MENU_UPDATE_IN_MS);
final List<View> views = mSolo.getViews();
@ -298,7 +298,8 @@ public class AppMenuComponent extends BaseComponent {
private boolean isLegacyMoreMenuOpen() {
// Check if the first menu option is visible.
return mSolo.searchText(mSolo.getString(R.string.share), true);
final String shareTitle = mSolo.getString(R.string.share);
return mSolo.searchText(String.format("^%s$", shareTitle), true);
}
/**
@ -310,7 +311,7 @@ public class AppMenuComponent extends BaseComponent {
*/
private boolean isMenuOpen(String menuItemTitle) {
final View menuItemView = findAppMenuItemView(menuItemTitle);
return isMenuOpen(menuItemView) ? true : mSolo.searchText(menuItemTitle, true);
return isMenuOpen(menuItemView) ? true : mSolo.searchText(String.format("^%s$", menuItemTitle), true);
}
/**

View File

@ -0,0 +1 @@
taskcluster

View File

@ -0,0 +1 @@
0.5.10

View File

@ -1,4 +1,4 @@
FROM taskcluster/builder:0.5.9
FROM taskcluster/builder:0.5.10
MAINTAINER Wander Lairson Costa <wcosta@mozilla.com>
ENV SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE /home/worker/socorro.token

View File

@ -1 +1 @@
0.0.22
0.0.23

View File

@ -19,7 +19,7 @@ task:
payload:
image: '{{#docker_image}}tester-device{{/docker_image}}'
maxRunTime: 3600
maxRunTime: 7200
cache:
tc-vcs: '/home/worker/.tc-vcs'
env:
@ -28,6 +28,7 @@ task:
GAIA_BASE_REPOSITORY: '{{{gaia_base_repository}}}'
GAIA_REF: '{{{gaia_ref}}}'
GAIA_REV: '{{{gaia_rev}}}'
TESTS_TIMEOUT_IN_MS: 30000
log: 'private/b2g/logs/live.log'
@ -43,6 +44,17 @@ task:
path: '/home/worker/upload/logs/'
expires: '{{#from_now}}1 year{{/from_now}}'
features:
testdroidProxy: true
capabilities:
devices:
phone:
type: 'flame'
memory: '512'
sims: '0'
build: '{{{img_url}}}'
extra:
treeherder:
groupSymbol: tc

View File

@ -11,13 +11,8 @@ task:
capabilities:
devices:
phone:
type: 'flame'
memory: '319'
sims: '1'
build: '{{{img_url}}}'
features:
testdroidProxy: true
maxRunTime: 7200
command:
- >
gaiatest
@ -30,7 +25,7 @@ task:
--address=$PROXY_HOST:$MARIONETTE_PORT
--device $SERIAL_ID
--xml-output=/home/worker/upload/logs/xml_output.xml
--timeout=10000
--timeout=$TESTS_TIMEOUT_IN_MS
--log-html=/home/worker/upload/logs/index.html
--restart
--type=b2g-dsds

View File

@ -11,13 +11,8 @@ task:
capabilities:
devices:
phone:
type: 'flame'
memory: '319'
sims: '2'
build: '{{{img_url}}}'
features:
testdroidProxy: true
maxRunTime: 7200
command:
- >
gaiatest
@ -28,7 +23,7 @@ task:
--address=$PROXY_HOST:$MARIONETTE_PORT
--device $SERIAL_ID
--xml-output=/home/worker/upload/logs/xml_output.xml
--timeout=10000
--timeout=$TESTS_TIMEOUT_IN_MS
--log-html=/home/worker/upload/logs/index.html
--restart
--type=b2g+dsds

View File

@ -12,13 +12,8 @@ task:
capabilities:
devices:
phone:
type: 'flame'
memory: '319'
sims: '1'
build: '{{{img_url}}}'
features:
testdroidProxy: true
maxRunTime: 7200
command:
- >
gaiatest
@ -29,7 +24,7 @@ task:
--address=$PROXY_HOST:$MARIONETTE_PORT
--device $SERIAL_ID
--xml-output=/home/worker/upload/logs/xml_output.xml
--timeout=10000
--timeout=$TESTS_TIMEOUT_IN_MS
--log-html=/home/worker/upload/logs/index.html
--restart
--type=b2g+sanity-dsds

View File

@ -8,16 +8,6 @@ task:
workerType: flame-kk-0-sim
payload:
capabilities:
devices:
phone:
type: 'flame'
memory: '319'
sims: '0'
build: '{{{img_url}}}'
features:
testdroidProxy: true
maxRunTime: 7200
command:
- >
gaiatest
@ -28,7 +18,7 @@ task:
--address=$PROXY_HOST:$MARIONETTE_PORT
--device $SERIAL_ID
--xml-output=/home/worker/upload/logs/xml_output.xml
--timeout=10000
--timeout=$TESTS_TIMEOUT_IN_MS
--log-html=/home/worker/upload/logs/index.html
--restart
--type=b2g

View File

@ -0,0 +1,125 @@
/* This Source Code Form is subject to the terms of the Mozilla Pub
* License, v. 2.0. If a copy of the MPL was not distributed with t
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/AlertNotification.h"
namespace mozilla {
NS_IMPL_CYCLE_COLLECTION(AlertNotification, mPrincipal)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AlertNotification)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAlertNotification)
NS_INTERFACE_MAP_ENTRY(nsIAlertNotification)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(AlertNotification)
NS_IMPL_CYCLE_COLLECTING_RELEASE(AlertNotification)
AlertNotification::AlertNotification()
: mTextClickable(false)
, mPrincipal(nullptr)
, mInPrivateBrowsing(false)
{}
AlertNotification::~AlertNotification()
{}
NS_IMETHODIMP
AlertNotification::Init(const nsAString& aName, const nsAString& aImageURL,
const nsAString& aTitle, const nsAString& aText,
bool aTextClickable, const nsAString& aCookie,
const nsAString& aDir, const nsAString& aLang,
const nsAString& aData, nsIPrincipal* aPrincipal,
bool aInPrivateBrowsing)
{
mName = aName;
mImageURL = aImageURL;
mTitle = aTitle;
mText = aText;
mTextClickable = aTextClickable;
mCookie = aCookie;
mDir = aDir;
mLang = aLang;
mData = aData;
mPrincipal = aPrincipal;
mInPrivateBrowsing = aInPrivateBrowsing;
return NS_OK;
}
NS_IMETHODIMP
AlertNotification::GetName(nsAString& aName)
{
aName = mName;
return NS_OK;
}
NS_IMETHODIMP
AlertNotification::GetImageURL(nsAString& aImageURL)
{
aImageURL = mImageURL;
return NS_OK;
}
NS_IMETHODIMP
AlertNotification::GetTitle(nsAString& aTitle)
{
aTitle = mTitle;
return NS_OK;
}
NS_IMETHODIMP
AlertNotification::GetText(nsAString& aText)
{
aText = mText;
return NS_OK;
}
NS_IMETHODIMP
AlertNotification::GetTextClickable(bool* aTextClickable)
{
*aTextClickable = mTextClickable;
return NS_OK;
}
NS_IMETHODIMP
AlertNotification::GetCookie(nsAString& aCookie)
{
aCookie = mCookie;
return NS_OK;
}
NS_IMETHODIMP
AlertNotification::GetDir(nsAString& aDir)
{
aDir = mDir;
return NS_OK;
}
NS_IMETHODIMP
AlertNotification::GetLang(nsAString& aLang)
{
aLang = mLang;
return NS_OK;
}
NS_IMETHODIMP
AlertNotification::GetData(nsAString& aData)
{
aData = mData;
return NS_OK;
}
NS_IMETHODIMP
AlertNotification::GetPrincipal(nsIPrincipal** aPrincipal)
{
NS_IF_ADDREF(*aPrincipal = mPrincipal);
return NS_OK;
}
NS_IMETHODIMP
AlertNotification::GetInPrivateBrowsing(bool* aInPrivateBrowsing)
{
*aInPrivateBrowsing = mInPrivateBrowsing;
return NS_OK;
}
} // namespace mozilla

View File

@ -0,0 +1,44 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_AlertNotification_h__
#define mozilla_AlertNotification_h__
#include "nsIAlertsService.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIPrincipal.h"
#include "nsString.h"
namespace mozilla {
class AlertNotification final : public nsIAlertNotification
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(AlertNotification,
nsIAlertNotification)
NS_DECL_NSIALERTNOTIFICATION
AlertNotification();
protected:
virtual ~AlertNotification();
private:
nsString mName;
nsString mImageURL;
nsString mTitle;
nsString mText;
bool mTextClickable;
nsString mCookie;
nsString mDir;
nsString mLang;
nsString mData;
nsCOMPtr<nsIPrincipal> mPrincipal;
bool mInPrivateBrowsing;
};
} // namespace mozilla
#endif /* mozilla_AlertNotification_h__ */

View File

@ -0,0 +1,119 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_AlertNotificationIPCSerializer_h__
#define mozilla_AlertNotificationIPCSerializer_h__
#include "nsComponentManagerUtils.h"
#include "nsCOMPtr.h"
#include "nsIAlertsService.h"
#include "nsIPrincipal.h"
#include "nsString.h"
#include "ipc/IPCMessageUtils.h"
#include "mozilla/dom/PermissionMessageUtils.h"
typedef nsIAlertNotification* AlertNotificationType;
namespace IPC {
template <>
struct ParamTraits<AlertNotificationType>
{
typedef AlertNotificationType paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
bool isNull = !aParam;
if (isNull) {
WriteParam(aMsg, isNull);
return;
}
nsString name, imageURL, title, text, cookie, dir, lang, data;
bool textClickable, inPrivateBrowsing;
nsCOMPtr<nsIPrincipal> principal;
if (NS_WARN_IF(NS_FAILED(aParam->GetName(name))) ||
NS_WARN_IF(NS_FAILED(aParam->GetImageURL(imageURL))) ||
NS_WARN_IF(NS_FAILED(aParam->GetTitle(title))) ||
NS_WARN_IF(NS_FAILED(aParam->GetText(text))) ||
NS_WARN_IF(NS_FAILED(aParam->GetTextClickable(&textClickable))) ||
NS_WARN_IF(NS_FAILED(aParam->GetCookie(cookie))) ||
NS_WARN_IF(NS_FAILED(aParam->GetDir(dir))) ||
NS_WARN_IF(NS_FAILED(aParam->GetLang(lang))) ||
NS_WARN_IF(NS_FAILED(aParam->GetData(data))) ||
NS_WARN_IF(NS_FAILED(aParam->GetPrincipal(getter_AddRefs(principal)))) ||
NS_WARN_IF(NS_FAILED(aParam->GetInPrivateBrowsing(&inPrivateBrowsing)))) {
// Write a `null` object if any getter returns an error. Otherwise, the
// receiver will try to deserialize an incomplete object and crash.
WriteParam(aMsg, /* isNull */ true);
return;
}
WriteParam(aMsg, isNull);
WriteParam(aMsg, name);
WriteParam(aMsg, imageURL);
WriteParam(aMsg, title);
WriteParam(aMsg, text);
WriteParam(aMsg, textClickable);
WriteParam(aMsg, cookie);
WriteParam(aMsg, dir);
WriteParam(aMsg, lang);
WriteParam(aMsg, data);
WriteParam(aMsg, IPC::Principal(principal));
WriteParam(aMsg, inPrivateBrowsing);
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
{
bool isNull;
NS_ENSURE_TRUE(ReadParam(aMsg, aIter, &isNull), false);
if (isNull) {
*aResult = nullptr;
return true;
}
nsString name, imageURL, title, text, cookie, dir, lang, data;
bool textClickable, inPrivateBrowsing;
IPC::Principal principal;
if (!ReadParam(aMsg, aIter, &name) ||
!ReadParam(aMsg, aIter, &imageURL) ||
!ReadParam(aMsg, aIter, &title) ||
!ReadParam(aMsg, aIter, &text) ||
!ReadParam(aMsg, aIter, &textClickable) ||
!ReadParam(aMsg, aIter, &cookie) ||
!ReadParam(aMsg, aIter, &dir) ||
!ReadParam(aMsg, aIter, &lang) ||
!ReadParam(aMsg, aIter, &data) ||
!ReadParam(aMsg, aIter, &principal) ||
!ReadParam(aMsg, aIter, &inPrivateBrowsing)) {
return false;
}
nsCOMPtr<nsIAlertNotification> alert =
do_CreateInstance(ALERT_NOTIFICATION_CONTRACTID);
if (NS_WARN_IF(!alert)) {
*aResult = nullptr;
return true;
}
nsresult rv = alert->Init(name, imageURL, title, text, textClickable,
cookie, dir, lang, data, principal,
inPrivateBrowsing);
if (NS_WARN_IF(NS_FAILED(rv))) {
*aResult = nullptr;
return true;
}
alert.forget(aResult);
return true;
}
};
} // namespace IPC
#endif /* mozilla_AlertNotificationIPCSerializer_h__ */

View File

@ -16,7 +16,13 @@ EXPORTS += [
'nsAlertsUtils.h',
]
EXPORTS.mozilla += [
'AlertNotification.h',
'AlertNotificationIPCSerializer.h',
]
UNIFIED_SOURCES += [
'AlertNotification.cpp',
'nsAlertsService.cpp',
'nsAlertsUtils.cpp',
'nsXULAlerts.cpp',

View File

@ -73,40 +73,66 @@ NS_IMETHODIMP nsAlertsService::ShowAlertNotification(const nsAString & aImageUrl
nsIPrincipal * aPrincipal,
bool aInPrivateBrowsing)
{
nsCOMPtr<nsIAlertNotification> alert =
do_CreateInstance(ALERT_NOTIFICATION_CONTRACTID);
NS_ENSURE_TRUE(alert, NS_ERROR_FAILURE);
nsresult rv = alert->Init(aAlertName, aImageUrl, aAlertTitle,
aAlertText, aAlertTextClickable,
aAlertCookie, aBidi, aLang, aData,
aPrincipal, aInPrivateBrowsing);
NS_ENSURE_SUCCESS(rv, rv);
return ShowAlert(alert, aAlertListener);
}
NS_IMETHODIMP nsAlertsService::ShowAlert(nsIAlertNotification * aAlert,
nsIObserver * aAlertListener)
{
NS_ENSURE_ARG(aAlert);
nsAutoString cookie;
nsresult rv = aAlert->GetCookie(cookie);
NS_ENSURE_SUCCESS(rv, rv);
if (XRE_IsContentProcess()) {
ContentChild* cpc = ContentChild::GetSingleton();
if (aAlertListener)
cpc->AddRemoteAlertObserver(PromiseFlatString(aAlertCookie), aAlertListener);
cpc->AddRemoteAlertObserver(cookie, aAlertListener);
cpc->SendShowAlertNotification(PromiseFlatString(aImageUrl),
PromiseFlatString(aAlertTitle),
PromiseFlatString(aAlertText),
aAlertTextClickable,
PromiseFlatString(aAlertCookie),
PromiseFlatString(aAlertName),
PromiseFlatString(aBidi),
PromiseFlatString(aLang),
PromiseFlatString(aData),
IPC::Principal(aPrincipal),
aInPrivateBrowsing);
cpc->SendShowAlert(aAlert);
return NS_OK;
}
nsAutoString imageUrl;
rv = aAlert->GetImageURL(imageUrl);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString title;
rv = aAlert->GetTitle(title);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString text;
rv = aAlert->GetText(text);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString name;
rv = aAlert->GetName(name);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrincipal> principal;
rv = aAlert->GetPrincipal(getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
#ifdef MOZ_WIDGET_ANDROID
mozilla::AndroidBridge::Bridge()->ShowAlertNotification(aImageUrl, aAlertTitle, aAlertText, aAlertCookie,
aAlertListener, aAlertName, aPrincipal);
mozilla::AndroidBridge::Bridge()->ShowAlertNotification(imageUrl, title, text, cookie,
aAlertListener, name, principal);
return NS_OK;
#else
// Check if there is an optional service that handles system-level notifications
nsCOMPtr<nsIAlertsService> sysAlerts(do_GetService(NS_SYSTEMALERTSERVICE_CONTRACTID));
nsresult rv;
if (sysAlerts) {
rv = sysAlerts->ShowAlertNotification(aImageUrl, aAlertTitle, aAlertText, aAlertTextClickable,
aAlertCookie, aAlertListener, aAlertName,
aBidi, aLang, aData,
IPC::Principal(aPrincipal),
aInPrivateBrowsing);
rv = sysAlerts->ShowAlert(aAlert, aAlertListener);
if (NS_SUCCEEDED(rv))
return NS_OK;
}
@ -114,14 +140,30 @@ NS_IMETHODIMP nsAlertsService::ShowAlertNotification(const nsAString & aImageUrl
if (!ShouldShowAlert()) {
// Do not display the alert. Instead call alertfinished and get out.
if (aAlertListener)
aAlertListener->Observe(nullptr, "alertfinished", PromiseFlatString(aAlertCookie).get());
aAlertListener->Observe(nullptr, "alertfinished", cookie.get());
return NS_OK;
}
bool textClickable;
rv = aAlert->GetTextClickable(&textClickable);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString bidi;
rv = aAlert->GetDir(bidi);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString lang;
rv = aAlert->GetLang(lang);
NS_ENSURE_SUCCESS(rv, rv);
bool inPrivateBrowsing;
rv = aAlert->GetInPrivateBrowsing(&inPrivateBrowsing);
NS_ENSURE_SUCCESS(rv, rv);
// Use XUL notifications as a fallback if above methods have failed.
rv = mXULAlerts.ShowAlertNotification(aImageUrl, aAlertTitle, aAlertText, aAlertTextClickable,
aAlertCookie, aAlertListener, aAlertName,
aBidi, aLang, aPrincipal, aInPrivateBrowsing);
rv = mXULAlerts.ShowAlertNotification(imageUrl, title, text, textClickable,
cookie, aAlertListener, name,
bidi, lang, principal, inPrivateBrowsing);
return rv;
#endif // !MOZ_WIDGET_ANDROID
}

View File

@ -8,9 +8,96 @@
interface nsIPrincipal;
[scriptable, uuid(9d0284bf-db40-42da-8f0d-c2769dbde7aa)]
%{C++
#define ALERT_NOTIFICATION_CONTRACTID "@mozilla.org/alert-notification;1"
%}
[scriptable, uuid(b26b4a67-81b0-4270-8311-1e00a097ef92)]
interface nsIAlertNotification : nsISupports
{
/** Initializes an alert notification. */
void init([optional] in AString name,
[optional] in AString imageURL,
[optional] in AString title,
[optional] in AString text,
[optional] in boolean textClickable,
[optional] in AString cookie,
[optional] in AString dir,
[optional] in AString lang,
[optional] in AString data,
[optional] in nsIPrincipal principal,
[optional] in boolean inPrivateBrowsing);
/**
* The name of the notification. This is currently only used on Android and
* OS X. On Android, the name is hashed and used as a notification ID.
* Notifications will replace previous notifications with the same name.
*/
readonly attribute AString name;
/**
* A URL identifying the image to put in the alert. The OS X backend limits
* the amount of time it will wait for the image to load to six seconds. After
* that time, the alert will show without an image.
*/
readonly attribute AString imageURL;
/** The title for the alert. */
readonly attribute AString title;
/** The contents of the alert. */
readonly attribute AString text;
/**
* Controls the click behavior. If true, the alert listener will be notified
* when the user clicks on the alert.
*/
readonly attribute boolean textClickable;
/**
* An opaque cookie that will be passed to the alert listener for each
* callback.
*/
readonly attribute AString cookie;
/**
* Bidi override for the title and contents. Valid values are "auto", "ltr",
* or "rtl". Ignored if the backend doesn't support localization.
*/
readonly attribute AString dir;
/**
* Language of the title and text. Ignored if the backend doesn't support
* localization.
*/
readonly attribute AString lang;
/**
* A Base64-encoded structured clone buffer containing data associated with
* this alert. Only used for web notifications. Chrome callers should use a
* cookie instead.
*/
readonly attribute AString data;
/**
* The principal of the page that created the alert. Used for IPC security
* checks, and to determine whether the alert should show the source string
* and action buttons.
*/
readonly attribute nsIPrincipal principal;
/**
* Controls the image loading behavior. If true, the image URL will be loaded
* in private browsing mode.
*/
readonly attribute boolean inPrivateBrowsing;
};
[scriptable, uuid(f7a36392-d98b-4141-a7d7-4e46642684e3)]
interface nsIAlertsService : nsISupports
{
void showAlert(in nsIAlertNotification alert,
[optional] in nsIObserver alertListener);
/**
* Displays a sliding notification window.
*

View File

@ -97,6 +97,9 @@
/////////////////////////////////////////////////////////////////////////////
#define ALERT_NOTIFICATION_CID \
{ 0x9a7b7a41, 0x0b47, 0x47f7, { 0xb6, 0x1b, 0x15, 0xa2, 0x10, 0xd6, 0xf0, 0x20 } }
// {A0CCAAF8-09DA-44D8-B250-9AC3E93C8117}
#define NS_ALERTSSERVICE_CID \
{ 0xa0ccaaf8, 0x9da, 0x44d8, { 0xb2, 0x50, 0x9a, 0xc3, 0xe9, 0x3c, 0x81, 0x17 } }

View File

@ -16,6 +16,7 @@
#include "nsParentalControlsService.h"
#endif
#include "mozilla/AlertNotification.h"
#include "nsAlertsService.h"
#include "nsDownloadManager.h"
@ -82,6 +83,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsFindService)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsParentalControlsService)
#endif
NS_GENERIC_FACTORY_CONSTRUCTOR(AlertNotification)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAlertsService)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsDownloadManager,
@ -138,6 +140,7 @@ NS_DEFINE_NAMED_CID(NS_TOOLKIT_PERFORMANCESTATSSERVICE_CID);
NS_DEFINE_NAMED_CID(NS_TOOLKIT_TERMINATOR_CID);
#endif
NS_DEFINE_NAMED_CID(NS_USERINFO_CID);
NS_DEFINE_NAMED_CID(ALERT_NOTIFICATION_CID);
NS_DEFINE_NAMED_CID(NS_ALERTSSERVICE_CID);
#if !defined(MOZ_DISABLE_PARENTAL_CONTROLS)
NS_DEFINE_NAMED_CID(NS_PARENTALCONTROLSSERVICE_CID);
@ -173,6 +176,7 @@ static const Module::CIDEntry kToolkitCIDs[] = {
{ &kNS_TOOLKIT_PERFORMANCESTATSSERVICE_CID, false, nullptr, nsPerformanceStatsServiceConstructor },
#endif // defined (MOZ_HAS_PERFSTATS)
{ &kNS_USERINFO_CID, false, nullptr, nsUserInfoConstructor },
{ &kALERT_NOTIFICATION_CID, false, nullptr, AlertNotificationConstructor },
{ &kNS_ALERTSSERVICE_CID, false, nullptr, nsAlertsServiceConstructor },
#if !defined(MOZ_DISABLE_PARENTAL_CONTROLS)
{ &kNS_PARENTALCONTROLSSERVICE_CID, false, nullptr, nsParentalControlsServiceConstructor },
@ -210,6 +214,7 @@ static const Module::ContractIDEntry kToolkitContracts[] = {
{ NS_TOOLKIT_PERFORMANCESTATSSERVICE_CONTRACTID, &kNS_TOOLKIT_PERFORMANCESTATSSERVICE_CID },
#endif // defined (MOZ_HAS_PERFSTATS)
{ NS_USERINFO_CONTRACTID, &kNS_USERINFO_CID },
{ ALERT_NOTIFICATION_CONTRACTID, &kALERT_NOTIFICATION_CID },
{ NS_ALERTSERVICE_CONTRACTID, &kNS_ALERTSSERVICE_CID },
#if !defined(MOZ_DISABLE_PARENTAL_CONTROLS)
{ NS_PARENTALCONTROLSSERVICE_CONTRACTID, &kNS_PARENTALCONTROLSSERVICE_CID },

Some files were not shown because too many files have changed in this diff Show More