Merge autoland to mozilla-central. a=merge

This commit is contained in:
Csoregi Natalia 2018-10-05 01:28:23 +03:00
commit add33e25e6
66 changed files with 1456 additions and 464 deletions

View File

@ -1256,7 +1256,6 @@ pref("browser.newtabpage.activity-stream.fxaccounts.endpoint", "https://accounts
pref("browser.newtabpage.activity-stream.improvesearch.topSiteSearchShortcuts", true);
#else
pref("browser.newtabpage.activity-stream.improvesearch.topSiteSearchShortcuts", false);
#else
#endif
// Enable the DOM fullscreen API.

View File

@ -267,7 +267,7 @@
accesskey="&sendPageToDevice.accesskey;"
hidden="true">
<menupopup id="context-sendpagetodevice-popup"
onpopupshowing="(() => { gSync.populateSendTabToDevicesMenu(event.target, gBrowser.currentURI.spec, gBrowser.contentTitle, gBrowser.selectedTab.multiselected); })()"/>
onpopupshowing="(() => { gSync.populateSendTabToDevicesMenu(event.target, gBrowser.currentURI.spec, gBrowser.contentTitle); })()"/>
</menu>
<menuseparator id="context-sep-viewbgimage"/>
<menuitem id="context-viewbgimage"

View File

@ -179,7 +179,7 @@ xmlns="http://www.w3.org/1999/xhtml"
<menu id="context_sendTabToDevice"
class="sync-ui-item">
<menupopup id="context_sendTabToDevicePopupMenu"
onpopupshowing="gSync.populateSendTabToDevicesMenu(event.target, TabContextMenu.contextTab);"/>
onpopupshowing="gSync.populateSendTabToDevicesMenu(event.target, TabContextMenu.contextTab.linkedBrowser.currentURI.spec, TabContextMenu.contextTab.linkedBrowser.contentTitle, TabContextMenu.contextTab.multiselected);"/>
</menu>
<menuseparator/>
<menuitem id="context_reloadAllTabs" label="&reloadAllTabs.label;" accesskey="&reloadAllTabs.accesskey;"

View File

@ -26,20 +26,31 @@ add_task(async function setup() {
await promiseSyncReady();
// gSync.init() is called in a requestIdleCallback. Force its initialization.
gSync.init();
is(gBrowser.visibleTabs.length, 1, "there is one visible tab");
sinon.stub(Weave.Service.clientsEngine, "getClientType").returns("desktop");
await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
registerCleanupFunction(() => {
gBrowser.removeCurrentTab();
});
is(gBrowser.visibleTabs.length, 2, "there are two visible tabs");
});
// We are not testing the devices popup contents, since it is already tested by
// browser_contextmenu_sendpage.js and the code to populate it is the same.
add_task(async function test_tab_contextmenu() {
const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: true, remoteClients: remoteClientsFixture,
state: UIState.STATUS_SIGNED_IN, isSendableURI: true });
let expectation = sandbox.mock(gSync)
.expects("sendTabToDevice")
.once()
.withExactArgs("about:mozilla", [{id: 1, name: "Foo"}], "The Book of Mozilla, 11:14");
updateTabContextMenu(testTab);
await openTabContextMenu("context_sendTabToDevice");
is(document.getElementById("context_sendTabToDevice").hidden, false, "Send tab to device is shown");
is(document.getElementById("context_sendTabToDevice").disabled, false, "Send tab to device is enabled");
document.getElementById("context_sendTabToDevicePopupMenu").querySelector("menuitem").click();
await hideTabContextMenu();
expectation.verify();
sandbox.restore();
});
@ -109,3 +120,26 @@ add_task(async function test_tab_contextmenu_fxa_disabled() {
getter.restore();
[...document.querySelectorAll(".sync-ui-item")].forEach(e => e.hidden = false);
});
async function openTabContextMenu(openSubmenuId = null) {
const contextMenu = document.getElementById("tabContextMenu");
is(contextMenu.state, "closed", "checking if popup is closed");
const awaitPopupShown = BrowserTestUtils.waitForEvent(contextMenu, "popupshown");
EventUtils.synthesizeMouseAtCenter(gBrowser.selectedTab, {type: "contextmenu", button: 2});
await awaitPopupShown;
if (openSubmenuId) {
const menuPopup = document.getElementById(openSubmenuId).menupopup;
const menuPopupPromise = BrowserTestUtils.waitForEvent(menuPopup, "popupshown");
menuPopup.openPopup();
await menuPopupPromise;
}
}
async function hideTabContextMenu() {
const contextMenu = document.getElementById("tabContextMenu");
const awaitPopupHidden = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden");
contextMenu.hidePopup();
await awaitPopupHidden;
}

View File

@ -765,7 +765,7 @@ var Policies = {
try {
pkcs11.addModule(deviceName, securityDevices[deviceName], 0, 0);
} catch (ex) {
log.error("Unable to add security device ${deviceName}");
log.error(`Unable to add security device ${deviceName}`);
log.debug(ex);
}
}

View File

@ -19,6 +19,7 @@ async function setDefaultTopSites() { // eslint-disable-line no-unused-vars
// Toggle the feed off and on as a workaround to read the new prefs.
await pushPrefs(["browser.newtabpage.activity-stream.feeds.topsites", false]);
await pushPrefs(["browser.newtabpage.activity-stream.feeds.topsites", true]);
await pushPrefs(["browser.newtabpage.activity-stream.improvesearch.topSiteSearchShortcuts", true]);
}
async function clearHistoryAndBookmarks() { // eslint-disable-line no-unused-vars

View File

@ -104,6 +104,7 @@ class UrlbarInput {
this.inputField.addEventListener("blur", this);
this.inputField.addEventListener("focus", this);
this.inputField.addEventListener("mousedown", this);
this.inputField.addEventListener("mouseover", this);
this.inputField.addEventListener("overflow", this);
this.inputField.addEventListener("underflow", this);
this.inputField.addEventListener("scrollend", this);
@ -210,6 +211,14 @@ class UrlbarInput {
});
}
_updateUrlTooltip() {
if (this.focused || !this._inOverflow) {
this.inputField.removeAttribute("title");
} else {
this.inputField.setAttribute("title", this.value);
}
}
_getSelectedValueForClipboard() {
// Grab the actual input field's value, not our value, which could
// include "moz-action:".
@ -328,9 +337,15 @@ class UrlbarInput {
}
_on_focus(event) {
this._updateUrlTooltip();
this.formatValue();
}
_on_mouseover(event) {
this._updateUrlTooltip();
}
_on_mousedown(event) {
if (event.button == 0 &&
event.detail == 2 &&
@ -390,7 +405,10 @@ class UrlbarInput {
return;
}
this._inOverflow = false;
this._updateTextOverflow();
this._updateUrlTooltip();
}
_on_scrollend(event) {

View File

@ -110,6 +110,9 @@ policy-SearchBar = Set the default location of the search bar. The user is still
policy-SearchEngines = Configure search engine settings. This policy is only available on the Extended Support Release (ESR) version.
# For more information, see https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/PKCS11/Module_Installation
policy-SecurityDevices = Install PKCS #11 modules.
# “format” refers to the format used for the value of this policy. See also:
# https://github.com/mozilla/policy-templates/blob/master/README.md#websitefilter-machine-only
policy-WebsiteFilter = Block websites from being visited. See documentation for more details on the format.

View File

@ -5,7 +5,7 @@
"use strict";
const { ADBScanner } = require("devtools/shared/adb/adb-scanner");
const { GetAvailableAddons } = require("devtools/client/webide/modules/addons");
loader.lazyRequireGetter(this, "adbAddon", "devtools/shared/adb/adb-addon", true);
/**
* This module provides a collection of helper methods to detect USB runtimes whom Firefox
@ -22,8 +22,7 @@ function disableUSBRuntimes() {
exports.disableUSBRuntimes = disableUSBRuntimes;
async function enableUSBRuntimes() {
const { adb } = GetAvailableAddons();
if (adb.status !== "installed") {
if (adbAddon.status !== "installed") {
console.error("ADB extension is not installed");
return;
}

View File

@ -175,6 +175,11 @@ class App extends PureComponent {
}
onResizeViewport(id, width, height) {
window.postMessage({
type: "viewport-resize",
width,
height,
}, "*");
this.props.dispatch(resizeViewport(id, width, height));
}

View File

@ -533,6 +533,9 @@ ResponsiveUI.prototype = {
case "remove-device-association":
this.onRemoveDeviceAssociation(event);
break;
case "viewport-resize":
this.onViewportResize(event);
break;
}
},
@ -611,6 +614,14 @@ ResponsiveUI.prototype = {
this.emit("device-association-removed");
},
onViewportResize(event) {
const { width, height } = event.data;
this.emit("viewport-resize", {
width,
height,
});
},
/**
* Set or clear the emulated device pixel ratio.
*
@ -669,12 +680,18 @@ ResponsiveUI.prototype = {
* Whether a reload is needed to apply the change.
*/
updateTouchSimulation(enabled) {
if (!enabled) {
return this.emulationFront.clearTouchEventsOverride();
let reloadNeeded;
if (enabled) {
reloadNeeded = this.emulationFront.setTouchEventsOverride(
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_ENABLED
).then(() => this.emulationFront.setMetaViewportOverride(
Ci.nsIDocShell.META_VIEWPORT_OVERRIDE_ENABLED
));
} else {
reloadNeeded = this.emulationFront.clearTouchEventsOverride()
.then(() => this.emulationFront.clearMetaViewportOverride());
}
return this.emulationFront.setTouchEventsOverride(
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_ENABLED
);
return reloadNeeded;
},
/**

View File

@ -137,35 +137,39 @@ function waitForViewportResizeTo(ui, width, height) {
const isSizeMatching = data => data.width == width && data.height == height;
// If the viewport has already the expected size, we resolve the promise immediately.
const size = await getContentSize(ui);
const size = ui.getViewportSize();
if (isSizeMatching(size)) {
info(`Content already resized to ${width} x ${height}`);
info(`Viewport already resized to ${width} x ${height}`);
resolve();
return;
}
// Otherwise, we'll listen to both content's resize event and browser's load end;
// since a racing condition can happen, where the content's listener is added after
// the resize, because the content's document was reloaded; therefore the test would
// hang forever. See bug 1302879.
// Otherwise, we'll listen to the content's resize event, the viewport's resize event,
// and the browser's load end; since a racing condition can happen, where the
// content's listener is added after the resize, because the content's document was
// reloaded; therefore the test would hang forever. See bug 1302879.
const browser = ui.getViewportBrowser();
const onResize = data => {
if (!isSizeMatching(data)) {
return;
}
ui.off("viewport-resize", onResize);
ui.off("content-resize", onResize);
browser.removeEventListener("mozbrowserloadend", onBrowserLoadEnd);
info(`Got content-resize to ${width} x ${height}`);
info(`Got content-resize or viewport-resize to ${width} x ${height}`);
resolve();
};
const onBrowserLoadEnd = async function() {
const data = await getContentSize(ui);
const data = ui.getViewportSize(ui);
onResize(data);
};
info(`Waiting for content-resize to ${width} x ${height}`);
info(`Waiting for content-resize or viewport-resize to ${width} x ${height}`);
// Depending on whether or not the viewport is overridden, we'll either get a
// viewport-resize event or a content-resize event.
ui.on("viewport-resize", onResize);
ui.on("content-resize", onResize);
browser.addEventListener("mozbrowserloadend",
onBrowserLoadEnd, { once: true });

View File

@ -2,14 +2,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
const {loader, require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
const Services = require("Services");
const {gDevTools} = require("devtools/client/framework/devtools");
const {GetAvailableAddons, ForgetAddonsList} = require("devtools/client/webide/modules/addons");
const Strings = Services.strings.createBundle("chrome://devtools/locale/webide.properties");
const {gDevTools} = require("devtools/client/framework/devtools");
const {ADBScanner} = require("devtools/shared/adb/adb-scanner");
const {RuntimeScanners} = require("devtools/client/webide/modules/runtimes");
loader.lazyRequireGetter(this, "adbAddon", "devtools/shared/adb/adb-addon", true);
window.addEventListener("load", function() {
document.querySelector("#aboutaddons").onclick = function() {
const browserWin = Services.wm.getMostRecentWindow(gDevTools.chromeWindowType);
@ -18,29 +21,21 @@ window.addEventListener("load", function() {
}
};
document.querySelector("#close").onclick = CloseUI;
BuildUI(GetAvailableAddons());
}, {capture: true, once: true});
window.addEventListener("unload", function() {
ForgetAddonsList();
BuildUI();
}, {capture: true, once: true});
function CloseUI() {
window.parent.UI.openProject();
}
function BuildUI(addons) {
BuildItem(addons.adb, "adb");
}
function BuildItem(addon, type) {
function BuildUI() {
function onAddonUpdate(arg) {
progress.removeAttribute("value");
li.setAttribute("status", addon.status);
status.textContent = Strings.GetStringFromName("addons_status_" + addon.status);
if (addon.status == "installed") {
li.setAttribute("status", adbAddon.status);
status.textContent = Strings.GetStringFromName("addons_status_" + adbAddon.status);
if (adbAddon.status == "installed") {
RuntimeScanners.add(ADBScanner);
} else if (addon.status == "uninstalled") {
} else if (adbAddon.status == "uninstalled") {
RuntimeScanners.remove(ADBScanner);
}
}
@ -57,57 +52,51 @@ function BuildItem(addon, type) {
}
}
addon.on("update", onAddonUpdate);
addon.on("failure", onAddonFailure);
addon.on("progress", onAddonProgress);
adbAddon.on("update", onAddonUpdate);
adbAddon.on("failure", onAddonFailure);
adbAddon.on("progress", onAddonProgress);
window.addEventListener("unload", function() {
addon.off("update", onAddonUpdate);
addon.off("failure", onAddonFailure);
addon.off("progress", onAddonProgress);
adbAddon.off("update", onAddonUpdate);
adbAddon.off("failure", onAddonFailure);
adbAddon.off("progress", onAddonProgress);
}, {once: true});
const li = document.createElement("li");
li.setAttribute("status", addon.status);
li.setAttribute("status", adbAddon.status);
const name = document.createElement("span");
name.className = "name";
switch (type) {
case "adb":
li.setAttribute("addon", type);
name.textContent = "ADB Extension";
break;
}
li.setAttribute("addon", "adb");
name.textContent = "ADB Extension";
li.appendChild(name);
const status = document.createElement("span");
status.className = "status";
status.textContent = Strings.GetStringFromName("addons_status_" + addon.status);
status.textContent = Strings.GetStringFromName("addons_status_" + adbAddon.status);
li.appendChild(status);
const installButton = document.createElement("button");
installButton.className = "install-button";
installButton.onclick = () => addon.install();
installButton.onclick = () => adbAddon.install("webide");
installButton.textContent = Strings.GetStringFromName("addons_install_button");
li.appendChild(installButton);
const uninstallButton = document.createElement("button");
uninstallButton.className = "uninstall-button";
uninstallButton.onclick = () => addon.uninstall();
uninstallButton.onclick = () => adbAddon.uninstall();
uninstallButton.textContent = Strings.GetStringFromName("addons_uninstall_button");
li.appendChild(uninstallButton);
const progress = document.createElement("progress");
li.appendChild(progress);
if (type == "adb") {
const warning = document.createElement("p");
warning.textContent = Strings.GetStringFromName("addons_adb_warning");
warning.className = "warning";
li.appendChild(warning);
}
const warning = document.createElement("p");
warning.textContent = Strings.GetStringFromName("addons_adb_warning");
warning.className = "warning";
li.appendChild(warning);
document.querySelector("ul").appendChild(li);
}

View File

@ -6,7 +6,7 @@
/* import-globals-from project-panel.js */
/* import-globals-from runtime-panel.js */
const {require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
const {loader, require} = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
const {gDevTools} = require("devtools/client/framework/devtools");
const {gDevToolsBrowser} = require("devtools/client/framework/devtools-browser");
const {Toolbox} = require("devtools/client/framework/toolbox");
@ -16,12 +16,13 @@ const {Connection} = require("devtools/shared/client/connection-manager");
const {AppManager} = require("devtools/client/webide/modules/app-manager");
const EventEmitter = require("devtools/shared/event-emitter");
const promise = require("promise");
const {GetAvailableAddons} = require("devtools/client/webide/modules/addons");
const {getJSON} = require("devtools/client/shared/getjson");
const Telemetry = require("devtools/client/shared/telemetry");
const {RuntimeScanners} = require("devtools/client/webide/modules/runtimes");
const {openContentLink} = require("devtools/client/shared/link");
loader.lazyRequireGetter(this, "adbAddon", "devtools/shared/adb/adb-addon", true);
const Strings =
Services.strings.createBundle("chrome://devtools/locale/webide.properties");
@ -86,8 +87,7 @@ var UI = {
// If the user decides to uninstall any of this addon, we won't install it again.
const autoinstallADBExtension = Services.prefs.getBoolPref("devtools.webide.autoinstallADBExtension");
if (autoinstallADBExtension) {
const addons = GetAvailableAddons();
addons.adb.install();
adbAddon.install("webide");
}
Services.prefs.setBoolPref("devtools.webide.autoinstallADBExtension", false);

View File

@ -5,7 +5,6 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'addons.js',
'app-manager.js',
'app-projects.js',
'app-validator.js',

View File

@ -35,6 +35,7 @@ const EmulationActor = protocol.ActorClassWithSpec(emulationSpec, {
this.clearDPPXOverride();
this.clearNetworkThrottling();
this.clearTouchEventsOverride();
this.clearMetaViewportOverride();
this.clearUserAgentOverride();
this.targetActor = null;
this.docShell = null;
@ -206,6 +207,33 @@ const EmulationActor = protocol.ActorClassWithSpec(emulationSpec, {
return false;
},
/* Meta viewport override */
_previousMetaViewportOverride: undefined,
setMetaViewportOverride(flag) {
if (this.getMetaViewportOverride() == flag) {
return false;
}
if (this._previousMetaViewportOverride === undefined) {
this._previousMetaViewportOverride = this.getMetaViewportOverride();
}
this.docShell.metaViewportOverride = flag;
return true;
},
getMetaViewportOverride() {
return this.docShell.metaViewportOverride;
},
clearMetaViewportOverride() {
if (this._previousMetaViewportOverride !== undefined) {
return this.setMetaViewportOverride(this._previousMetaViewportOverride);
}
return false;
},
/* User agent override */
_previousUserAgentOverride: undefined,

View File

@ -7,18 +7,12 @@
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
add_task(async function() {
// This test runs very slowly on linux32 debug EC2 instances.
requestLongerTimeout(2);
await addTab(MAIN_DOMAIN + "doc_force_cc.html");
initDebuggerServer();
const client = new DebuggerClient(DebuggerServer.connectPipe());
const form = await connectDebuggerClient(client);
const front = PerformanceFront(client, form);
const target = await addTabTarget(MAIN_DOMAIN + "doc_force_cc.html");
const front = target.getFront("performance");
await front.connect();
const rec = await front.startRecording({ withMarkers: true });
@ -31,6 +25,6 @@ add_task(async function() {
ok(markers.some(m => m.name === "nsCycleCollector::ForgetSkippable"),
"got some nsCycleCollector::Collect markers");
await client.close();
await target.destroy();
gBrowser.removeCurrentTab();
});

View File

@ -6,16 +6,11 @@
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
const MARKER_NAME = "GarbageCollection";
add_task(async function() {
await addTab(MAIN_DOMAIN + "doc_force_gc.html");
initDebuggerServer();
const client = new DebuggerClient(DebuggerServer.connectPipe());
const form = await connectDebuggerClient(client);
const front = PerformanceFront(client, form);
const target = await addTabTarget(MAIN_DOMAIN + "doc_force_gc.html");
const front = target.getFront("performance");
await front.connect();
const rec = await front.startRecording({ withMarkers: true });
@ -46,6 +41,6 @@ add_task(async function() {
is(ordered, true, "All GC and non-GC markers are in order by start time.");
await client.close();
await target.destroy();
gBrowser.removeCurrentTab();
});

View File

@ -7,18 +7,12 @@
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
add_task(async function() {
// This test runs very slowly on linux32 debug EC2 instances.
requestLongerTimeout(2);
await addTab(MAIN_DOMAIN + "doc_allocations.html");
initDebuggerServer();
const client = new DebuggerClient(DebuggerServer.connectPipe());
const form = await connectDebuggerClient(client);
const front = PerformanceFront(client, form);
const target = await addTabTarget(MAIN_DOMAIN + "doc_allocations.html");
const front = target.getFront("performance");
await front.connect();
const rec = await front.startRecording({ withMarkers: true });
@ -28,6 +22,6 @@ add_task(async function() {
ok(markers.some(m => m.name === "MinorGC" && m.causeName),
"got some MinorGC markers");
await client.close();
await target.destroy();
gBrowser.removeCurrentTab();
});

View File

@ -6,16 +6,12 @@
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
const MARKER_NAME = "Parse HTML";
add_task(async function() {
await addTab(MAIN_DOMAIN + "doc_innerHTML.html");
const target = await addTabTarget(MAIN_DOMAIN + "doc_innerHTML.html");
initDebuggerServer();
const client = new DebuggerClient(DebuggerServer.connectPipe());
const form = await connectDebuggerClient(client);
const front = PerformanceFront(client, form);
const front = target.getFront("performance");
await front.connect();
const rec = await front.startRecording({ withMarkers: true });
@ -24,6 +20,6 @@ add_task(async function() {
ok(markers.some(m => m.name === MARKER_NAME), `got some ${MARKER_NAME} markers`);
await client.close();
await target.destroy();
gBrowser.removeCurrentTab();
});

View File

@ -6,16 +6,12 @@
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
const MARKER_NAME = "Styles";
add_task(async function() {
await addTab(MAIN_DOMAIN + "doc_perf.html");
const target = await addTabTarget(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
const client = new DebuggerClient(DebuggerServer.connectPipe());
const form = await connectDebuggerClient(client);
const front = PerformanceFront(client, form);
const front = target.getFront("performance");
await front.connect();
const rec = await front.startRecording({ withMarkers: true });
@ -25,6 +21,6 @@ add_task(async function() {
ok(markers.some(m => m.name === MARKER_NAME), `got some ${MARKER_NAME} markers`);
await client.close();
await target.destroy();
gBrowser.removeCurrentTab();
});

View File

@ -6,18 +6,14 @@
*/
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
const { pmmConsoleMethod, pmmLoadFrameScripts, pmmClearFrameScripts }
= require("devtools/client/performance/test/helpers/profiler-mm-utils");
const MARKER_NAME = "TimeStamp";
add_task(async function() {
await addTab(MAIN_DOMAIN + "doc_perf.html");
const target = await addTabTarget(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
const client = new DebuggerClient(DebuggerServer.connectPipe());
const form = await connectDebuggerClient(client);
const front = PerformanceFront(client, form);
const front = target.getFront("performance");
await front.connect();
const rec = await front.startRecording({ withMarkers: true });
@ -41,6 +37,6 @@ add_task(async function() {
pmmClearFrameScripts();
await client.close();
await target.destroy();
gBrowser.removeCurrentTab();
});

View File

@ -7,15 +7,9 @@
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
add_task(async function() {
await addTab(MAIN_DOMAIN + "doc_allocations.html");
initDebuggerServer();
const client = new DebuggerClient(DebuggerServer.connectPipe());
const form = await connectDebuggerClient(client);
const front = PerformanceFront(client, form);
const target = await addTabTarget(MAIN_DOMAIN + "doc_allocations.html");
const front = target.getFront("performance");
await front.connect();
const rec = await front.startRecording(
@ -36,6 +30,6 @@ add_task(async function() {
ok(sizes.every(n => n > 0 && typeof n === "number"), "all sizes are positive numbers");
await front.destroy();
await client.close();
await target.destroy();
gBrowser.removeCurrentTab();
});

View File

@ -9,16 +9,12 @@
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
const { pmmIsProfilerActive, pmmLoadFrameScripts } = require("devtools/client/performance/test/helpers/profiler-mm-utils");
add_task(async function() {
await addTab(MAIN_DOMAIN + "doc_perf.html");
const target = await addTabTarget(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
const client = new DebuggerClient(DebuggerServer.connectPipe());
const form = await connectDebuggerClient(client);
const front = PerformanceFront(client, form);
const front = target.getFront("performance");
await front.connect();
pmmLoadFrameScripts(gBrowser);
@ -37,7 +33,7 @@ add_task(async function() {
"The built-in profiler module should still be active (2).");
await front.destroy();
await client.close();
await target.destroy();
ok(!(await pmmIsProfilerActive()),
"The built-in profiler module should no longer be active.");

View File

@ -8,25 +8,19 @@
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
const { pmmIsProfilerActive, pmmLoadFrameScripts } = require("devtools/client/performance/test/helpers/profiler-mm-utils");
add_task(async function() {
await addTab(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
const client = new DebuggerClient(DebuggerServer.connectPipe());
const form = await connectDebuggerClient(client);
const firstFront = PerformanceFront(client, form);
const target1 = await addTabTarget(MAIN_DOMAIN + "doc_perf.html");
const firstFront = target1.getFront("performance");
await firstFront.connect();
pmmLoadFrameScripts(gBrowser);
await firstFront.startRecording();
await addTab(MAIN_DOMAIN + "doc_perf.html");
const client2 = new DebuggerClient(DebuggerServer.connectPipe());
const form2 = await connectDebuggerClient(client2);
const secondFront = PerformanceFront(client2, form2);
const target2 = await addTabTarget(MAIN_DOMAIN + "doc_perf.html");
const secondFront = target2.getFront("performance");
await secondFront.connect();
pmmLoadFrameScripts(gBrowser);
@ -34,12 +28,12 @@ add_task(async function() {
// Manually teardown the tabs so we can check profiler status
await secondFront.destroy();
await client2.close();
await target2.destroy();
ok((await pmmIsProfilerActive()),
"The built-in profiler module should still be active.");
await firstFront.destroy();
await client.close();
await target1.destroy();
ok(!(await pmmIsProfilerActive()),
"The built-in profiler module should no longer be active.");

View File

@ -10,7 +10,6 @@
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
const { pmmIsProfilerActive, pmmStartProfiler, pmmLoadFrameScripts, pmmClearFrameScripts } = require("devtools/client/performance/test/helpers/profiler-mm-utils");
add_task(async function() {
@ -24,28 +23,23 @@ add_task(async function() {
ok((await pmmIsProfilerActive()),
"The built-in profiler module should still be active.");
await addTab(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
const client = new DebuggerClient(DebuggerServer.connectPipe());
const form = await connectDebuggerClient(client);
const firstFront = PerformanceFront(client, form);
const target1 = await addTabTarget(MAIN_DOMAIN + "doc_perf.html");
const firstFront = target1.getFront("performance");
await firstFront.connect();
await firstFront.startRecording();
await addTab(MAIN_DOMAIN + "doc_perf.html");
const client2 = new DebuggerClient(DebuggerServer.connectPipe());
const form2 = await connectDebuggerClient(client2);
const secondFront = PerformanceFront(client2, form2);
const target2 = await addTabTarget(MAIN_DOMAIN + "doc_perf.html");
const secondFront = target2.getFront("performance");
await secondFront.connect();
await secondFront.destroy();
await client2.close();
await target2.destroy();
ok((await pmmIsProfilerActive()),
"The built-in profiler module should still be active.");
await firstFront.destroy();
await client.close();
await target1.destroy();
ok(!(await pmmIsProfilerActive()),
"The built-in profiler module should have been automatically stopped.");

View File

@ -7,15 +7,10 @@
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
add_task(async function() {
await addTab(MAIN_DOMAIN + "doc_perf.html");
const target = await addTabTarget(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
const client = new DebuggerClient(DebuggerServer.connectPipe());
const form = await connectDebuggerClient(client);
const front = PerformanceFront(client, form);
const front = target.getFront("performance");
await front.connect();
let lastMemoryDelta = 0;
@ -46,7 +41,7 @@ add_task(async function() {
is(counters.ticks.length, 3, "three ticks events fired.");
await front.destroy();
await client.close();
await target.destroy();
gBrowser.removeCurrentTab();
function handler(name, data) {

View File

@ -8,15 +8,9 @@
"use strict";
const { PerformanceFront } = require("devtools/shared/fronts/performance");
add_task(async function() {
await addTab(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
const client = new DebuggerClient(DebuggerServer.connectPipe());
const form = await connectDebuggerClient(client);
const front = PerformanceFront(client, form);
const target = await addTabTarget(MAIN_DOMAIN + "doc_perf.html");
const front = target.getFront("performance");
await front.connect();
const rec = await front.startRecording(
@ -71,7 +65,7 @@ add_task(async function() {
checkSystemInfo(importedModel, "Client");
await front.destroy();
await client.close();
await target.destroy();
gBrowser.removeCurrentTab();
});

View File

@ -10,15 +10,10 @@
var BUFFER_SIZE = 20000;
var config = { bufferSize: BUFFER_SIZE };
const { PerformanceFront } = require("devtools/shared/fronts/performance");
add_task(async function() {
await addTab(MAIN_DOMAIN + "doc_perf.html");
const target = await addTabTarget(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
const client = new DebuggerClient(DebuggerServer.connectPipe());
const form = await connectDebuggerClient(client);
const front = PerformanceFront(client, form);
const front = target.getFront("performance");
await front.connect();
await front.setProfilerStatusInterval(10);
@ -54,6 +49,6 @@ add_task(async function() {
"buffer usage should be null when no longer recording.");
await front.destroy();
await client.close();
await target.destroy();
gBrowser.removeCurrentTab();
});

View File

@ -11,16 +11,11 @@
// time in ms
const WAIT_TIME = 1000;
const { PerformanceFront } = require("devtools/shared/fronts/performance");
add_task(async function() {
await SpecialPowers.pushPrefEnv({"set": [["privacy.reduceTimerPrecision", false]]});
await addTab(MAIN_DOMAIN + "doc_perf.html");
const target = await addTabTarget(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
const client = new DebuggerClient(DebuggerServer.connectPipe());
const form = await connectDebuggerClient(client);
const front = PerformanceFront(client, form);
const front = target.getFront("performance");
await front.connect();
// Perform the first recording...
@ -65,6 +60,6 @@ add_task(async function() {
"even though the total number of frames did not overflow.");
await front.destroy();
await client.close();
await target.destroy();
gBrowser.removeCurrentTab();
});

View File

@ -12,15 +12,10 @@
// Time in ms
const WAIT_TIME = 1000;
const { PerformanceFront } = require("devtools/shared/fronts/performance");
add_task(async function() {
await addTab(MAIN_DOMAIN + "doc_perf.html");
const target = await addTabTarget(MAIN_DOMAIN + "doc_perf.html");
initDebuggerServer();
const client = new DebuggerClient(DebuggerServer.connectPipe());
const form = await connectDebuggerClient(client);
const front = PerformanceFront(client, form);
const front = target.getFront("performance");
await front.connect();
const rec = await front.startRecording();
@ -48,7 +43,7 @@ add_task(async function() {
"At least some samples have been iterated over, checking for root nodes.");
await front.destroy();
await client.close();
await target.getFront("performance");
gBrowser.removeCurrentTab();
});

View File

@ -5,18 +5,17 @@
"use strict";
const {AddonManager} = require("resource://gre/modules/AddonManager.jsm");
const {Devices} = require("resource://devtools/shared/apps/Devices.jsm");
const Services = require("Services");
const EventEmitter = require("devtools/shared/event-emitter");
var ADB_LINK = Services.prefs.getCharPref("devtools.remote.adb.extensionURL");
var ADB_ADDON_ID = Services.prefs.getCharPref("devtools.remote.adb.extensionID");
const ADB_LINK = Services.prefs.getCharPref("devtools.remote.adb.extensionURL");
const ADB_ADDON_ID = Services.prefs.getCharPref("devtools.remote.adb.extensionID");
// Extension ID for adb helper extension that might be installed on Firefox 63 or older.
const OLD_ADB_ADDON_ID = "adbhelper@mozilla.org";
var platform = Services.appShell.hiddenDOMWindow.navigator.platform;
var OS = "";
const platform = Services.appShell.hiddenDOMWindow.navigator.platform;
let OS = "";
if (platform.includes("Win")) {
OS = "win32";
} else if (platform.includes("Mac")) {
@ -29,33 +28,11 @@ if (platform.includes("Win")) {
}
}
var addonsListener = {};
addonsListener.onEnabled =
addonsListener.onDisabled =
addonsListener.onInstalled =
addonsListener.onUninstalled = (updatedAddon) => {
const addons = GetAvailableAddons();
addons.adb.updateInstallStatus();
};
AddonManager.addAddonListener(addonsListener);
var AvailableAddons = null;
var GetAvailableAddons = exports.GetAvailableAddons = function() {
if (!AvailableAddons) {
AvailableAddons = {
adb: new ADBAddon()
};
}
return AvailableAddons;
};
exports.ForgetAddonsList = function() {
AvailableAddons = null;
};
function ADBAddon() {
EventEmitter.decorate(this);
this._status = "unknown";
// This addon uses the string "linux" for "linux32"
const fixedOS = OS == "linux32" ? "linux" : OS;
this.xpiLink = ADB_LINK.replace(/#OS#/g, fixedOS);
@ -64,17 +41,23 @@ function ADBAddon() {
this.uninstallOldExtension();
this.updateInstallStatus();
const addonsListener = {};
addonsListener.onEnabled =
addonsListener.onDisabled =
addonsListener.onInstalled =
addonsListener.onUninstalled = () => this.updateInstallStatus();
AddonManager.addAddonListener(addonsListener);
}
ADBAddon.prototype = {
_status: "unknown",
set status(value) {
Devices.adbExtensionInstalled = (value == "installed");
if (this._status != value) {
this._status = value;
this.emit("update");
}
},
get status() {
return this._status;
},
@ -88,7 +71,14 @@ ADBAddon.prototype = {
}
},
install: async function() {
/**
* Install and enable the adb extension. Returns a promise that resolves when ADB is
* enabled.
*
* @param {String} source
* String passed to the AddonManager for telemetry.
*/
install: async function(source) {
const addon = await AddonManager.getAddonByID(ADB_ADDON_ID);
if (addon && !addon.userDisabled) {
this.status = "installed";
@ -98,8 +88,12 @@ ADBAddon.prototype = {
if (addon && addon.userDisabled) {
await addon.enable();
} else {
const install = await AddonManager.getInstallForURL(this.xpiLink, "application/x-xpinstall", null,
null, null, null, null, {source: "webide"});
const install = await AddonManager.getInstallForURL(
this.xpiLink,
"application/x-xpinstall",
null, null, null, null, null,
{ source }
);
install.addListener(this);
install.install();
}
@ -155,3 +149,5 @@ ADBAddon.prototype = {
this.installFailureHandler(install, "Install failed");
},
};
exports.adbAddon = new ADBAddon();

View File

@ -3,6 +3,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'adb-addon.js',
'adb-binary.js',
'adb-client.js',
'adb-device.js',

View File

@ -6,12 +6,13 @@
const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
const EventEmitter = require("devtools/shared/event-emitter");
const { adbAddon } = require("devtools/shared/adb/adb-addon");
/* exported EXPORTED_SYMBOLS */
const EXPORTED_SYMBOLS = ["Devices"];
var addonInstalled = false;
var addonInstalled = adbAddon.status === "installed";
const Devices = {
_devices: {},
@ -45,8 +46,13 @@ const Devices = {
getByName: function(name) {
return this._devices[name];
}
},
updateAdbAddonStatus: function() {
this.adbExtensionInstalled = adbAddon.status === "installed";
},
};
Object.defineProperty(this, "Devices", {
value: Devices,
enumerable: true,
@ -54,3 +60,5 @@ Object.defineProperty(this, "Devices", {
});
EventEmitter.decorate(Devices);
adbAddon.on("update", () => Devices.updateAdbAddonStatus());

View File

@ -78,6 +78,29 @@ const emulationSpec = generateActorSpec({
}
},
setMetaViewportOverride: {
request: {
flag: Arg(0, "number")
},
response: {
valueChanged: RetVal("boolean")
}
},
getMetaViewportOverride: {
request: {},
response: {
flag: RetVal("number")
}
},
clearMetaViewportOverride: {
request: {},
response: {
valueChanged: RetVal("boolean")
}
},
setUserAgentOverride: {
request: {
flag: Arg(0, "string")

View File

@ -339,6 +339,7 @@ nsDocShell::nsDocShell()
, mDisplayMode(nsIDocShell::DISPLAY_MODE_BROWSER)
, mJSRunToCompletionDepth(0)
, mTouchEventsOverride(nsIDocShell::TOUCHEVENTS_OVERRIDE_NONE)
, mMetaViewportOverride(nsIDocShell::META_VIEWPORT_OVERRIDE_NONE)
, mFullscreenAllowed(CHECK_ATTRIBUTES)
, mCreatingDocument(false)
#ifdef DEBUG
@ -2648,6 +2649,36 @@ nsDocShell::SetTouchEventsOverride(uint32_t aTouchEventsOverride)
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetMetaViewportOverride(uint32_t* aMetaViewportOverride)
{
NS_ENSURE_ARG_POINTER(aMetaViewportOverride);
*aMetaViewportOverride = mMetaViewportOverride;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::SetMetaViewportOverride(uint32_t aMetaViewportOverride)
{
if (!(aMetaViewportOverride == nsIDocShell::META_VIEWPORT_OVERRIDE_NONE ||
aMetaViewportOverride == nsIDocShell::META_VIEWPORT_OVERRIDE_ENABLED ||
aMetaViewportOverride == nsIDocShell::META_VIEWPORT_OVERRIDE_DISABLED)) {
return NS_ERROR_INVALID_ARG;
}
mMetaViewportOverride = aMetaViewportOverride;
// Inform our presShell that it needs to re-check its need for a viewport
// override.
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
if (presShell) {
presShell->UpdateViewportOverridden(true);
}
return NS_OK;
}
/* virtual */ int32_t
nsDocShell::ItemType()
{
@ -2927,6 +2958,9 @@ nsDocShell::SetDocLoaderParent(nsDocLoader* aParent)
if (NS_SUCCEEDED(parentAsDocShell->GetTouchEventsOverride(&touchEventsOverride))) {
SetTouchEventsOverride(touchEventsOverride);
}
// We don't need to inherit metaViewportOverride, because the viewport
// is only relevant for the outermost nsDocShell, not for any iframes
// like this that might be embedded within it.
}
nsCOMPtr<nsILoadContext> parentAsLoadContext(do_QueryInterface(parent));

View File

@ -1079,6 +1079,10 @@ private: // data members
// as constants in the nsIDocShell.idl file.
uint32_t mTouchEventsOverride;
// Whether or not handling of the <meta name="viewport"> tag is overridden.
// Possible values are defined as constants in nsIDocShell.idl.
uint32_t mMetaViewportOverride;
// mFullscreenAllowed stores how we determine whether fullscreen is allowed
// when GetFullscreenAllowed() is called. Fullscreen is allowed in a
// docshell when all containing iframes have the allowfullscreen

View File

@ -1153,6 +1153,28 @@ interface nsIDocShell : nsIDocShellTreeItem
*/
const unsigned long TOUCHEVENTS_OVERRIDE_NONE = 2;
/**
* Override platform/pref default behaviour and force-disable support for
* <meta name="viewport">.
*/
const unsigned long META_VIEWPORT_OVERRIDE_DISABLED = 0;
/**
* Override platform/pref default behaviour and force-enable support for
* <meta name="viewport">.
*/
const unsigned long META_VIEWPORT_OVERRIDE_ENABLED = 1;
/**
* Don't override the platform/pref default behaviour for support for
* <meta name="viewport">.
*/
const unsigned long META_VIEWPORT_OVERRIDE_NONE = 2;
/**
* This allows chrome to override the default choice of whether the
* <meta name="viewport"> tag is respected in a specific docshell.
* Possible values are listed above.
*/
attribute unsigned long metaViewportOverride;
/**
* This value is `true` if its corresponding unit of related browsing contexts
* (TabGroup) contains only 1 toplevel window, and that window is the outer

View File

@ -7251,7 +7251,7 @@ nsIDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
/*allowZoom*/ true);
}
if (!gfxPrefs::MetaViewportEnabled()) {
if (!nsLayoutUtils::ShouldHandleMetaViewport(this)) {
return nsViewportInfo(aDisplaySize,
defaultScale,
/*allowZoom*/ false);

View File

@ -1,3 +1,3 @@
[test_loader_global_sharing.py]
skip-if = !manage_instance || appname == 'fennec'
skip-if = !manage_instance || appname == 'fennec' || (os == "win" && !(debug || asan)) # Bug 1495667

View File

@ -56,13 +56,14 @@ public:
* updated, and the visual viewport size needs to be updated. */
void ResolutionUpdated();
private:
~MobileViewportManager();
/* Called to compute the initial viewport on page load or before-first-paint,
* whichever happens first. */
* whichever happens first. Also called directly if we are created after the
* presShell is initialized. */
void SetInitialViewport();
private:
~MobileViewportManager();
/* Main helper method to update the CSS viewport and any other properties that
* need updating. */
void RefreshViewportSize(bool aForceAdjustResolution);

View File

@ -1045,9 +1045,9 @@ PresShell::Init(nsIDocument* aDocument,
if (mPresContext->IsRootContentDocument()) {
mZoomConstraintsClient = new ZoomConstraintsClient();
mZoomConstraintsClient->Init(this, mDocument);
if (gfxPrefs::MetaViewportEnabled() || gfxPrefs::APZAllowZooming()) {
mMobileViewportManager = new MobileViewportManager(this, mDocument);
}
// We call this to create mMobileViewportManager, if it is needed.
UpdateViewportOverridden(false);
}
}
@ -10505,6 +10505,49 @@ PresShell::SetIsActive(bool aIsActive)
return rv;
}
void
PresShell::UpdateViewportOverridden(bool aAfterInitialization)
{
// Determine if we require a MobileViewportManager.
bool needMVM = nsLayoutUtils::ShouldHandleMetaViewport(mDocument) ||
gfxPrefs::APZAllowZooming();
if (needMVM == !!mMobileViewportManager) {
// Either we've need one and we've already got it, or we don't need one
// and don't have it. Either way, we're done.
return;
}
if (needMVM) {
if (mPresContext->IsRootContentDocument()) {
mMobileViewportManager = new MobileViewportManager(this, mDocument);
if (aAfterInitialization) {
// Setting the initial viewport will trigger a reflow.
mMobileViewportManager->SetInitialViewport();
}
}
return;
}
MOZ_ASSERT(mMobileViewportManager, "Shouldn't reach this without a "
"MobileViewportManager.");
mMobileViewportManager->Destroy();
mMobileViewportManager = nullptr;
if (aAfterInitialization) {
// Force a reflow to our correct size by going back to the docShell
// and asking it to reassert its size. This is necessary because
// everything underneath the docShell, like the ViewManager, has been
// altered by the MobileViewportManager in an irreversible way.
nsDocShell* docShell =
static_cast<nsDocShell*>(GetPresContext()->GetDocShell());
int32_t width, height;
docShell->GetSize(&width, &height);
docShell->SetSize(width, height, false);
}
}
/*
* Determines the current image locking state. Called when one of the
* dependent factors changes.

View File

@ -345,6 +345,8 @@ public:
return (mMobileViewportManager != nullptr);
}
void UpdateViewportOverridden(bool aAfterInitialization) override;
bool IsLayoutFlushObserver() override
{
return GetPresContext()->RefreshDriver()->

View File

@ -366,10 +366,16 @@ public:
ResizeReflowOptions::eBSizeExact) = 0;
/**
* Returns true if ResizeReflowOverride has been called.
* Returns true if the platform/pref or docshell require a meta viewport.
*/
virtual bool GetIsViewportOverridden() = 0;
/**
* Note that the assumptions that determine the need for a meta viewport
* may have changed.
*/
virtual void UpdateViewportOverridden(bool aAfterInitialization) = 0;
/**
* Return true if the presshell expects layout flush.
*/

View File

@ -10219,6 +10219,28 @@ nsLayoutUtils::ParseFontLanguageOverride(const nsAString& aLangTag)
return result;
}
/* static */ bool
nsLayoutUtils::ShouldHandleMetaViewport(nsIDocument* aDocument)
{
uint32_t metaViewportOverride = nsIDocShell::META_VIEWPORT_OVERRIDE_NONE;
if (aDocument) {
if (nsIDocShell* docShell = aDocument->GetDocShell()) {
docShell->GetMetaViewportOverride(&metaViewportOverride);
}
}
switch (metaViewportOverride) {
case nsIDocShell::META_VIEWPORT_OVERRIDE_ENABLED:
return true;
case nsIDocShell::META_VIEWPORT_OVERRIDE_DISABLED:
return false;
default:
MOZ_ASSERT(metaViewportOverride == nsIDocShell::META_VIEWPORT_OVERRIDE_NONE);
// The META_VIEWPORT_OVERRIDE_NONE case means that there is no override
// and we rely solely on the gfxPrefs.
return gfxPrefs::MetaViewportEnabled();
}
}
/* static */ ComputedStyle*
nsLayoutUtils::StyleForScrollbar(nsIFrame* aScrollbarPart)
{

View File

@ -3066,6 +3066,12 @@ public:
static uint32_t ParseFontLanguageOverride(const nsAString& aLangTag);
/**
* Returns true if there are any preferences or overrides that indicate a
* need to create a MobileViewportManager.
*/
static bool ShouldHandleMetaViewport(nsIDocument* aDocument);
/**
* Resolve a CSS <length-percentage> value to a definite size.
*/

View File

@ -3379,10 +3379,8 @@ Http2Session::WriteSegmentsAgain(nsAHttpSegmentWriter *writer,
Http2Stream *pushSink = streamToCleanup->GetConsumerStream();
if (pushSink) {
bool enqueueSink = true;
for (auto iter = mPushesReadyForRead.begin();
iter != mPushesReadyForRead.end();
++iter) {
if (*iter == pushSink) {
for (auto s : mPushesReadyForRead) {
if (s == pushSink) {
enqueueSink = false;
break;
}

View File

@ -769,6 +769,7 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
{ "fi.google.com", true, false, false, -1, &kPinset_google_root_pems },
{ "fi.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
{ "firebaseio.com", true, false, false, -1, &kPinset_google_root_pems },
{ "firefox.com", true, true, true, 15, &kPinset_mozilla_services },
{ "fj.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
{ "fr.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
{ "g.co", true, false, false, -1, &kPinset_google_root_pems },
@ -1166,8 +1167,8 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
{ "zh.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
};
// Pinning Preload List Length = 487;
// Pinning Preload List Length = 488;
static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1546862504246000);
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1547121793919000);

File diff suppressed because it is too large Load Diff

View File

@ -136,11 +136,7 @@ pref("security.cert_pinning.max_max_age_seconds", 5184000);
// 1: Symantec roots distrusted for certificates issued after cutoff
// 2: Symantec roots distrusted regardless of date
// See https://wiki.mozilla.org/CA/Upcoming_Distrust_Actions for more details.
#ifdef NIGHTLY_BUILD
pref("security.pki.distrust_ca_policy", 2);
#else
pref("security.pki.distrust_ca_policy", 1);
#endif
// Issuer we use to detect MitM proxies. Set to the issuer of the cert of the
// Firefox update service. The string format is whatever NSS uses to print a DN.

View File

@ -159,7 +159,8 @@ win64-rust-1.29:
using: toolchain-script
script: repack_rust.py
arguments: [
'--channel', '1.29.0',
# Rustc 1.30 beta for rust-lang/rust#52847
'--channel', 'beta-2018-09-28',
'--host', 'x86_64-pc-windows-msvc',
'--target', 'x86_64-pc-windows-msvc',
'--target', 'i686-pc-windows-msvc',

View File

@ -23,6 +23,9 @@ __all__ = ['ProcessHandlerMixin', 'ProcessHandler', 'LogOutput',
# Set the MOZPROCESS_DEBUG environment variable to 1 to see some debugging output
MOZPROCESS_DEBUG = os.getenv("MOZPROCESS_DEBUG")
INTERVAL_PROCESS_ALIVE_CHECK = 0.02
# We dont use mozinfo because it is expensive to import, see bug 933558.
isWin = os.name == "nt"
isPosix = os.name == "posix" # includes MacOS X
@ -189,7 +192,7 @@ class ProcessHandlerMixin(object):
if self.poll() is not None:
# process terminated nicely
break
time.sleep(0.02)
time.sleep(INTERVAL_PROCESS_ALIVE_CHECK)
else:
# process did not terminate - send SIGKILL to force
send_sig(signal.SIGKILL)
@ -202,14 +205,27 @@ class ProcessHandlerMixin(object):
return self.returncode
def poll(self):
""" Popen.poll
Check if child process has terminated. Set and return returncode attribute.
"""
# If we have a handle, the process is alive
if isWin and getattr(self, '_handle', None):
return None
"""Check if child process has terminated, and set returncode attribute.
return subprocess.Popen.poll(self)
This method overrides the Popen.poll implementation for our custom
process handling for Windows.
"""
if isWin:
# If we have a handle, check that the process is still alive.
if self._handle:
returncode = winprocess.GetExitCodeProcess(self._handle)
# If the process doesn't exist anymore run cleanup steps
if returncode != winprocess.STILL_ACTIVE:
self.returncode = returncode
self._cleanup()
else:
self.returncode = None
else:
self.returncode = subprocess.Popen.poll(self)
return self.returncode
def wait(self):
""" Popen.wait
@ -789,9 +805,9 @@ falling back to not using job objects for managing child processes""", file=sys.
:param sig: Signal used to kill the process, defaults to SIGKILL
(has no effect on Windows)
"""
if not hasattr(self, 'proc'):
raise RuntimeError("Calling kill() on a non started process is not"
" allowed.")
if not hasattr(self, "proc"):
raise RuntimeError("Process hasn't been started yet")
self.proc.kill(sig=sig)
# When we kill the the managed process we also have to wait for the
@ -808,16 +824,16 @@ falling back to not using job objects for managing child processes""", file=sys.
- '0' if the process ended without failures
"""
if not hasattr(self, "proc"):
raise RuntimeError("Process hasn't been started yet")
# Ensure that we first check for the reader status. Otherwise
# we might mark the process as finished while output is still getting
# processed.
if not hasattr(self, 'proc'):
raise RuntimeError("Calling poll() on a non started process is not"
" allowed.")
elif self.reader.is_alive():
return None
elif hasattr(self.proc, "returncode"):
return self.proc.returncode
elif hasattr(self, "returncode"):
return self.returncode
else:
return self.proc.poll()
@ -857,12 +873,12 @@ falling back to not using job objects for managing child processes""", file=sys.
- '0' if the process ended without failures
"""
# Thread.join() blocks the main thread until the reader thread is finished
# wake up once a second in case a keyboard interrupt is sent
if self.reader.thread and self.reader.thread is not threading.current_thread():
# Thread.join() blocks the main thread until the reader thread is finished
# wake up once a second in case a keyboard interrupt is sent
count = 0
while self.reader.is_alive():
self.reader.thread.join(timeout=1)
self.reader.join(timeout=1)
count += 1
if timeout is not None and count > timeout:
return None
@ -872,6 +888,9 @@ falling back to not using job objects for managing child processes""", file=sys.
@property
def pid(self):
if not hasattr(self, "proc"):
raise RuntimeError("Process hasn't been started yet")
return self.proc.pid
@staticmethod
@ -924,8 +943,8 @@ falling back to not using job objects for managing child processes""", file=sys.
new_pid is the new process id of the child process.
"""
if not self.proc:
return
if not hasattr(self, "proc"):
raise RuntimeError("Process hasn't been started yet")
if isPosix:
new_pgid = self._getpgid(new_pid)
@ -1014,7 +1033,7 @@ class ProcessReader(object):
or (stderr_reader and stderr_reader.is_alive()):
has_line = True
try:
line, callback = queue.get(True, 0.02)
line, callback = queue.get(True, INTERVAL_PROCESS_ALIVE_CHECK)
except Empty:
has_line = False
now = time.time()
@ -1048,6 +1067,11 @@ class ProcessReader(object):
return self.thread.is_alive()
return False
def join(self, timeout=None):
if self.thread:
self.thread.join(timeout=timeout)
# default output handlers
# these should be callables that take the output line

View File

@ -1,8 +1,11 @@
[DEFAULT]
subsuite = mozbase, os == "linux"
skip-if = python == 3
[test_detached.py]
skip-if = os == "win" # Bug 1493796
[test_kill.py]
[test_misc.py]
[test_pid.py]
[test_poll.py]
[test_wait.py]
[test_output.py]

View File

@ -0,0 +1,67 @@
#!/usr/bin/env python
from __future__ import absolute_import
import os
import mozunit
from mozprocess import processhandler
import proctest
here = os.path.dirname(os.path.abspath(__file__))
class ProcTestDetached(proctest.ProcTest):
"""Class to test for detached processes."""
def test_check_for_detached_before_run(self):
"""Process is not started yet when checked for detached."""
p = processhandler.ProcessHandler([self.python, self.proclaunch,
"process_normal_finish.ini"],
cwd=here)
with self.assertRaises(RuntimeError):
p.check_for_detached(1234)
def test_check_for_detached_while_running_with_current_pid(self):
"""Process is started, and check for detached with original pid."""
p = processhandler.ProcessHandler([self.python, self.proclaunch,
"process_normal_finish.ini"],
cwd=here)
p.run()
orig_pid = p.pid
p.check_for_detached(p.pid)
self.assertEqual(p.pid, orig_pid)
self.assertIsNone(p.proc.detached_pid)
self.determine_status(p, True)
p.kill()
def test_check_for_detached_after_fork(self):
"""Process is started, and check for detached with new pid."""
pass
def test_check_for_detached_after_kill(self):
"""Process is killed before checking for detached pid."""
p = processhandler.ProcessHandler([self.python, self.proclaunch,
"process_normal_finish.ini"],
cwd=here)
p.run()
p.kill()
orig_pid = p.pid
p.check_for_detached(p.pid)
self.assertEqual(p.pid, orig_pid)
self.assertIsNone(p.proc.detached_pid)
self.determine_status(p)
if __name__ == '__main__':
mozunit.main()

View File

@ -34,7 +34,8 @@ class ProcTestOutput(proctest.ProcTest):
"""
Process is started, outputs data with no newline
"""
p = processhandler.ProcessHandler([self.python, "scripts", "procnonewline.py"],
p = processhandler.ProcessHandler([self.python,
os.path.join("scripts", "procnonewline.py")],
cwd=here)
p.run()

View File

@ -0,0 +1,51 @@
#!/usr/bin/env python
from __future__ import absolute_import
import os
import mozunit
from mozprocess import processhandler
import proctest
here = os.path.dirname(os.path.abspath(__file__))
class ProcTestPid(proctest.ProcTest):
"""Class to test process pid."""
def test_pid_before_run(self):
"""Process is not started, and pid is checked."""
p = processhandler.ProcessHandler([self.python])
with self.assertRaises(RuntimeError):
p.pid
def test_pid_while_running(self):
"""Process is started, and pid is checked."""
p = processhandler.ProcessHandler([self.python, self.proclaunch,
"process_normal_finish.ini"],
cwd=here)
p.run()
self.assertIsNotNone(p.pid)
self.determine_status(p, True)
p.kill()
def test_pid_after_kill(self):
"""Process is killed, and pid is checked."""
p = processhandler.ProcessHandler([self.python, self.proclaunch,
"process_normal_finish.ini"],
cwd=here)
p.run()
p.kill()
self.assertIsNotNone(p.pid)
self.determine_status(p)
if __name__ == '__main__':
mozunit.main()

View File

@ -4,6 +4,7 @@ from __future__ import absolute_import
import os
import signal
import time
import mozinfo
import mozunit
@ -108,8 +109,15 @@ class ProcTestPoll(proctest.ProcTest):
"process_normal_finish.ini"],
cwd=here)
p.run()
os.kill(p.pid, signal.SIGTERM)
returncode = p.wait()
# Allow the output reader thread to finish processing remaining data
for i in xrange(0, 100):
time.sleep(processhandler.INTERVAL_PROCESS_ALIVE_CHECK)
returncode = p.poll()
if returncode is not None:
break
# We killed the process, so the returncode should be non-zero
if mozinfo.isWin:
@ -119,7 +127,7 @@ class ProcTestPoll(proctest.ProcTest):
self.assertEqual(returncode, -signal.SIGTERM,
'%s expected, got "%s"' % (-signal.SIGTERM, returncode))
self.assertEqual(returncode, p.poll())
self.assertEqual(returncode, p.wait())
self.determine_status(p)

View File

@ -3,13 +3,15 @@
from __future__ import absolute_import
import os
import proctest
import mozinfo
import signal
import mozinfo
import mozunit
from mozprocess import processhandler
import proctest
here = os.path.dirname(os.path.abspath(__file__))
@ -101,6 +103,27 @@ class ProcTestWait(proctest.ProcTest):
self.assertEqual(returncode1, returncode2,
'Expected both returncodes of wait() to be equal')
def test_wait_after_external_kill(self):
"""Process is killed externally, and poll() is called."""
p = processhandler.ProcessHandler([self.python, self.proclaunch,
"process_normal_finish.ini"],
cwd=here)
p.run()
os.kill(p.pid, signal.SIGTERM)
returncode = p.wait()
# We killed the process, so the returncode should be non-zero
if mozinfo.isWin:
self.assertEqual(returncode, signal.SIGTERM,
'Positive returncode expected, got "%s"' % returncode)
else:
self.assertEqual(returncode, -signal.SIGTERM,
'%s expected, got "%s"' % (-signal.SIGTERM, returncode))
self.assertEqual(returncode, p.poll())
self.determine_status(p)
if __name__ == '__main__':
mozunit.main()

View File

@ -242,8 +242,9 @@ class UpdateVerifyConfigCreator(BaseScript):
for release_name, release_info in \
reversed(sorted(releases.items(),
key=lambda x: MozillaVersion(x[1]['version']))):
product = release_info['product']
version = release_info['version']
# we need to use releases_name instead of release_info since esr
# string is included in the name. later we rely on this.
product, version = release_name.split('-', 1)
category = release_info['category']
tag = "{}_{}_RELEASE".format(product.upper(), version.replace(".", "_"))
# Product details has a "category" for releases that we can use to

View File

@ -22,9 +22,9 @@
<img src="support/swatch-yellow.png" width="160" height="20" alt="Image download support must be enabled" />
<img src="support/black20x20.png" width="160" height="20" alt="Image download support must be enabled" />
<img src="support/swatch-yellow.png" width="160" height="20" alt="Image download support must be enabled" />
<img src="support/swatch-yellow.png" width="40" height="20" alt="Image download support must be enabled" /><img src="support/swatch-blue.png" width="80" height="20" alt="Image download support must be enabled" /><img src="support/swatch-pink.png" width="40" height="20" alt="Image download support must be enabled" />
<img src="support/swatch-orange.png" width="40" height="20" alt="Image download support must be enabled" /><img src="support/swatch-blue.png" width="40" height="20" alt="Image download support must be enabled" /><img src="support/swatch-pink.png" width="80" height="20" alt="Image download support must be enabled" />
<img src="support/swatch-yellow.png" width="40" height="20" alt="Image download support must be enabled" /><img src="support/swatch-blue.png" width="40" height="20" alt="Image download support must be enabled" /><img src="support/swatch-pink.png" width="40" height="20" alt="Image download support must be enabled" /><img src="support/swatch-yellow.png" width="40" height="20" alt="Image download support must be enabled" />
<img src="support/swatch-blue.png" width="80" height="20" alt="Image download support must be enabled" /><img src="support/swatch-pink.png" width="40" height="20" alt="Image download support must be enabled" /><img src="support/swatch-yellow.png" width="40" height="20" alt="Image download support must be enabled" />
</div>
</body>

View File

@ -50,10 +50,10 @@
color: orange;
/*
In this test, the glyphs "or" are painted into 1st column box.
"Content in the normal flow that extends into column
gaps (e.g., long words or images) is clipped in the
middle of the column gap."
Therefore, the glyphs "ang" are clipped and not painted.
Per spec, content in the normal flow that extends into column
gaps (e.g., long words or images) is not clipped to the column
box. However, the glyphs "ang" are overwritten by <span>s, so
they're not visible.
*/
}

View File

@ -113,6 +113,7 @@ clang_checkers:
- name: readability-container-size-empty
- name: readability-delete-null-pointer
- name: readability-else-after-return
- name: readability-implicit-bool-conversion
- name: readability-inconsistent-declaration-parameter-name
- name: readability-misleading-indentation
- name: readability-non-const-parameter

View File

@ -0,0 +1,51 @@
#define MOZ_IMPLICIT __attribute__((annotate("moz_implicit")))
void takesChar(char);
void takesShort(short);
void takesInt(int);
void takesLong(long);
void takesUChar(unsigned char);
void takesUShort(unsigned short);
void takesUInt(unsigned int);
void takesULong(unsigned long);
struct InitializedWithInt {
MOZ_IMPLICIT InitializedWithInt(int);
};
void f() {
bool b = true;
char s0 = b;
short s1 = b;
int s2 = b;
long s3 = b;
unsigned char u0 = b;
unsigned short u1 = b;
unsigned u2 = b;
unsigned long u3 = b;
takesChar(b);
takesShort(b);
takesInt(b);
takesLong(b);
takesUChar(b);
takesUShort(b);
takesUInt(b);
takesULong(b);
InitializedWithInt i = b;
(InitializedWithInt(b));
bool x = b;
int exp = (int)true;
if (x == b) {}
if (x != b) {}
if (b == exp) {}
if (exp == b) {}
}

View File

@ -0,0 +1 @@
[["warning", "implicit conversion bool -> 'char'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'short'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'int'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'long'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'unsigned char'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'unsigned short'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'unsigned int'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'unsigned long'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'char'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'short'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'int'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'long'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'unsigned char'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'unsigned short'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'unsigned int'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'unsigned long'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'int'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'int'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'int'", "readability-implicit-bool-conversion"], ["warning", "implicit conversion bool -> 'int'", "readability-implicit-bool-conversion"]]

View File

@ -7,7 +7,7 @@
#include "nsCOMPtr.h"
nsresult
nsQueryInterface::operator()(const nsIID& aIID, void** aAnswer) const
nsQueryInterfaceISupports::operator()(const nsIID& aIID, void** aAnswer) const
{
nsresult status;
if (mRawPtr) {
@ -20,7 +20,7 @@ nsQueryInterface::operator()(const nsIID& aIID, void** aAnswer) const
}
nsresult
nsQueryInterfaceWithError::operator()(const nsIID& aIID, void** aAnswer) const
nsQueryInterfaceISupportsWithError::operator()(const nsIID& aIID, void** aAnswer) const
{
nsresult status;
if (mRawPtr) {
@ -45,7 +45,7 @@ nsCOMPtr_base::assign_with_AddRef(nsISupports* aRawPtr)
}
void
nsCOMPtr_base::assign_from_qi(const nsQueryInterface aQI, const nsIID& aIID)
nsCOMPtr_base::assign_from_qi(const nsQueryInterfaceISupports aQI, const nsIID& aIID)
{
void* newRawPtr;
if (NS_FAILED(aQI(aIID, &newRawPtr))) {
@ -55,7 +55,7 @@ nsCOMPtr_base::assign_from_qi(const nsQueryInterface aQI, const nsIID& aIID)
}
void
nsCOMPtr_base::assign_from_qi_with_error(const nsQueryInterfaceWithError& aQI,
nsCOMPtr_base::assign_from_qi_with_error(const nsQueryInterfaceISupportsWithError& aQI,
const nsIID& aIID)
{
void* newRawPtr;

View File

@ -155,11 +155,11 @@ public:
* often enough that the codesize savings are big enough to warrant the
* specialcasing.
*/
class MOZ_STACK_CLASS nsQueryInterface final
class MOZ_STACK_CLASS nsQueryInterfaceISupports
{
public:
explicit
nsQueryInterface(nsISupports* aRawPtr) : mRawPtr(aRawPtr) {}
nsQueryInterfaceISupports(nsISupports* aRawPtr) : mRawPtr(aRawPtr) {}
nsresult NS_FASTCALL operator()(const nsIID& aIID, void**) const;
@ -167,10 +167,24 @@ private:
nsISupports* MOZ_OWNING_REF mRawPtr;
};
class nsQueryInterfaceWithError final
#ifndef NSCAP_FEATURE_USE_BASE
template<typename T>
class MOZ_STACK_CLASS nsQueryInterface final : public nsQueryInterfaceISupports
{
public:
nsQueryInterfaceWithError(nsISupports* aRawPtr, nsresult* aError)
explicit
nsQueryInterface(T* aRawPtr) : nsQueryInterfaceISupports(aRawPtr) {}
nsresult NS_FASTCALL operator()(const nsIID& aIID, void** aAnswer) const {
return nsQueryInterfaceISupports::operator()(aIID, aAnswer);
}
};
#endif // #ifndef NSCAP_FEATURE_USE_BASE
class MOZ_STACK_CLASS nsQueryInterfaceISupportsWithError
{
public:
nsQueryInterfaceISupportsWithError(nsISupports* aRawPtr, nsresult* aError)
: mRawPtr(aRawPtr)
, mErrorPtr(aError)
{
@ -183,18 +197,62 @@ private:
nsresult* mErrorPtr;
};
inline nsQueryInterface
#ifndef NSCAP_FEATURE_USE_BASE
template<typename T>
class MOZ_STACK_CLASS nsQueryInterfaceWithError final : public nsQueryInterfaceISupportsWithError
{
public:
explicit
nsQueryInterfaceWithError(T* aRawPtr, nsresult* aError)
: nsQueryInterfaceISupportsWithError(aRawPtr, aError)
{}
nsresult NS_FASTCALL operator()(const nsIID& aIID, void** aAnswer) const {
return nsQueryInterfaceISupportsWithError::operator()(aIID, aAnswer);
}
};
#endif // #ifndef NSCAP_FEATURE_USE_BASE
#ifdef NSCAP_FEATURE_USE_BASE
inline nsQueryInterfaceISupports
do_QueryInterface(nsISupports* aRawPtr)
{
return nsQueryInterface(aRawPtr);
return nsQueryInterfaceISupports(aRawPtr);
}
inline nsQueryInterfaceWithError
inline nsQueryInterfaceISupportsWithError
do_QueryInterface(nsISupports* aRawPtr, nsresult* aError)
{
return nsQueryInterfaceWithError(aRawPtr, aError);
return nsQueryInterfaceISupportsWithError(aRawPtr, aError);
}
#else
namespace mozilla {
// PointedToType<> is needed so that do_QueryInterface() will work with a
// variety of smart pointer types in addition to raw pointers. These types
// include RefPtr<>, nsCOMPtr<>, and OwningNonNull<>.
template<class T>
using PointedToType = typename mozilla::RemovePointer<decltype(&*mozilla::DeclVal<T>())>::Type;
} // namespace mozilla
template<class T>
inline nsQueryInterface<mozilla::PointedToType<T>>
do_QueryInterface(T aPtr)
{
return nsQueryInterface<mozilla::PointedToType<T>>(aPtr);
}
template<class T>
inline nsQueryInterfaceWithError<mozilla::PointedToType<T>>
do_QueryInterface(T aRawPtr, nsresult* aError)
{
return nsQueryInterfaceWithError<mozilla::PointedToType<T>>(aRawPtr, aError);
}
#endif // ! #ifdef NSCAP_FEATURE_USE_BASE
template<class T>
inline void
do_QueryInterface(already_AddRefed<T>&)
@ -317,9 +375,9 @@ public:
void NS_FASTCALL
assign_with_AddRef(nsISupports*);
void NS_FASTCALL
assign_from_qi(const nsQueryInterface, const nsIID&);
assign_from_qi(const nsQueryInterfaceISupports, const nsIID&);
void NS_FASTCALL
assign_from_qi_with_error(const nsQueryInterfaceWithError&, const nsIID&);
assign_from_qi_with_error(const nsQueryInterfaceISupportsWithError&, const nsIID&);
void NS_FASTCALL
assign_from_gs_cid(const nsGetServiceByCID, const nsIID&);
void NS_FASTCALL
@ -379,8 +437,10 @@ class MOZ_IS_REFPTR nsCOMPtr final
private:
void assign_with_AddRef(nsISupports*);
void assign_from_qi(const nsQueryInterface, const nsIID&);
void assign_from_qi_with_error(const nsQueryInterfaceWithError&, const nsIID&);
template<typename U>
void assign_from_qi(const nsQueryInterface<U>, const nsIID&);
template<typename U>
void assign_from_qi_with_error(const nsQueryInterfaceWithError<U>&, const nsIID&);
void assign_from_gs_cid(const nsGetServiceByCID, const nsIID&);
void assign_from_gs_cid_with_error(const nsGetServiceByCIDWithError&,
const nsIID&);
@ -432,8 +492,13 @@ public:
void Assert_NoQueryNeeded()
{
if (mRawPtr) {
nsCOMPtr<T> query_result(do_QueryInterface(mRawPtr));
NS_ASSERTION(query_result.get() == mRawPtr, "QueryInterface needed");
// This can't be defined in terms of do_QueryInterface because
// that bans casts from a class to itself.
void* out = nullptr;
mRawPtr->QueryInterface(NS_GET_TEMPLATE_IID(T), &out);
T* query_result = static_cast<T*>(out);
MOZ_ASSERT(query_result == mRawPtr, "QueryInterface needed");
NS_RELEASE(query_result);
}
}
@ -559,7 +624,12 @@ public:
}
// Construct from |do_QueryInterface(expr)|.
MOZ_IMPLICIT nsCOMPtr(const nsQueryInterface aQI)
#ifdef NSCAP_FEATURE_USE_BASE
MOZ_IMPLICIT nsCOMPtr(const nsQueryInterfaceISupports aQI)
#else
template<typename U>
MOZ_IMPLICIT nsCOMPtr(const nsQueryInterface<U> aQI)
#endif // ! #ifdef NSCAP_FEATURE_USE_BASE
: NSCAP_CTOR_BASE(nullptr)
{
assert_validity();
@ -568,7 +638,12 @@ public:
}
// Construct from |do_QueryInterface(expr, &rv)|.
MOZ_IMPLICIT nsCOMPtr(const nsQueryInterfaceWithError& aQI)
#ifdef NSCAP_FEATURE_USE_BASE
MOZ_IMPLICIT nsCOMPtr(const nsQueryInterfaceISupportsWithError& aQI)
#else
template<typename U>
MOZ_IMPLICIT nsCOMPtr(const nsQueryInterfaceWithError<U>& aQI)
#endif // ! #ifdef NSCAP_FEATURE_USE_BASE
: NSCAP_CTOR_BASE(nullptr)
{
assert_validity();
@ -711,14 +786,24 @@ public:
}
// Assign from |do_QueryInterface(expr)|.
nsCOMPtr<T>& operator=(const nsQueryInterface aRhs)
#ifdef NSCAP_FEATURE_USE_BASE
nsCOMPtr<T>& operator=(const nsQueryInterfaceISupports aRhs)
#else
template<typename U>
nsCOMPtr<T>& operator=(const nsQueryInterface<U> aRhs)
#endif // ! #ifdef NSCAP_FEATURE_USE_BASE
{
assign_from_qi(aRhs, NS_GET_TEMPLATE_IID(T));
return *this;
}
// Assign from |do_QueryInterface(expr, &rv)|.
nsCOMPtr<T>& operator=(const nsQueryInterfaceWithError& aRhs)
#ifdef NSCAP_FEATURE_USE_BASE
nsCOMPtr<T>& operator=(const nsQueryInterfaceISupportsWithError& aRhs)
#else
template<typename U>
nsCOMPtr<T>& operator=(const nsQueryInterfaceWithError<U>& aRhs)
#endif // ! #ifdef NSCAP_FEATURE_USE_BASE
{
assign_from_qi_with_error(aRhs, NS_GET_TEMPLATE_IID(T));
return *this;
@ -943,7 +1028,7 @@ public:
}
// Construct from |do_QueryInterface(expr)|.
MOZ_IMPLICIT nsCOMPtr(const nsQueryInterface aQI)
MOZ_IMPLICIT nsCOMPtr(const nsQueryInterfaceISupports aQI)
: nsCOMPtr_base(nullptr)
{
NSCAP_LOG_ASSIGNMENT(this, nullptr);
@ -951,7 +1036,7 @@ public:
}
// Construct from |do_QueryInterface(expr, &rv)|.
MOZ_IMPLICIT nsCOMPtr(const nsQueryInterfaceWithError& aQI)
MOZ_IMPLICIT nsCOMPtr(const nsQueryInterfaceISupportsWithError& aQI)
: nsCOMPtr_base(nullptr)
{
NSCAP_LOG_ASSIGNMENT(this, nullptr);
@ -1043,14 +1128,14 @@ public:
}
// Assign from |do_QueryInterface(expr)|.
nsCOMPtr<nsISupports>& operator=(const nsQueryInterface aRhs)
nsCOMPtr<nsISupports>& operator=(const nsQueryInterfaceISupports aRhs)
{
assign_from_qi(aRhs, NS_GET_IID(nsISupports));
return *this;
}
// Assign from |do_QueryInterface(expr, &rv)|.
nsCOMPtr<nsISupports>& operator=(const nsQueryInterfaceWithError& aRhs)
nsCOMPtr<nsISupports>& operator=(const nsQueryInterfaceISupportsWithError& aRhs)
{
assign_from_qi_with_error(aRhs, NS_GET_IID(nsISupports));
return *this;
@ -1215,9 +1300,13 @@ nsCOMPtr<T>::assign_with_AddRef(nsISupports* aRawPtr)
}
template<class T>
template<typename U>
void
nsCOMPtr<T>::assign_from_qi(const nsQueryInterface aQI, const nsIID& aIID)
nsCOMPtr<T>::assign_from_qi(const nsQueryInterface<U> aQI, const nsIID& aIID)
{
static_assert(!(mozilla::IsSame<T, U>::value ||
mozilla::IsBaseOf<T, U>::value),
"don't use do_QueryInterface for compile-time-determinable casts");
void* newRawPtr;
if (NS_FAILED(aQI(aIID, &newRawPtr))) {
newRawPtr = nullptr;
@ -1226,10 +1315,14 @@ nsCOMPtr<T>::assign_from_qi(const nsQueryInterface aQI, const nsIID& aIID)
}
template<class T>
template<typename U>
void
nsCOMPtr<T>::assign_from_qi_with_error(const nsQueryInterfaceWithError& aQI,
nsCOMPtr<T>::assign_from_qi_with_error(const nsQueryInterfaceWithError<U>& aQI,
const nsIID& aIID)
{
static_assert(!(mozilla::IsSame<T, U>::value ||
mozilla::IsBaseOf<T, U>::value),
"don't use do_QueryInterface for compile-time-determinable casts");
void* newRawPtr;
if (NS_FAILED(aQI(aIID, &newRawPtr))) {
newRawPtr = nullptr;