зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland. a=merge on a CLOSED TREE
This commit is contained in:
Коммит
edc60268bf
|
@ -1,5 +1,5 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<blocklist lastupdate="1522103097333" xmlns="http://www.mozilla.org/2006/addons-blocklist">
|
||||
<blocklist lastupdate="1523286321447" xmlns="http://www.mozilla.org/2006/addons-blocklist">
|
||||
<emItems>
|
||||
<emItem blockID="i334" id="{0F827075-B026-42F3-885D-98981EE7B1AE}">
|
||||
<prefs/>
|
||||
|
@ -2235,6 +2235,10 @@
|
|||
<prefs/>
|
||||
<versionRange minVersion="0" maxVersion="*" severity="1"/>
|
||||
</emItem>
|
||||
<emItem blockID="36f97298-8bef-4372-a548-eb829413bee9" id="/(__TEMPLATE__APPLICATION__@ruta-mapa\.com)|(application-3@findizer\.fr)|(application2@allo-pages\.fr)|(application2@bilan-imc\.fr)|(application2@lettres\.net)|(application2@search-maps-finder\.com)|(application-imcpeso@imc-peso\.com)|(application-meuimc@meu-imc\.com)|(application-us2@factorlove)|(application-us@misterdirections)|(application-us@yummmi\.es)|(application@amiouze\.fr)|(application@astrolignes\.com)|(application@blotyn\.com)|(application@bmi-result\.com)|(application@bmi-tw\.com)|(application@calcolo-bmi\.com)|(application@cartes-itineraires\.com)|(application@convertisseur\.pro)|(application@de-findizer\.fr)|(application@de-super-rezepte\.com)|(application@dermabeauty\.fr)|(application@dev\.squel\.v2)|(application@eu-my-drivingdirections\.com)|(application@fr-allo-pages\.fr)|(application@fr-catizz\.com)|(application@fr-mr-traduction\.com)|(application@good-recettes\.com)|(application@horaires\.voyage)|(application@imc-calcular\.com)|(application@imc-peso\.com)|(application@it-mio-percorso\.com)|(application@iti-maps\.fr)|(application@itineraire\.info)|(application@lbc-search\.com)|(application@les-pages\.com)|(application@lovincalculator\.com)|(application@lovintest\.com)|(application@masowe\.com)|(application@matchs\.direct)|(application@mein-bmi\.com)|(application@mes-resultats\.com)|(application@mestaf\.com)|(application@meu-imc\.com)|(application@mon-calcul-imc\.fr)|(application@mon-juste-poids\.com)|(application@mon-trajet\.com)|(application@my-drivingdirections\.com)|(application@people-show\.com)|(application@plans-reduc\.fr)|(application@point-meteo\.fr)|(application@poulixo\.com)|(application@quipage\.fr)|(application@quizdeamor\.com)|(application@quizdoamor\.com)|(application@quotient-retraite\.fr)|(application@recettes\.net)|(application@routenplaner-karten\.com)|(application@ruta-mapa\.com)|(application@satellite\.dev\.squel\.v2)|(application@search-bilan-imc\.fr)|(application@search-maps-finder\.com)|(application@slimness\.fr)|(application@start-bmi\.com)|(application@tests-moi\.com)|(application@tousmesjeux\.fr)|(application@toutlannuaire\.fr)|(application@tuto-diy\.com)|(application@ubersetzung-app\.com)|(application@uk-cookyummy\.com)|(application@uk-howlogin\.me)|(application@uk-myloap\.com)|(application@voyagevoyage\.co)|(application@wikimot\.fr)|(application@www\.plans-reduc\.fr)|(application@yummmi\.es)|(application@yummmies\.be)|(application@yummmies\.ch)|(application@yummmies\.fr)|(application@yummmies\.lu)|(application@zikplay\.fr)|(applicationY@search-maps-finder\.com)|(cmesapps@findizer\.fr)|(findizer-shopping@jetpack)|(\{8aaebb36-1488-4022-b7ec-29b790d12c17\})/">
|
||||
<prefs/>
|
||||
<versionRange minVersion="0" maxVersion="*" severity="3"/>
|
||||
</emItem>
|
||||
</emItems>
|
||||
<pluginItems>
|
||||
<pluginItem blockID="p332">
|
||||
|
|
|
@ -358,7 +358,12 @@ nsBrowserContentHandler.prototype = {
|
|||
if (isLocal(resolvedURI)) {
|
||||
// If the URI is local, we are sure it won't wrongly inherit chrome privs
|
||||
let features = "chrome,dialog=no,all" + this.getFeatures(cmdLine);
|
||||
Services.ww.openWindow(null, resolvedURI.spec, "_blank", features, null);
|
||||
// Provide 1 null argument, as openWindow has a different behavior
|
||||
// when the arg count is 0.
|
||||
let argArray = Cc["@mozilla.org/array;1"]
|
||||
.createInstance(Ci.nsIMutableArray);
|
||||
argArray.appendElement(null);
|
||||
Services.ww.openWindow(null, resolvedURI.spec, "_blank", features, argArray);
|
||||
cmdLine.preventDefault = true;
|
||||
} else {
|
||||
dump("*** Preventing load of web URI as chrome\n");
|
||||
|
|
|
@ -98,7 +98,7 @@ if test "$GNU_CXX"; then
|
|||
dnl x86 with clang is a little peculiar. std::atomic does not require
|
||||
dnl linking with libatomic, but using atomic intrinsics does, so we
|
||||
dnl force the setting on for such systems.
|
||||
if test "$CC_TYPE" = "clang" -a "$CPU_ARCH" = "x86"; then
|
||||
if test "$CC_TYPE" = "clang" -a "$CPU_ARCH" = "x86" -a "$OS_ARCH" = "Linux"; then
|
||||
ac_cv_needs_atomic=yes
|
||||
else
|
||||
AC_TRY_LINK(
|
||||
|
|
|
@ -141,6 +141,10 @@ AccessibilityPanel.prototype = {
|
|||
this.postContentMessage("selectAccessible", this._walker, accessibleFront);
|
||||
},
|
||||
|
||||
selectAccessibleForNode(nodeFront) {
|
||||
this.postContentMessage("selectNodeAccessible", this._walker, nodeFront);
|
||||
},
|
||||
|
||||
highlightAccessible(accessibleFront) {
|
||||
this.postContentMessage("highlightAccessible", this._walker, accessibleFront);
|
||||
},
|
||||
|
|
|
@ -7,6 +7,7 @@ support-files =
|
|||
!/devtools/client/inspector/test/shared-head.js
|
||||
!/devtools/client/shared/test/shared-redux-head.js
|
||||
|
||||
[browser_accessibility_context_menu_inspector.js]
|
||||
[browser_accessibility_mutations.js]
|
||||
[browser_accessibility_reload.js]
|
||||
[browser_accessibility_sidebar.js]
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "<h1 id=\"h1\">header</h1><p id=\"p\">paragraph</p>";
|
||||
|
||||
addA11YPanelTask("Test show accessibility properties context menu.", TEST_URI,
|
||||
async function testShowAccessibilityPropertiesContextMenu({ panel, toolbox }) {
|
||||
let inspector = await toolbox.selectTool("inspector");
|
||||
|
||||
ok(inspector.selection.isBodyNode(), "Default selection is a body node.");
|
||||
let menuUpdated = inspector.once("node-menu-updated");
|
||||
let allMenuItems = openContextMenuAndGetAllItems(inspector);
|
||||
let showA11YPropertiesNode = allMenuItems.find(item =>
|
||||
item.id === "node-menu-showaccessibilityproperties");
|
||||
ok(showA11YPropertiesNode,
|
||||
"the popup menu now has a show accessibility properties item");
|
||||
await menuUpdated;
|
||||
ok(showA11YPropertiesNode.disabled, "Body node does not have accessible");
|
||||
|
||||
await selectNode("#h1", inspector, "test");
|
||||
menuUpdated = inspector.once("node-menu-updated");
|
||||
allMenuItems = openContextMenuAndGetAllItems(inspector);
|
||||
showA11YPropertiesNode = allMenuItems.find(item =>
|
||||
item.id === "node-menu-showaccessibilityproperties");
|
||||
ok(showA11YPropertiesNode,
|
||||
"the popup menu now has a show accessibility properties item");
|
||||
await menuUpdated;
|
||||
ok(!showA11YPropertiesNode.disabled, "Body node has an accessible");
|
||||
|
||||
info("Triggering 'Show Accessibility Properties' and waiting for " +
|
||||
"accessibility panel to open");
|
||||
let panelSelected = toolbox.once("accessibility-selected");
|
||||
let objectSelected = panel.once("new-accessible-front-selected");
|
||||
showA11YPropertiesNode.click();
|
||||
await panelSelected;
|
||||
let selected = await objectSelected;
|
||||
|
||||
let expectedSelected = await panel.walker.getAccessibleFor(
|
||||
inspector.selection.nodeFront);
|
||||
is(selected, expectedSelected, "Accessible front selected correctly");
|
||||
});
|
|
@ -99,6 +99,7 @@ async function addTestTab(url) {
|
|||
browser: tab.linkedBrowser,
|
||||
panel,
|
||||
win,
|
||||
toolbox: panel._toolbox,
|
||||
doc,
|
||||
store
|
||||
};
|
||||
|
@ -108,10 +109,14 @@ async function addTestTab(url) {
|
|||
* Turn off accessibility features from within the panel. We call it before the
|
||||
* cleanup function to make sure that the panel is still present.
|
||||
*/
|
||||
function disableAccessibilityInspector(env) {
|
||||
let { doc, win } = env;
|
||||
async function disableAccessibilityInspector(env) {
|
||||
let { doc, win, panel } = env;
|
||||
// Disable accessibility service through the panel and wait for the shutdown
|
||||
// event.
|
||||
let shutdown = panel._front.once("shutdown");
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
doc.getElementById("accessibility-disable-button"), win);
|
||||
await shutdown;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,7 +247,7 @@ async function runA11yPanelTests(tests, env) {
|
|||
* @return {String} built URL
|
||||
*/
|
||||
function buildURL(uri) {
|
||||
return `data:text/html,${encodeURIComponent(uri)}`;
|
||||
return `data:text/html;charset=UTF-8,${encodeURIComponent(uri)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -260,15 +265,22 @@ function buildURL(uri) {
|
|||
* @param {String} msg a message that is printed for the test
|
||||
*/
|
||||
function addA11yPanelTestsTask(tests, uri, msg) {
|
||||
tests.push({
|
||||
desc: "Disable accessibility inspector.",
|
||||
action: env => disableAccessibilityInspector(env),
|
||||
expected: {}
|
||||
});
|
||||
add_task(async function a11yPanelTests() {
|
||||
addA11YPanelTask(msg, uri, env => runA11yPanelTests(tests, env));
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper function around add_task that sets up the test environment, runs
|
||||
* the test and then disables accessibility tools.
|
||||
* @param {String} msg a message that is printed for the test
|
||||
* @param {String} uri test URL
|
||||
* @param {Function} task task function containing the tests.
|
||||
*/
|
||||
function addA11YPanelTask(msg, uri, task) {
|
||||
add_task(async function a11YPanelTask() {
|
||||
info(msg);
|
||||
let env = await addTestTab(buildURL(uri));
|
||||
await runA11yPanelTests(tests, env);
|
||||
await task(env);
|
||||
await disableAccessibilityInspector(env);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1566,6 +1566,8 @@ Inspector.prototype = {
|
|||
click: () => this.showDOMProperties(),
|
||||
}));
|
||||
|
||||
this.buildA11YMenuItem(menu);
|
||||
|
||||
let nodeLinkMenuItems = this._getNodeLinkMenuItems();
|
||||
if (nodeLinkMenuItems.filter(item => item.visible).length > 0) {
|
||||
menu.append(new MenuItem({
|
||||
|
@ -1582,6 +1584,38 @@ Inspector.prototype = {
|
|||
return menu;
|
||||
},
|
||||
|
||||
buildA11YMenuItem: function(menu) {
|
||||
if (!this.selection.isElementNode() ||
|
||||
!Services.prefs.getBoolPref("devtools.accessibility.enabled")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const showA11YPropsItem = new MenuItem({
|
||||
id: "node-menu-showaccessibilityproperties",
|
||||
label: INSPECTOR_L10N.getStr("inspectorShowAccessibilityProperties.label"),
|
||||
click: () => this.showAccessibilityProperties(),
|
||||
disabled: true
|
||||
});
|
||||
this._updateA11YMenuItem(showA11YPropsItem);
|
||||
menu.append(showA11YPropsItem);
|
||||
},
|
||||
|
||||
_updateA11YMenuItem: async function(menuItem) {
|
||||
const hasMethod = await this.target.actorHasMethod("domwalker",
|
||||
"hasAccessibilityProperties");
|
||||
if (!hasMethod) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hasA11YProps = await this.walker.hasAccessibilityProperties(
|
||||
this.selection.nodeFront);
|
||||
if (hasA11YProps) {
|
||||
this._toolbox.doc.getElementById(menuItem.id).disabled = menuItem.disabled = false;
|
||||
}
|
||||
|
||||
this.emit("node-menu-updated");
|
||||
},
|
||||
|
||||
_getCopySubmenu: function(markupContainer, isSelectionElement) {
|
||||
let copySubmenu = new Menu();
|
||||
copySubmenu.append(new MenuItem({
|
||||
|
@ -1953,6 +1987,18 @@ Inspector.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Show Accessibility properties for currently selected node
|
||||
*/
|
||||
async showAccessibilityProperties() {
|
||||
let a11yPanel = await this._toolbox.selectTool("accessibility");
|
||||
// Select the accessible object in the panel and wait for the event that
|
||||
// tells us it has been done.
|
||||
let onSelected = a11yPanel.once("new-accessible-front-selected");
|
||||
a11yPanel.selectAccessibleForNode(this.selection.nodeFront);
|
||||
await onSelected;
|
||||
},
|
||||
|
||||
/**
|
||||
* Use in Console.
|
||||
*
|
||||
|
|
|
@ -749,26 +749,6 @@ async function assertTooltipHiddenOnMouseOut(tooltip, target) {
|
|||
ok(!tooltip.isVisible(), "The tooltip is hidden on mouseout");
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the inspector menu and return all of it's items in a flat array
|
||||
* @param {InspectorPanel} inspector
|
||||
* @param {Object} options to pass into openMenu
|
||||
* @return An array of MenuItems
|
||||
*/
|
||||
function openContextMenuAndGetAllItems(inspector, options) {
|
||||
let menu = inspector._openMenu(options);
|
||||
|
||||
// Flatten all menu items into a single array to make searching through it easier
|
||||
let allItems = [].concat.apply([], menu.items.map(function addItem(item) {
|
||||
if (item.submenu) {
|
||||
return addItem(item.submenu.items);
|
||||
}
|
||||
return item;
|
||||
}));
|
||||
|
||||
return allItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rule editor from the rule-view given its index
|
||||
*
|
||||
|
|
|
@ -573,16 +573,11 @@ var setSearchFilter = async function(view, searchValue) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Open the style editor context menu and return all of it's items in a flat array
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @return An array of MenuItems
|
||||
* Flatten all context menu items into a single array to make searching through
|
||||
* it easier.
|
||||
*/
|
||||
function openStyleContextMenuAndGetAllItems(view, target) {
|
||||
let menu = view._contextmenu._openMenu({target: target});
|
||||
|
||||
// Flatten all menu items into a single array to make searching through it easier
|
||||
let allItems = [].concat.apply([], menu.items.map(function addItem(item) {
|
||||
function buildContextMenuItems(menu) {
|
||||
const allItems = [].concat.apply([], menu.items.map(function addItem(item) {
|
||||
if (item.submenu) {
|
||||
return addItem(item.submenu.items);
|
||||
}
|
||||
|
@ -591,3 +586,25 @@ function openStyleContextMenuAndGetAllItems(view, target) {
|
|||
|
||||
return allItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the style editor context menu and return all of it's items in a flat array
|
||||
* @param {CssRuleView} view
|
||||
* The instance of the rule-view panel
|
||||
* @return An array of MenuItems
|
||||
*/
|
||||
function openStyleContextMenuAndGetAllItems(view, target) {
|
||||
const menu = view._contextmenu._openMenu({target: target});
|
||||
return buildContextMenuItems(menu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the inspector menu and return all of it's items in a flat array
|
||||
* @param {InspectorPanel} inspector
|
||||
* @param {Object} options to pass into openMenu
|
||||
* @return An array of MenuItems
|
||||
*/
|
||||
function openContextMenuAndGetAllItems(inspector, options) {
|
||||
const menu = inspector._openMenu(options);
|
||||
return buildContextMenuItems(menu);
|
||||
}
|
||||
|
|
|
@ -301,6 +301,13 @@ inspectorImageDataUri.label=Image Data-URL
|
|||
# opens the split Console and displays the properties in its side panel.
|
||||
inspectorShowDOMProperties.label=Show DOM Properties
|
||||
|
||||
# LOCALIZATION NOTE (inspectorShowAccessibilityProperties.label): This is the
|
||||
# label shown in the inspector contextual-menu for the item that lets users see
|
||||
# the accessibility tree and accessibility properties of the current node.
|
||||
# When triggered, this item opens accessibility panel and selects an accessible
|
||||
# object for the given node.
|
||||
inspectorShowAccessibilityProperties.label=Show Accessibility Properties
|
||||
|
||||
# LOCALIZATION NOTE (inspectorUseInConsole.label): This is the label
|
||||
# shown in the inspector contextual-menu for the item that outputs a
|
||||
# variable for the current node to the console. When triggered,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const {Ci, Cu} = require("chrome");
|
||||
const {Cc, Ci, Cu} = require("chrome");
|
||||
|
||||
const Services = require("Services");
|
||||
const protocol = require("devtools/shared/protocol");
|
||||
|
@ -2014,6 +2014,21 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
|
|||
|
||||
return this._ref(offsetParent);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if accessibility service is running and the node has a
|
||||
* corresponding valid accessible object.
|
||||
*/
|
||||
hasAccessibilityProperties: async function(node) {
|
||||
if (isNodeDead(node) || !Services.appinfo.accessibilityEnabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const accService = Cc["@mozilla.org/accessibilityService;1"].getService(
|
||||
Ci.nsIAccessibilityService);
|
||||
const acc = accService.getAccessibleFor(node.rawNode);
|
||||
return acc && acc.indexInParent > -1;
|
||||
},
|
||||
});
|
||||
|
||||
exports.WalkerActor = WalkerActor;
|
||||
|
|
|
@ -348,9 +348,7 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
* Hook to modify the packet before it is sent. Feel free to return a
|
||||
* promise.
|
||||
*/
|
||||
_pauseAndRespond: function(frame, reason, onPacket = function(k) {
|
||||
return k;
|
||||
}) {
|
||||
_pauseAndRespond: async function(frame, reason, onPacket = k => k) {
|
||||
try {
|
||||
let packet = this._paused(frame);
|
||||
if (!packet) {
|
||||
|
@ -359,28 +357,27 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
packet.why = reason;
|
||||
|
||||
let generatedLocation = this.sources.getFrameLocation(frame);
|
||||
this.sources.getOriginalLocation(generatedLocation)
|
||||
.then((originalLocation) => {
|
||||
if (!originalLocation.originalSourceActor) {
|
||||
this.sources.getOriginalLocation(generatedLocation).then((originalLocation) => {
|
||||
if (!originalLocation.originalSourceActor) {
|
||||
// The only time the source actor will be null is if there
|
||||
// was a sourcemap and it tried to look up the original
|
||||
// location but there was no original URL. This is a strange
|
||||
// scenario so we simply don't pause.
|
||||
DevToolsUtils.reportException(
|
||||
DevToolsUtils.reportException(
|
||||
"ThreadActor",
|
||||
new Error("Attempted to pause in a script with a sourcemap but " +
|
||||
"could not find original location.")
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
packet.frame.where = {
|
||||
source: originalLocation.originalSourceActor.form(),
|
||||
line: originalLocation.originalLine,
|
||||
column: originalLocation.originalColumn
|
||||
};
|
||||
|
||||
packet.frame.where = {
|
||||
source: originalLocation.originalSourceActor.form(),
|
||||
line: originalLocation.originalLine,
|
||||
column: originalLocation.originalColumn
|
||||
};
|
||||
Promise.resolve(onPacket(packet))
|
||||
Promise.resolve(onPacket(packet))
|
||||
.catch(error => {
|
||||
reportError(error);
|
||||
return {
|
||||
|
@ -392,8 +389,8 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
this.conn.send(pkt);
|
||||
});
|
||||
|
||||
return undefined;
|
||||
});
|
||||
return undefined;
|
||||
});
|
||||
|
||||
this._pushThreadPause();
|
||||
} catch (e) {
|
||||
|
@ -410,12 +407,16 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
return frame => {
|
||||
const generatedLocation = this.sources.getFrameLocation(frame);
|
||||
let { originalSourceActor } = this.unsafeSynchronize(
|
||||
this.sources.getOriginalLocation(generatedLocation));
|
||||
this.sources.getOriginalLocation(generatedLocation)
|
||||
);
|
||||
|
||||
let url = originalSourceActor.url;
|
||||
|
||||
return this.sources.isBlackBoxed(url)
|
||||
? undefined
|
||||
: pauseAndRespond(frame);
|
||||
if (this.sources.isBlackBoxed(url)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return pauseAndRespond(frame);
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -423,10 +424,11 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
startLocation }) {
|
||||
const result = function(completion) {
|
||||
// onPop is called with 'this' set to the current frame.
|
||||
|
||||
const generatedLocation = thread.sources.getFrameLocation(this);
|
||||
const { originalSourceActor } = thread.unsafeSynchronize(
|
||||
thread.sources.getOriginalLocation(generatedLocation));
|
||||
thread.sources.getOriginalLocation(generatedLocation)
|
||||
);
|
||||
|
||||
const url = originalSourceActor.url;
|
||||
|
||||
if (thread.sources.isBlackBoxed(url)) {
|
||||
|
@ -465,12 +467,10 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
},
|
||||
|
||||
_makeOnStep: function({ thread, pauseAndRespond, startFrame,
|
||||
startLocation, steppingType }) {
|
||||
startLocation, steppingType }) {
|
||||
// Breaking in place: we should always pause.
|
||||
if (steppingType === "break") {
|
||||
return function() {
|
||||
return pauseAndRespond(this);
|
||||
};
|
||||
return () => pauseAndRespond(this);
|
||||
}
|
||||
|
||||
// Otherwise take what a "step" means into consideration.
|
||||
|
@ -489,8 +489,9 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
}
|
||||
|
||||
const generatedLocation = thread.sources.getFrameLocation(this);
|
||||
const newLocation = thread.unsafeSynchronize(thread.sources.getOriginalLocation(
|
||||
generatedLocation));
|
||||
const newLocation = thread.unsafeSynchronize(
|
||||
thread.sources.getOriginalLocation(generatedLocation)
|
||||
);
|
||||
|
||||
// Cases when we should pause because we have executed enough to consider
|
||||
// a "step" to have occured:
|
||||
|
@ -559,11 +560,12 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
// binding in each _makeOnX method, just do it once here and pass it
|
||||
// in to each function.
|
||||
const steppingHookState = {
|
||||
pauseAndRespond: (frame, onPacket = k=>k) => {
|
||||
return this._pauseAndRespond(frame, { type: "resumeLimit" }, onPacket);
|
||||
},
|
||||
createValueGrip: v => createValueGrip(v, this._pausePool,
|
||||
this.objectGrip),
|
||||
pauseAndRespond: (frame, onPacket = k=>k) => this._pauseAndRespond(
|
||||
frame,
|
||||
{ type: "resumeLimit" },
|
||||
onPacket
|
||||
),
|
||||
createValueGrip: v => createValueGrip(v, this._pausePool, this.objectGrip),
|
||||
thread: this,
|
||||
startFrame: this.youngestFrame,
|
||||
startLocation: startLocation,
|
||||
|
@ -586,41 +588,42 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
* @returns A promise that resolves to true once the hooks are attached, or is
|
||||
* rejected with an error packet.
|
||||
*/
|
||||
_handleResumeLimit: function(request) {
|
||||
_handleResumeLimit: async function(request) {
|
||||
let steppingType = request.resumeLimit.type;
|
||||
if (!["break", "step", "next", "finish"].includes(steppingType)) {
|
||||
return Promise.reject({ error: "badParameterType",
|
||||
message: "Unknown resumeLimit type" });
|
||||
return Promise.reject({
|
||||
error: "badParameterType",
|
||||
message: "Unknown resumeLimit type"
|
||||
});
|
||||
}
|
||||
|
||||
const generatedLocation = this.sources.getFrameLocation(this.youngestFrame);
|
||||
return this.sources.getOriginalLocation(generatedLocation)
|
||||
.then(originalLocation => {
|
||||
const { onEnterFrame, onPop, onStep } = this._makeSteppingHooks(originalLocation,
|
||||
steppingType);
|
||||
const originalLocation = await this.sources.getOriginalLocation(generatedLocation);
|
||||
const { onEnterFrame, onPop, onStep } = this._makeSteppingHooks(
|
||||
originalLocation,
|
||||
steppingType
|
||||
);
|
||||
|
||||
// Make sure there is still a frame on the stack if we are to continue
|
||||
// stepping.
|
||||
let stepFrame = this._getNextStepFrame(this.youngestFrame);
|
||||
if (stepFrame) {
|
||||
switch (steppingType) {
|
||||
case "step":
|
||||
this.dbg.onEnterFrame = onEnterFrame;
|
||||
// Fall through.
|
||||
case "break":
|
||||
case "next":
|
||||
if (stepFrame.script) {
|
||||
stepFrame.onStep = onStep;
|
||||
}
|
||||
stepFrame.onPop = onPop;
|
||||
break;
|
||||
case "finish":
|
||||
stepFrame.onPop = onPop;
|
||||
// Make sure there is still a frame on the stack if we are to continue stepping.
|
||||
let stepFrame = this._getNextStepFrame(this.youngestFrame);
|
||||
if (stepFrame) {
|
||||
switch (steppingType) {
|
||||
case "step":
|
||||
this.dbg.onEnterFrame = onEnterFrame;
|
||||
// Fall through.
|
||||
case "break":
|
||||
case "next":
|
||||
if (stepFrame.script) {
|
||||
stepFrame.onStep = onStep;
|
||||
}
|
||||
}
|
||||
stepFrame.onPop = onPop;
|
||||
break;
|
||||
case "finish":
|
||||
stepFrame.onPop = onPop;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1345,14 +1348,23 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
if (completion == null) {
|
||||
protoValue.terminated = true;
|
||||
} else if ("return" in completion) {
|
||||
protoValue.return = createValueGrip(completion.return,
|
||||
this._pausePool, this.objectGrip);
|
||||
protoValue.return = createValueGrip(
|
||||
completion.return,
|
||||
this._pausePool,
|
||||
this.objectGrip
|
||||
);
|
||||
} else if ("throw" in completion) {
|
||||
protoValue.throw = createValueGrip(completion.throw,
|
||||
this._pausePool, this.objectGrip);
|
||||
protoValue.throw = createValueGrip(
|
||||
completion.throw,
|
||||
this._pausePool,
|
||||
this.objectGrip
|
||||
);
|
||||
} else {
|
||||
protoValue.return = createValueGrip(completion.yield,
|
||||
this._pausePool, this.objectGrip);
|
||||
protoValue.return = createValueGrip(
|
||||
completion.yield,
|
||||
this._pausePool,
|
||||
this.objectGrip
|
||||
);
|
||||
}
|
||||
return protoValue;
|
||||
},
|
||||
|
|
|
@ -330,6 +330,14 @@ const walkerSpec = generateActorSpec({
|
|||
node: RetVal("nullable:domnode")
|
||||
}
|
||||
},
|
||||
hasAccessibilityProperties: {
|
||||
request: {
|
||||
node: Arg(0, "nullable:domnode")
|
||||
},
|
||||
response: {
|
||||
value: RetVal("boolean")
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -10140,7 +10140,7 @@ nsContentUtils::UnregisterUnresolvedElement(Element* aElement)
|
|||
{
|
||||
MOZ_ASSERT(aElement);
|
||||
|
||||
RefPtr<nsAtom> typeAtom =
|
||||
nsAtom* typeAtom =
|
||||
aElement->GetCustomElementData()->GetCustomElementType();
|
||||
nsIDocument* doc = aElement->OwnerDoc();
|
||||
nsPIDOMWindowInner* window(doc->GetInnerWindow());
|
||||
|
@ -10148,7 +10148,7 @@ nsContentUtils::UnregisterUnresolvedElement(Element* aElement)
|
|||
return;
|
||||
}
|
||||
|
||||
RefPtr<CustomElementRegistry> registry(window->CustomElements());
|
||||
CustomElementRegistry* registry = window->CustomElements();
|
||||
if (!registry) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -546,7 +546,6 @@ ContentChild::ContentChild()
|
|||
#endif
|
||||
, mIsAlive(true)
|
||||
, mShuttingDown(false)
|
||||
, mShutdownTimeout(0)
|
||||
{
|
||||
// This process is a content process, so it's clearly running in
|
||||
// multiprocess mode!
|
||||
|
@ -561,12 +560,6 @@ ContentChild::ContentChild()
|
|||
sShutdownCanary = new ShutdownCanary();
|
||||
ClearOnShutdown(&sShutdownCanary, ShutdownPhase::Shutdown);
|
||||
}
|
||||
// If a shutdown message is received from within a nested event loop, we set
|
||||
// the timeout for the nested event loop to half the ForceKillTimer timeout
|
||||
// (in ms) to leave enough time to send the FinishShutdown message to the
|
||||
// parent.
|
||||
mShutdownTimeout =
|
||||
Preferences::GetInt("dom.ipc.tabs.shutdownTimeoutSecs", 5) * 1000 / 2;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -3020,32 +3013,28 @@ ContentChild::RecvShutdown()
|
|||
void
|
||||
ContentChild::ShutdownInternal()
|
||||
{
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCShutdownState"),
|
||||
NS_LITERAL_CSTRING("RecvShutdown"));
|
||||
|
||||
// If we receive the shutdown message from within a nested event loop, we want
|
||||
// to wait for that event loop to finish. Otherwise we could prematurely
|
||||
// terminate an "unload" or "pagehide" event handler (which might be doing a
|
||||
// sync XHR, for example). However, we need to strike a balance and shut down
|
||||
// within a reasonable amount of time (mShutdownTimeout) or the ForceKillTimer
|
||||
// in the parent will execute and kill us hard.
|
||||
// sync XHR, for example).
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCShutdownState"),
|
||||
NS_LITERAL_CSTRING("RecvShutdown"));
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RefPtr<nsThread> mainThread = nsThreadManager::get().GetCurrentThread();
|
||||
// Note that we only have to check the recursion count for the current
|
||||
// cooperative thread. Since the Shutdown message is not labeled with a
|
||||
// SchedulerGroup, there can be no other cooperative threads doing work while
|
||||
// we're running.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RefPtr<nsThread> mainThread = nsThreadManager::get().GetCurrentThread();
|
||||
if (mainThread && mainThread->RecursionDepth() > 1 && mShutdownTimeout > 0) {
|
||||
if (mainThread && mainThread->RecursionDepth() > 1) {
|
||||
// We're in a nested event loop. Let's delay for an arbitrary period of
|
||||
// time (100ms) in the hopes that the event loop will have finished by
|
||||
// then.
|
||||
int32_t delay = 100;
|
||||
MessageLoop::current()->PostDelayedTask(
|
||||
NewRunnableMethod(
|
||||
"dom::ContentChild::RecvShutdown", this,
|
||||
&ContentChild::ShutdownInternal),
|
||||
delay);
|
||||
mShutdownTimeout -= delay;
|
||||
100);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -828,7 +828,6 @@ private:
|
|||
nsClassHashtable<nsUint64HashKey, AnonymousTemporaryFileCallback> mPendingAnonymousTemporaryFiles;
|
||||
|
||||
mozilla::Atomic<bool> mShuttingDown;
|
||||
int32_t mShutdownTimeout;
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
// NOTE: This member is atomic because it can be accessed from off-main-thread.
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
#include "ServiceWorkerUnregisterJob.h"
|
||||
#include "ServiceWorkerUpdateJob.h"
|
||||
#include "ServiceWorkerUpdaterChild.h"
|
||||
#include "ServiceWorkerUtils.h"
|
||||
|
||||
#ifdef PostMessage
|
||||
#undef PostMessage
|
||||
|
@ -196,27 +197,28 @@ PopulateRegistrationData(nsIPrincipal* aPrincipal,
|
|||
|
||||
aData.scope() = aRegistration->Scope();
|
||||
|
||||
RefPtr<ServiceWorkerInfo> newest = aRegistration->Newest();
|
||||
if (NS_WARN_IF(!newest)) {
|
||||
// TODO: When bug 1426401 is implemented we will need to handle more
|
||||
// than just the active worker here.
|
||||
RefPtr<ServiceWorkerInfo> active = aRegistration->GetActive();
|
||||
MOZ_ASSERT(active);
|
||||
if (NS_WARN_IF(!active)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (aRegistration->GetActive()) {
|
||||
aData.currentWorkerURL() = aRegistration->GetActive()->ScriptSpec();
|
||||
aData.cacheName() = aRegistration->GetActive()->CacheName();
|
||||
aData.currentWorkerHandlesFetch() = aRegistration->GetActive()->HandlesFetch();
|
||||
aData.currentWorkerURL() = active->ScriptSpec();
|
||||
aData.cacheName() = active->CacheName();
|
||||
aData.currentWorkerHandlesFetch() = active->HandlesFetch();
|
||||
|
||||
aData.currentWorkerInstalledTime() =
|
||||
aRegistration->GetActive()->GetInstalledTime();
|
||||
aData.currentWorkerActivatedTime() =
|
||||
aRegistration->GetActive()->GetActivatedTime();
|
||||
}
|
||||
aData.currentWorkerInstalledTime() = active->GetInstalledTime();
|
||||
aData.currentWorkerActivatedTime() = active->GetActivatedTime();
|
||||
|
||||
aData.updateViaCache() =
|
||||
static_cast<uint32_t>(aRegistration->GetUpdateViaCache());
|
||||
|
||||
aData.lastUpdateTime() = aRegistration->GetLastUpdateTime();
|
||||
|
||||
MOZ_ASSERT(ServiceWorkerRegistrationDataIsValid(aData));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,13 +40,8 @@ ServiceWorkerRegisterJob::AsyncExecute()
|
|||
bool sameUVC = GetUpdateViaCache() == registration->GetUpdateViaCache();
|
||||
registration->SetUpdateViaCache(GetUpdateViaCache());
|
||||
|
||||
// If we are resurrecting an uninstalling registration, then persist
|
||||
// it to disk again. We preemptively removed it earlier during
|
||||
// unregister so that closing the window by shutting down the browser
|
||||
// results in the registration being gone on restart.
|
||||
if (registration->IsPendingUninstall()) {
|
||||
registration->ClearPendingUninstall();
|
||||
swm->StoreRegistration(mPrincipal, registration);
|
||||
// Its possible that a ready promise is created between when the
|
||||
// uninstalling flag is set and when we resurrect the registration
|
||||
// here. In that case we might need to fire the ready promise
|
||||
|
|
|
@ -689,6 +689,12 @@ ServiceWorkerRegistrar::ReadData()
|
|||
|
||||
// Copy data over to mData.
|
||||
for (uint32_t i = 0; i < tmpData.Length(); ++i) {
|
||||
// Older versions could sometimes write out empty, useless entries.
|
||||
// Prune those here.
|
||||
if (!ServiceWorkerRegistrationDataIsValid(tmpData[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bool match = false;
|
||||
if (dedupe) {
|
||||
MOZ_ASSERT(overwrite);
|
||||
|
@ -779,6 +785,7 @@ ServiceWorkerRegistrar::RegisterServiceWorkerInternal(const ServiceWorkerRegistr
|
|||
}
|
||||
|
||||
if (!found) {
|
||||
MOZ_ASSERT(ServiceWorkerRegistrationDataIsValid(aData));
|
||||
mData.AppendElement(aData);
|
||||
}
|
||||
}
|
||||
|
@ -956,6 +963,12 @@ ServiceWorkerRegistrar::WriteData()
|
|||
}
|
||||
|
||||
for (uint32_t i = 0, len = data.Length(); i < len; ++i) {
|
||||
// We have an assertion further up the stack, but as a last
|
||||
// resort avoid writing out broken entries here.
|
||||
if (!ServiceWorkerRegistrationDataIsValid(data[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const mozilla::ipc::PrincipalInfo& info = data[i].principal();
|
||||
|
||||
MOZ_ASSERT(info.type() == mozilla::ipc::PrincipalInfo::TContentPrincipalInfo);
|
||||
|
|
|
@ -141,6 +141,16 @@ ServiceWorkerRegistrationInfo::SetPendingUninstall()
|
|||
void
|
||||
ServiceWorkerRegistrationInfo::ClearPendingUninstall()
|
||||
{
|
||||
// If we are resurrecting an uninstalling registration, then persist
|
||||
// it to disk again. We preemptively removed it earlier during
|
||||
// unregister so that closing the window by shutting down the browser
|
||||
// results in the registration being gone on restart.
|
||||
if (mPendingUninstall && mActiveWorker) {
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
if (swm) {
|
||||
swm->StoreRegistration(mPrincipal, this);
|
||||
}
|
||||
}
|
||||
mPendingUninstall = false;
|
||||
}
|
||||
|
||||
|
@ -607,12 +617,8 @@ ServiceWorkerRegistrationInfo::TransitionInstallingToWaiting()
|
|||
|
||||
NotifyChromeRegistrationListeners();
|
||||
|
||||
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
|
||||
if (!swm) {
|
||||
// browser shutdown began
|
||||
return;
|
||||
}
|
||||
swm->StoreRegistration(mPrincipal, this);
|
||||
// TODO: When bug 1426401 is implemented we will need to call
|
||||
// StoreRegistration() here to persist the waiting worker.
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -32,5 +32,13 @@ ServiceWorkerParentInterceptEnabled()
|
|||
return sEnabled;
|
||||
}
|
||||
|
||||
bool
|
||||
ServiceWorkerRegistrationDataIsValid(const ServiceWorkerRegistrationData& aData)
|
||||
{
|
||||
return !aData.scope().IsEmpty() &&
|
||||
!aData.currentWorkerURL().IsEmpty() &&
|
||||
!aData.cacheName().IsEmpty();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ServiceWorkerRegistrationData;
|
||||
class ServiceWorkerRegistrationDescriptor;
|
||||
|
||||
typedef MozPromise<ServiceWorkerRegistrationDescriptor, nsresult, false>
|
||||
|
@ -20,6 +21,9 @@ typedef MozPromise<ServiceWorkerRegistrationDescriptor, nsresult, false>
|
|||
bool
|
||||
ServiceWorkerParentInterceptEnabled();
|
||||
|
||||
bool
|
||||
ServiceWorkerRegistrationDataIsValid(const ServiceWorkerRegistrationData& aData);
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
function f() {
|
||||
var t = new Float32Array(1);
|
||||
t[t.length] = 1;
|
||||
return t[t.length];
|
||||
}
|
||||
for (var i = 0; i < 5; i++)
|
||||
assertEq(f(), undefined);
|
|
@ -10237,14 +10237,11 @@ CodeGenerator::link(JSContext* cx, CompilerConstraintList* constraints)
|
|||
// will trickle to jit::Compile() and return Method_Skipped.
|
||||
uint32_t warmUpCount = script->getWarmUpCount();
|
||||
|
||||
JitRuntime* jrt = cx->runtime()->jitRuntime();
|
||||
IonCompilationId compilationId = jrt->nextCompilationId();
|
||||
#ifdef DEBUG
|
||||
jrt->currentCompilationId().emplace(compilationId);
|
||||
auto resetCurrentId = mozilla::MakeScopeExit([jrt] {
|
||||
jrt->currentCompilationId().reset();
|
||||
IonCompilationId compilationId = cx->runtime()->jitRuntime()->nextCompilationId();
|
||||
cx->zone()->types.currentCompilationIdRef().emplace(compilationId);
|
||||
auto resetCurrentId = mozilla::MakeScopeExit([cx] {
|
||||
cx->zone()->types.currentCompilationIdRef().reset();
|
||||
});
|
||||
#endif
|
||||
|
||||
// Record constraints. If an error occured, returns false and potentially
|
||||
// prevent future compilations. Otherwise, if an invalidation occured, then
|
||||
|
|
|
@ -2870,7 +2870,7 @@ jit::Invalidate(TypeZone& types, FreeOp* fop,
|
|||
if (cancelOffThread)
|
||||
CancelOffThreadIonCompile(info.script());
|
||||
|
||||
IonScript* ionScript = info.maybeIonScriptToInvalidate();
|
||||
IonScript* ionScript = info.maybeIonScriptToInvalidate(types);
|
||||
if (!ionScript)
|
||||
continue;
|
||||
|
||||
|
@ -2897,7 +2897,7 @@ jit::Invalidate(TypeZone& types, FreeOp* fop,
|
|||
// IonScript will be immediately destroyed. Otherwise, it will be held live
|
||||
// until its last invalidated frame is destroyed.
|
||||
for (const RecompileInfo& info : invalid) {
|
||||
IonScript* ionScript = info.maybeIonScriptToInvalidate();
|
||||
IonScript* ionScript = info.maybeIonScriptToInvalidate(types);
|
||||
if (!ionScript)
|
||||
continue;
|
||||
|
||||
|
@ -2919,7 +2919,7 @@ jit::Invalidate(TypeZone& types, FreeOp* fop,
|
|||
|
||||
// Finally, null out script->ion for IonScripts that are still on the stack.
|
||||
for (const RecompileInfo& info : invalid) {
|
||||
if (info.maybeIonScriptToInvalidate())
|
||||
if (info.maybeIonScriptToInvalidate(types))
|
||||
ClearIonScriptAfterInvalidation(cx, info.script(), resetUses);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,9 +65,6 @@ class JitRuntime
|
|||
ActiveThreadData<ExecutableAllocator> execAlloc_;
|
||||
|
||||
ActiveThreadData<uint64_t> nextCompilationId_;
|
||||
#ifdef DEBUG
|
||||
ActiveThreadData<mozilla::Maybe<IonCompilationId>> currentCompilationId_;
|
||||
#endif
|
||||
|
||||
// Shared exception-handler tail.
|
||||
ExclusiveAccessLockWriteOnceData<uint32_t> exceptionTailOffset_;
|
||||
|
@ -190,11 +187,6 @@ class JitRuntime
|
|||
IonCompilationId nextCompilationId() {
|
||||
return IonCompilationId(nextCompilationId_++);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
mozilla::Maybe<IonCompilationId>& currentCompilationId() {
|
||||
return currentCompilationId_.ref();
|
||||
}
|
||||
#endif
|
||||
|
||||
TrampolinePtr getVMWrapper(const VMFunction& f) const;
|
||||
JitCode* debugTrapHandler(JSContext* cx);
|
||||
|
|
|
@ -1430,6 +1430,8 @@ CodeGenerator::visitUnbox(LUnbox* unbox)
|
|||
// inputs.
|
||||
MUnbox* mir = unbox->mir();
|
||||
Register type = ToRegister(unbox->type());
|
||||
Register payload = ToRegister(unbox->payload());
|
||||
Register output = ToRegister(unbox->output());
|
||||
|
||||
mozilla::Maybe<ScratchRegisterScope> scratch;
|
||||
scratch.emplace(masm);
|
||||
|
@ -1448,6 +1450,11 @@ CodeGenerator::visitUnbox(LUnbox* unbox)
|
|||
masm.bind(&ok);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Note: If spectreValueMasking is disabled, then this instruction will
|
||||
// default to a no-op as long as the lowering allocate the same register for
|
||||
// the output and the payload.
|
||||
masm.unboxNonDouble(ValueOperand(type, payload), output, ValueTypeFromMIRType(mir->type()));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -2176,7 +2176,6 @@ void
|
|||
MacroAssembler::spectreBoundsCheck32(Register index, Register length, Register maybeScratch,
|
||||
Label* failure)
|
||||
{
|
||||
MOZ_ASSERT(index != length);
|
||||
MOZ_ASSERT(length != maybeScratch);
|
||||
MOZ_ASSERT(index != maybeScratch);
|
||||
|
||||
|
|
|
@ -3000,26 +3000,62 @@ MacroAssemblerARMCompat::testGCThing(Condition cond, const BaseIndex& address)
|
|||
|
||||
// Unboxing code.
|
||||
void
|
||||
MacroAssemblerARMCompat::unboxNonDouble(const ValueOperand& operand, Register dest, JSValueType)
|
||||
MacroAssemblerARMCompat::unboxNonDouble(const ValueOperand& operand, Register dest, JSValueType type)
|
||||
{
|
||||
if (operand.payloadReg() != dest)
|
||||
ma_mov(operand.payloadReg(), dest);
|
||||
auto movPayloadToDest = [&]() {
|
||||
if (operand.payloadReg() != dest)
|
||||
ma_mov(operand.payloadReg(), dest, LeaveCC);
|
||||
};
|
||||
if (!JitOptions.spectreValueMasking) {
|
||||
movPayloadToDest();
|
||||
return;
|
||||
}
|
||||
|
||||
// Spectre mitigation: We zero the payload if the tag does not match the
|
||||
// expected type and if this is a pointer type.
|
||||
if (type == JSVAL_TYPE_INT32 || type == JSVAL_TYPE_BOOLEAN) {
|
||||
movPayloadToDest();
|
||||
return;
|
||||
}
|
||||
|
||||
// We zero the destination register and move the payload into it if
|
||||
// the tag corresponds to the given type.
|
||||
ma_cmp(operand.typeReg(), ImmType(type));
|
||||
movPayloadToDest();
|
||||
ma_mov(Imm32(0), dest, NotEqual);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::unboxNonDouble(const Address& src, Register dest, JSValueType)
|
||||
MacroAssemblerARMCompat::unboxNonDouble(const Address& src, Register dest, JSValueType type)
|
||||
{
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
ma_ldr(ToPayload(src), dest, scratch);
|
||||
if (!JitOptions.spectreValueMasking) {
|
||||
ma_ldr(ToPayload(src), dest, scratch);
|
||||
return;
|
||||
}
|
||||
|
||||
// Spectre mitigation: We zero the payload if the tag does not match the
|
||||
// expected type and if this is a pointer type.
|
||||
if (type == JSVAL_TYPE_INT32 || type == JSVAL_TYPE_BOOLEAN) {
|
||||
ma_ldr(ToPayload(src), dest, scratch);
|
||||
return;
|
||||
}
|
||||
|
||||
// We zero the destination register and move the payload into it if
|
||||
// the tag corresponds to the given type.
|
||||
ma_ldr(ToType(src), scratch, scratch);
|
||||
ma_cmp(scratch, ImmType(type));
|
||||
ma_ldr(ToPayload(src), dest, scratch, Offset, Equal);
|
||||
ma_mov(Imm32(0), dest, NotEqual);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::unboxNonDouble(const BaseIndex& src, Register dest, JSValueType)
|
||||
MacroAssemblerARMCompat::unboxNonDouble(const BaseIndex& src, Register dest, JSValueType type)
|
||||
{
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
SecondScratchRegisterScope scratch2(asMasm());
|
||||
ma_alu(src.base, lsl(src.index, src.scale), scratch, OpAdd);
|
||||
ma_ldr(Address(scratch, src.offset), dest, scratch2);
|
||||
ma_alu(src.base, lsl(src.index, src.scale), scratch2, OpAdd);
|
||||
Address value(scratch2, src.offset);
|
||||
unboxNonDouble(value, dest, type);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3048,8 +3084,8 @@ MacroAssemblerARMCompat::unboxValue(const ValueOperand& src, AnyRegister dest, J
|
|||
bind(¬Int32);
|
||||
unboxDouble(src, dest.fpu());
|
||||
bind(&end);
|
||||
} else if (src.payloadReg() != dest.gpr()) {
|
||||
as_mov(dest.gpr(), O2Reg(src.payloadReg()));
|
||||
} else {
|
||||
unboxNonDouble(src, dest.gpr(), type);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -829,12 +829,15 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
|||
// and returns that.
|
||||
Register extractObject(const Address& address, Register scratch);
|
||||
Register extractObject(const ValueOperand& value, Register scratch) {
|
||||
unboxNonDouble(value, value.payloadReg(), JSVAL_TYPE_OBJECT);
|
||||
return value.payloadReg();
|
||||
}
|
||||
Register extractString(const ValueOperand& value, Register scratch) {
|
||||
unboxNonDouble(value, value.payloadReg(), JSVAL_TYPE_STRING);
|
||||
return value.payloadReg();
|
||||
}
|
||||
Register extractSymbol(const ValueOperand& value, Register scratch) {
|
||||
unboxNonDouble(value, value.payloadReg(), JSVAL_TYPE_SYMBOL);
|
||||
return value.payloadReg();
|
||||
}
|
||||
Register extractInt32(const ValueOperand& value, Register scratch) {
|
||||
|
|
|
@ -1855,7 +1855,6 @@ void
|
|||
MacroAssembler::spectreBoundsCheck32(Register index, Register length, Register maybeScratch,
|
||||
Label* failure)
|
||||
{
|
||||
MOZ_ASSERT(index != length);
|
||||
MOZ_ASSERT(length != maybeScratch);
|
||||
MOZ_ASSERT(index != maybeScratch);
|
||||
|
||||
|
|
|
@ -856,7 +856,6 @@ void
|
|||
MacroAssembler::spectreBoundsCheck32(Register index, Register length, Register maybeScratch,
|
||||
Label* failure)
|
||||
{
|
||||
MOZ_ASSERT(index != length);
|
||||
MOZ_ASSERT(length != maybeScratch);
|
||||
MOZ_ASSERT(index != maybeScratch);
|
||||
|
||||
|
|
|
@ -1081,7 +1081,6 @@ void
|
|||
MacroAssembler::spectreBoundsCheck32(Register index, Register length, Register maybeScratch,
|
||||
Label* failure)
|
||||
{
|
||||
MOZ_ASSERT(index != length);
|
||||
MOZ_ASSERT(length != maybeScratch);
|
||||
MOZ_ASSERT(index != maybeScratch);
|
||||
|
||||
|
|
|
@ -36,11 +36,13 @@ namespace js {
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
jit::IonScript*
|
||||
RecompileInfo::maybeIonScriptToInvalidate() const
|
||||
RecompileInfo::maybeIonScriptToInvalidate(const TypeZone& zone) const
|
||||
{
|
||||
MOZ_ASSERT(script_->zone() == zone.zone());
|
||||
|
||||
// Make sure this is not called under CodeGenerator::link (before the
|
||||
// IonScript is created).
|
||||
MOZ_ASSERT(!TlsContext.get()->runtime()->jitRuntime()->currentCompilationId().isSome());
|
||||
MOZ_ASSERT_IF(zone.currentCompilationId(), zone.currentCompilationId().ref() != id_);
|
||||
|
||||
if (!script_->hasIonScript() || script_->ionScript()->compilationId() != id_)
|
||||
return nullptr;
|
||||
|
@ -49,11 +51,19 @@ RecompileInfo::maybeIonScriptToInvalidate() const
|
|||
}
|
||||
|
||||
inline bool
|
||||
RecompileInfo::shouldSweep()
|
||||
RecompileInfo::shouldSweep(const TypeZone& zone)
|
||||
{
|
||||
if (IsAboutToBeFinalizedUnbarriered(&script_))
|
||||
return true;
|
||||
return maybeIonScriptToInvalidate() == nullptr;
|
||||
|
||||
MOZ_ASSERT(script_->zone() == zone.zone());
|
||||
|
||||
// Don't sweep if we're called under CodeGenerator::link, before the
|
||||
// IonScript is created.
|
||||
if (zone.currentCompilationId() && zone.currentCompilationId().ref() == id_)
|
||||
return false;
|
||||
|
||||
return maybeIonScriptToInvalidate(zone) == nullptr;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -1213,7 +1213,7 @@ class TypeCompilerConstraint : public TypeConstraint
|
|||
}
|
||||
|
||||
bool sweep(TypeZone& zone, TypeConstraint** res) override {
|
||||
if (data.shouldSweep() || compilation.shouldSweep())
|
||||
if (data.shouldSweep() || compilation.shouldSweep(zone))
|
||||
return false;
|
||||
*res = zone.typeLifoAlloc().new_<TypeCompilerConstraint<T> >(compilation, data);
|
||||
return true;
|
||||
|
@ -1422,7 +1422,7 @@ bool
|
|||
js::FinishCompilation(JSContext* cx, HandleScript script, CompilerConstraintList* constraints,
|
||||
IonCompilationId compilationId, bool* isValidOut)
|
||||
{
|
||||
MOZ_ASSERT(*cx->runtime()->jitRuntime()->currentCompilationId() == compilationId);
|
||||
MOZ_ASSERT(*cx->zone()->types.currentCompilationId() == compilationId);
|
||||
|
||||
if (constraints->failed())
|
||||
return false;
|
||||
|
@ -4415,7 +4415,7 @@ JSScript::maybeSweepTypes(AutoClearTypeInferenceStateOnOOM* oom)
|
|||
RecompileInfoVector& inlinedCompilations = types_->inlinedCompilations();
|
||||
size_t dest = 0;
|
||||
for (size_t i = 0; i < inlinedCompilations.length(); i++) {
|
||||
if (inlinedCompilations[i].shouldSweep())
|
||||
if (inlinedCompilations[i].shouldSweep(types))
|
||||
continue;
|
||||
inlinedCompilations[dest] = inlinedCompilations[i];
|
||||
dest++;
|
||||
|
@ -4485,6 +4485,7 @@ Zone::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
|
|||
TypeZone::TypeZone(Zone* zone)
|
||||
: zone_(zone),
|
||||
typeLifoAlloc_(zone->group(), (size_t) TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
|
||||
currentCompilationId_(zone->group()),
|
||||
generation(zone->group(), 0),
|
||||
sweepTypeLifoAlloc(zone->group(), (size_t) TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
|
||||
sweepReleaseTypes(zone->group(), false),
|
||||
|
|
|
@ -1106,17 +1106,21 @@ ClassCanHaveExtraProperties(const Class* clasp);
|
|||
// constraints for IonScripts that have been invalidated/destroyed.
|
||||
class IonCompilationId
|
||||
{
|
||||
uint64_t id_;
|
||||
// Use two 32-bit integers instead of uint64_t to avoid 8-byte alignment on
|
||||
// some 32-bit platforms.
|
||||
uint32_t idLo_;
|
||||
uint32_t idHi_;
|
||||
|
||||
public:
|
||||
explicit IonCompilationId(uint64_t id)
|
||||
: id_(id)
|
||||
: idLo_(id & UINT32_MAX),
|
||||
idHi_(id >> 32)
|
||||
{}
|
||||
bool operator==(const IonCompilationId& other) const {
|
||||
return id_ == other.id_;
|
||||
return idLo_ == other.idLo_ && idHi_ == other.idHi_;
|
||||
}
|
||||
bool operator!=(const IonCompilationId& other) const {
|
||||
return id_ != other.id_;
|
||||
return !operator==(other);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1135,9 +1139,9 @@ class RecompileInfo
|
|||
return script_;
|
||||
}
|
||||
|
||||
inline jit::IonScript* maybeIonScriptToInvalidate() const;
|
||||
inline jit::IonScript* maybeIonScriptToInvalidate(const TypeZone& zone) const;
|
||||
|
||||
inline bool shouldSweep();
|
||||
inline bool shouldSweep(const TypeZone& zone);
|
||||
|
||||
bool operator==(const RecompileInfo& other) const {
|
||||
return script_== other.script_ && id_ == other.id_;
|
||||
|
@ -1336,6 +1340,9 @@ class TypeZone
|
|||
static const size_t TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 8 * 1024;
|
||||
ZoneGroupData<LifoAlloc> typeLifoAlloc_;
|
||||
|
||||
// Under CodeGenerator::link, the id of the current compilation.
|
||||
ZoneGroupData<mozilla::Maybe<IonCompilationId>> currentCompilationId_;
|
||||
|
||||
TypeZone(const TypeZone&) = delete;
|
||||
void operator=(const TypeZone&) = delete;
|
||||
|
||||
|
@ -1384,6 +1391,13 @@ class TypeZone
|
|||
MOZ_RELEASE_ASSERT(sweepingTypes != sweeping);
|
||||
sweepingTypes = sweeping;
|
||||
}
|
||||
|
||||
mozilla::Maybe<IonCompilationId> currentCompilationId() const {
|
||||
return currentCompilationId_.ref();
|
||||
}
|
||||
mozilla::Maybe<IonCompilationId>& currentCompilationIdRef() {
|
||||
return currentCompilationId_.ref();
|
||||
}
|
||||
};
|
||||
|
||||
enum SpewChannel {
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.mozilla.gecko.util.ThreadUtils;
|
|||
import org.mozilla.gecko.util.ViewUtil;
|
||||
import org.mozilla.gecko.widget.ActionModePresenter;
|
||||
import org.mozilla.gecko.widget.AnchoredPopup;
|
||||
import org.mozilla.geckoview.GeckoRuntime;
|
||||
import org.mozilla.geckoview.GeckoSession;
|
||||
import org.mozilla.geckoview.GeckoSessionSettings;
|
||||
import org.mozilla.geckoview.GeckoView;
|
||||
|
@ -1079,17 +1080,17 @@ public abstract class GeckoApp extends GeckoActivity
|
|||
mLayerView = (GeckoView) findViewById(R.id.layer_view);
|
||||
|
||||
final GeckoSession session = new GeckoSession();
|
||||
session.getSettings().setString(GeckoSessionSettings.CHROME_URI,
|
||||
"chrome://browser/content/browser.xul");
|
||||
session.setContentDelegate(this);
|
||||
|
||||
// If the view already has a session, we need to ensure it is closed.
|
||||
if (mLayerView.getSession() != null) {
|
||||
mLayerView.getSession().close();
|
||||
}
|
||||
mLayerView.setSession(session);
|
||||
mLayerView.setSession(session, GeckoRuntime.getDefault(this));
|
||||
mLayerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
|
||||
|
||||
session.getSettings().setString(GeckoSessionSettings.CHROME_URI,
|
||||
"chrome://browser/content/browser.xul");
|
||||
session.setContentDelegate(this);
|
||||
|
||||
GeckoAccessibility.setDelegate(mLayerView);
|
||||
|
||||
getAppEventDispatcher().registerGeckoThreadListener(this,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.ScreenManagerHelper;
|
||||
import org.mozilla.geckoview.GeckoRuntime;
|
||||
import org.mozilla.geckoview.GeckoSession;
|
||||
import org.mozilla.geckoview.GeckoSessionSettings;
|
||||
import org.mozilla.geckoview.GeckoView;
|
||||
|
@ -124,15 +125,14 @@ class VirtualPresentation extends CastPresentation {
|
|||
* resources.
|
||||
*/
|
||||
|
||||
// Create new GeckoView
|
||||
view = new GeckoView(getContext());
|
||||
|
||||
final GeckoSession session = new GeckoSession();
|
||||
session.getSettings().setString(GeckoSessionSettings.CHROME_URI,
|
||||
PRESENTATION_VIEW_URI + "#" + deviceId);
|
||||
session.getSettings().setInt(GeckoSessionSettings.SCREEN_ID, screenId);
|
||||
|
||||
view.setSession(session);
|
||||
// Create new GeckoView
|
||||
view = new GeckoView(getContext());
|
||||
view.setSession(session, GeckoRuntime.getDefault(getContext()));
|
||||
view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
|
||||
LayoutParams.MATCH_PARENT));
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ import org.mozilla.gecko.util.PackageUtil;
|
|||
import org.mozilla.gecko.webapps.WebApps;
|
||||
import org.mozilla.gecko.widget.ActionModePresenter;
|
||||
import org.mozilla.gecko.widget.GeckoPopupMenu;
|
||||
import org.mozilla.geckoview.GeckoRuntime;
|
||||
import org.mozilla.geckoview.GeckoSession;
|
||||
import org.mozilla.geckoview.GeckoSessionSettings;
|
||||
import org.mozilla.geckoview.GeckoView;
|
||||
|
@ -125,13 +126,19 @@ public class CustomTabsActivity extends AppCompatActivity
|
|||
|
||||
GeckoAccessibility.setDelegate(mGeckoView);
|
||||
|
||||
mGeckoSession = new GeckoSession();
|
||||
mGeckoView.setSession(mGeckoSession);
|
||||
|
||||
final GeckoSessionSettings settings = new GeckoSessionSettings();
|
||||
settings.setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, false);
|
||||
settings.setBoolean(
|
||||
GeckoSessionSettings.USE_REMOTE_DEBUGGER,
|
||||
GeckoSharedPrefs.forApp(this).getBoolean(
|
||||
GeckoPreferences.PREFS_DEVTOOLS_REMOTE_USB_ENABLED, false));
|
||||
mGeckoSession = new GeckoSession(settings);
|
||||
mGeckoSession.setNavigationDelegate(this);
|
||||
mGeckoSession.setProgressDelegate(this);
|
||||
mGeckoSession.setContentDelegate(this);
|
||||
|
||||
mGeckoView.setSession(mGeckoSession, GeckoRuntime.getDefault(this));
|
||||
|
||||
mPromptService = new PromptService(this, mGeckoView.getEventDispatcher());
|
||||
mDoorHangerPopup = new DoorHangerPopup(this, mGeckoView.getEventDispatcher());
|
||||
|
||||
|
@ -141,13 +148,6 @@ public class CustomTabsActivity extends AppCompatActivity
|
|||
mTextSelection = TextSelection.Factory.create(mGeckoView, this);
|
||||
mTextSelection.create();
|
||||
|
||||
final GeckoSessionSettings settings = mGeckoView.getSettings();
|
||||
settings.setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, false);
|
||||
settings.setBoolean(
|
||||
GeckoSessionSettings.USE_REMOTE_DEBUGGER,
|
||||
GeckoSharedPrefs.forApp(this).getBoolean(
|
||||
GeckoPreferences.PREFS_DEVTOOLS_REMOTE_USB_ENABLED, false));
|
||||
|
||||
if (intent != null && !TextUtils.isEmpty(intent.getDataString())) {
|
||||
mGeckoSession.loadUri(intent.getDataString());
|
||||
} else {
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.mozilla.gecko.text.TextSelection;
|
|||
import org.mozilla.gecko.util.ActivityUtils;
|
||||
import org.mozilla.gecko.util.ColorUtil;
|
||||
import org.mozilla.gecko.widget.ActionModePresenter;
|
||||
import org.mozilla.geckoview.GeckoRuntime;
|
||||
import org.mozilla.geckoview.GeckoSession;
|
||||
import org.mozilla.geckoview.GeckoSessionSettings;
|
||||
import org.mozilla.geckoview.GeckoView;
|
||||
|
@ -91,8 +92,14 @@ public class WebAppActivity extends AppCompatActivity
|
|||
setContentView(R.layout.webapp_activity);
|
||||
mGeckoView = (GeckoView) findViewById(R.id.pwa_gecko_view);
|
||||
|
||||
mGeckoSession = new GeckoSession();
|
||||
mGeckoView.setSession(mGeckoSession);
|
||||
final GeckoSessionSettings settings = new GeckoSessionSettings();
|
||||
settings.setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, false);
|
||||
settings.setBoolean(
|
||||
GeckoSessionSettings.USE_REMOTE_DEBUGGER,
|
||||
GeckoSharedPrefs.forApp(this).getBoolean(
|
||||
GeckoPreferences.PREFS_DEVTOOLS_REMOTE_USB_ENABLED, false));
|
||||
mGeckoSession = new GeckoSession(settings);
|
||||
mGeckoView.setSession(mGeckoSession, GeckoRuntime.getDefault(this));
|
||||
|
||||
mGeckoSession.setNavigationDelegate(this);
|
||||
mGeckoSession.setContentDelegate(this);
|
||||
|
@ -147,13 +154,6 @@ public class WebAppActivity extends AppCompatActivity
|
|||
mTextSelection = TextSelection.Factory.create(mGeckoView, this);
|
||||
mTextSelection.create();
|
||||
|
||||
final GeckoSessionSettings settings = mGeckoView.getSettings();
|
||||
settings.setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, false);
|
||||
settings.setBoolean(
|
||||
GeckoSessionSettings.USE_REMOTE_DEBUGGER,
|
||||
GeckoSharedPrefs.forApp(this).getBoolean(
|
||||
GeckoPreferences.PREFS_DEVTOOLS_REMOTE_USB_ENABLED, false));
|
||||
|
||||
try {
|
||||
mManifest = WebAppManifest.fromFile(getIntent().getStringExtra(MANIFEST_URL),
|
||||
getIntent().getStringExtra(MANIFEST_PATH));
|
||||
|
@ -320,7 +320,7 @@ public class WebAppActivity extends AppCompatActivity
|
|||
break;
|
||||
}
|
||||
|
||||
mGeckoView.getSettings().setInt(GeckoSessionSettings.DISPLAY_MODE, mode);
|
||||
mGeckoSession.getSettings().setInt(GeckoSessionSettings.DISPLAY_MODE, mode);
|
||||
}
|
||||
|
||||
@Override // GeckoSession.NavigationDelegate
|
||||
|
|
|
@ -735,7 +735,8 @@ class GeckoSessionTestRuleTest : BaseSessionTest(noErrorCollector = true) {
|
|||
}
|
||||
|
||||
@Test fun wrapSession() {
|
||||
val session = sessionRule.wrapSession(GeckoSession(sessionRule.session.settings))
|
||||
val session = sessionRule.wrapSession(
|
||||
GeckoSession(sessionRule.session.settings))
|
||||
sessionRule.openSession(session)
|
||||
session.reload()
|
||||
session.waitForPageStop()
|
||||
|
|
|
@ -356,7 +356,7 @@ class NavigationDelegateTest : BaseSessionTest() {
|
|||
sessionRule.delegateDuringNextWait(object : Callbacks.NavigationDelegate {
|
||||
@AssertCalled(count = 1)
|
||||
override fun onNewSession(session: GeckoSession, uri: String, response: GeckoSession.Response<GeckoSession>) {
|
||||
var newSession = GeckoSession(session.settings)
|
||||
val newSession = sessionRule.createClosedSession(session.settings)
|
||||
newSession.open()
|
||||
response.respond(newSession)
|
||||
}
|
||||
|
|
|
@ -60,7 +60,8 @@ class ProgressDelegateTest : BaseSessionTest() {
|
|||
sessionRule.forCallbacksDuringWait(object : Callbacks.ProgressDelegate, Callbacks.NavigationDelegate {
|
||||
@AssertCalled(count = 2)
|
||||
override fun onLoadRequest(session: GeckoSession, uri: String,
|
||||
where: Int, response: GeckoSession.Response<Boolean>) {
|
||||
where: Int,
|
||||
response: GeckoSession.Response<Boolean>) {
|
||||
if (sessionRule.currentCall.counter == 1) {
|
||||
assertThat("URI should be " + testUri, uri, equalTo(testUri));
|
||||
} else {
|
||||
|
|
|
@ -19,14 +19,6 @@ import org.junit.runner.RunWith
|
|||
@MediumTest
|
||||
class SessionLifecycleTest : BaseSessionTest() {
|
||||
|
||||
@Test fun open_allowNullContext() {
|
||||
sessionRule.session.close()
|
||||
|
||||
sessionRule.session.open(null)
|
||||
sessionRule.session.reload()
|
||||
sessionRule.session.waitForPageStop()
|
||||
}
|
||||
|
||||
@Test fun open_interleaved() {
|
||||
val session1 = sessionRule.createOpenSession()
|
||||
val session2 = sessionRule.createOpenSession()
|
||||
|
|
|
@ -8,6 +8,8 @@ package org.mozilla.geckoview.test;
|
|||
import org.mozilla.geckoview.GeckoSession;
|
||||
import org.mozilla.geckoview.GeckoSessionSettings;
|
||||
import org.mozilla.geckoview.GeckoView;
|
||||
import org.mozilla.geckoview.GeckoRuntime;
|
||||
import org.mozilla.geckoview.GeckoRuntimeSettings;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
|
@ -17,6 +19,8 @@ import android.os.Bundle;
|
|||
public class TestRunnerActivity extends Activity {
|
||||
private static final String LOGTAG = "TestRunnerActivity";
|
||||
|
||||
static GeckoRuntime sRuntime;
|
||||
|
||||
GeckoSession mSession;
|
||||
GeckoView mView;
|
||||
|
||||
|
@ -37,8 +41,8 @@ public class TestRunnerActivity extends Activity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onLoadRequest(GeckoSession session, String uri,
|
||||
int target, GeckoSession.Response<Boolean> response) {
|
||||
public void onLoadRequest(GeckoSession session, String uri, int target,
|
||||
GeckoSession.Response<Boolean> response) {
|
||||
// Allow Gecko to load all URIs
|
||||
response.respond(false);
|
||||
}
|
||||
|
@ -103,13 +107,16 @@ public class TestRunnerActivity extends Activity {
|
|||
super.onCreate(savedInstanceState);
|
||||
|
||||
final Intent intent = getIntent();
|
||||
GeckoSession.preload(this, new String[] { "-purgecaches" },
|
||||
intent.getExtras(), false /* no multiprocess, see below */);
|
||||
|
||||
// We can't use e10s because we get deadlocked when quickly creating and
|
||||
// destroying sessions. Bug 1348361.
|
||||
if (sRuntime == null) {
|
||||
final GeckoRuntimeSettings geckoSettings = new GeckoRuntimeSettings();
|
||||
geckoSettings.setArguments(new String[] { "-purgecaches" });
|
||||
geckoSettings.setExtras(intent.getExtras());
|
||||
sRuntime = GeckoRuntime.create(this, geckoSettings);
|
||||
}
|
||||
|
||||
mSession = createSession();
|
||||
mSession.open(this);
|
||||
mSession.open(sRuntime);
|
||||
|
||||
// If we were passed a URI in the Intent, open it
|
||||
final Uri uri = intent.getData();
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
package org.mozilla.geckoview.test.rule;
|
||||
|
||||
import org.mozilla.gecko.gfx.GeckoDisplay;
|
||||
import org.mozilla.geckoview.GeckoRuntime;
|
||||
import org.mozilla.geckoview.GeckoRuntimeSettings;
|
||||
import org.mozilla.geckoview.GeckoSession;
|
||||
import org.mozilla.geckoview.GeckoSessionSettings;
|
||||
import org.mozilla.geckoview.test.util.Callbacks;
|
||||
|
@ -506,6 +508,7 @@ public class GeckoSessionTestRule extends UiThreadTestRule {
|
|||
}
|
||||
|
||||
private static final List<Class<?>> CALLBACK_CLASSES = Arrays.asList(getCallbackClasses());
|
||||
private static GeckoRuntime sRuntime;
|
||||
|
||||
public final Environment env = new Environment();
|
||||
|
||||
|
@ -611,6 +614,15 @@ public class GeckoSessionTestRule extends UiThreadTestRule {
|
|||
return mMainSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the runtime set up for the current test.
|
||||
*
|
||||
* @return GeckoRuntime object.
|
||||
*/
|
||||
public @NonNull GeckoRuntime getRuntime() {
|
||||
return sRuntime;
|
||||
}
|
||||
|
||||
protected static Method getCallbackSetter(final @NonNull Class<?> cls)
|
||||
throws NoSuchMethodException {
|
||||
return GeckoSession.class.getMethod("set" + cls.getSimpleName(), cls);
|
||||
|
@ -714,7 +726,14 @@ public class GeckoSessionTestRule extends UiThreadTestRule {
|
|||
mCallbackProxy = Proxy.newProxyInstance(GeckoSession.class.getClassLoader(),
|
||||
classes, recorder);
|
||||
|
||||
GeckoSession.preload(InstrumentationRegistry.getTargetContext(), new String[] { "-purgecaches" }, null, false);
|
||||
if (sRuntime == null) {
|
||||
final GeckoRuntimeSettings geckoSettings = new GeckoRuntimeSettings();
|
||||
geckoSettings.setArguments(new String[] { "-purgecaches" });
|
||||
sRuntime = GeckoRuntime.create(
|
||||
InstrumentationRegistry.getTargetContext(),
|
||||
geckoSettings);
|
||||
}
|
||||
|
||||
mMainSession = new GeckoSession(settings);
|
||||
prepareSession(mMainSession);
|
||||
|
||||
|
@ -753,7 +772,7 @@ public class GeckoSessionTestRule extends UiThreadTestRule {
|
|||
loopUntilIdle(/* timeout */ 0);
|
||||
}
|
||||
|
||||
session.open(mInstrumentation.getTargetContext());
|
||||
session.open(sRuntime);
|
||||
|
||||
if (!e10s) {
|
||||
return;
|
||||
|
|
|
@ -44,7 +44,8 @@ class Callbacks private constructor() {
|
|||
override fun onCanGoForward(session: GeckoSession, canGoForward: Boolean) {
|
||||
}
|
||||
|
||||
override fun onLoadRequest(session: GeckoSession, uri: String, where: Int, response: GeckoSession.Response<Boolean>) {
|
||||
override fun onLoadRequest(session: GeckoSession, uri: String, where: Int,
|
||||
response: GeckoSession.Response<Boolean>) {
|
||||
response.respond(false)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* vim: ts=4 sw=4 expandtab:
|
||||
* 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/. */
|
||||
|
||||
package org.mozilla.geckoview;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||
import org.mozilla.gecko.EventDispatcher;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.GeckoThread;
|
||||
import org.mozilla.gecko.util.BundleEventListener;
|
||||
import org.mozilla.gecko.util.EventCallback;
|
||||
import org.mozilla.gecko.util.GeckoBundle;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
public final class GeckoRuntime implements Parcelable {
|
||||
private static final String LOGTAG = "GeckoRuntime";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static GeckoRuntime sDefaultRuntime;
|
||||
|
||||
/**
|
||||
* Get the default runtime for the given context.
|
||||
* This will create and initialize the runtime with the default settings.
|
||||
*
|
||||
* Note: Only use this for session-less apps.
|
||||
* For regular apps, use create() and createSession() instead.
|
||||
*
|
||||
* @return The (static) default runtime for the context.
|
||||
*/
|
||||
public static synchronized @NonNull GeckoRuntime getDefault(
|
||||
final @NonNull Context context) {
|
||||
Log.d(LOGTAG, "getDefault");
|
||||
if (sDefaultRuntime == null) {
|
||||
sDefaultRuntime = new GeckoRuntime();
|
||||
sDefaultRuntime.attachTo(context);
|
||||
sDefaultRuntime.init(new GeckoRuntimeSettings());
|
||||
}
|
||||
|
||||
return sDefaultRuntime;
|
||||
}
|
||||
|
||||
private GeckoRuntimeSettings mSettings;
|
||||
|
||||
/**
|
||||
* Attach the runtime to the given context.
|
||||
*
|
||||
* @param context The new context to attach to.
|
||||
*/
|
||||
public void attachTo(final @NonNull Context context) {
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "attachTo " + context.getApplicationContext());
|
||||
}
|
||||
final Context appContext = context.getApplicationContext();
|
||||
if (!appContext.equals(GeckoAppShell.getApplicationContext())) {
|
||||
GeckoAppShell.setApplicationContext(appContext);
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ boolean init(final @NonNull GeckoRuntimeSettings settings) {
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "init");
|
||||
}
|
||||
final int flags = settings.getUseContentProcessHint()
|
||||
? GeckoThread.FLAG_PRELOAD_CHILD
|
||||
: 0;
|
||||
if (GeckoThread.initMainProcess(/* profile */ null,
|
||||
settings.getArguments(),
|
||||
settings.getExtras(),
|
||||
flags)) {
|
||||
if (!GeckoThread.launch()) {
|
||||
Log.d(LOGTAG, "init failed (GeckoThread already launched)");
|
||||
return false;
|
||||
}
|
||||
mSettings = settings;
|
||||
return true;
|
||||
}
|
||||
Log.d(LOGTAG, "init failed (could not initiate GeckoThread)");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new runtime with default settings and attach it to the given
|
||||
* context.
|
||||
*
|
||||
* Create will throw if there is already an active Gecko instance running,
|
||||
* to prevent that, bind the runtime to the process lifetime instead of the
|
||||
* activity lifetime.
|
||||
*
|
||||
* @param context The context of the runtime.
|
||||
* @return An initialized runtime.
|
||||
*/
|
||||
public static @NonNull GeckoRuntime create(final @NonNull Context context) {
|
||||
return create(context, new GeckoRuntimeSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new runtime with the given settings and attach it to the given
|
||||
* context.
|
||||
*
|
||||
* Create will throw if there is already an active Gecko instance running,
|
||||
* to prevent that, bind the runtime to the process lifetime instead of the
|
||||
* activity lifetime.
|
||||
*
|
||||
* @param context The context of the runtime.
|
||||
* @param settings The settings for the runtime.
|
||||
* @return An initialized runtime.
|
||||
*/
|
||||
public static @NonNull GeckoRuntime create(
|
||||
final @NonNull Context context,
|
||||
final @NonNull GeckoRuntimeSettings settings) {
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "create " + context);
|
||||
}
|
||||
|
||||
final GeckoRuntime runtime = new GeckoRuntime();
|
||||
runtime.attachTo(context);
|
||||
|
||||
if (!runtime.init(settings)) {
|
||||
throw new IllegalStateException("Failed to initialize GeckoRuntime");
|
||||
}
|
||||
|
||||
return runtime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the runtime. This will invalidate all attached sessions.
|
||||
*/
|
||||
public void shutdown() {
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "shutdown");
|
||||
}
|
||||
|
||||
GeckoThread.forceQuit();
|
||||
}
|
||||
|
||||
@Override // Parcelable
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override // Parcelable
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeParcelable(mSettings, flags);
|
||||
}
|
||||
|
||||
// AIDL code may call readFromParcel even though it's not part of Parcelable.
|
||||
public void readFromParcel(final Parcel source) {
|
||||
mSettings = source.readParcelable(getClass().getClassLoader());
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<GeckoRuntime> CREATOR
|
||||
= new Parcelable.Creator<GeckoRuntime>() {
|
||||
@Override
|
||||
public GeckoRuntime createFromParcel(final Parcel in) {
|
||||
final GeckoRuntime runtime = new GeckoRuntime();
|
||||
runtime.readFromParcel(in);
|
||||
return runtime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeckoRuntime[] newArray(final int size) {
|
||||
return new GeckoRuntime[size];
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* vim: ts=4 sw=4 expandtab:
|
||||
* 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/. */
|
||||
|
||||
package org.mozilla.geckoview;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
public final class GeckoRuntimeSettings implements Parcelable {
|
||||
private boolean mUseContentProcess;
|
||||
private String[] mArgs;
|
||||
private Bundle mExtras;
|
||||
|
||||
/**
|
||||
* Initialize default settings.
|
||||
*/
|
||||
public GeckoRuntimeSettings() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/* package */ GeckoRuntimeSettings(final @Nullable GeckoRuntimeSettings settings) {
|
||||
if (settings != null) {
|
||||
mUseContentProcess = settings.mUseContentProcess;
|
||||
mArgs = settings.mArgs.clone();
|
||||
mExtras = new Bundle(settings.mExtras);
|
||||
} else {
|
||||
mArgs = new String[0];
|
||||
mExtras = new Bundle();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content process hint flag.
|
||||
*
|
||||
* @return The content process hint flag.
|
||||
*/
|
||||
public boolean getUseContentProcessHint() {
|
||||
return mUseContentProcess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the custom Gecko process arguments.
|
||||
*
|
||||
* @return The Gecko process arguments.
|
||||
*/
|
||||
public String[] getArguments() {
|
||||
return mArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the custom Gecko intent extras.
|
||||
*
|
||||
* @return The Gecko intent extras.
|
||||
*/
|
||||
public Bundle getExtras() {
|
||||
return mExtras;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the content process hint flag.
|
||||
*
|
||||
* @param use If true, this will reload the content process for future use.
|
||||
*/
|
||||
public void setUseContentProcessHint(boolean use) {
|
||||
mUseContentProcess = use;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the custom Gecko process arguments.
|
||||
*
|
||||
* @param args The Gecko process arguments.
|
||||
*/
|
||||
public void setArguments(final @NonNull String[] args) {
|
||||
mArgs = args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the custom Gecko intent extras.
|
||||
*
|
||||
* @param extras The Gecko intent extras.
|
||||
*/
|
||||
public void setExtras(final @NonNull Bundle extras) {
|
||||
mExtras = extras;
|
||||
}
|
||||
|
||||
@Override // Parcelable
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override // Parcelable
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeByte((byte) (mUseContentProcess ? 1 : 0));
|
||||
out.writeStringArray(mArgs);
|
||||
mExtras.writeToParcel(out, flags);
|
||||
}
|
||||
|
||||
// AIDL code may call readFromParcel even though it's not part of Parcelable.
|
||||
public void readFromParcel(final Parcel source) {
|
||||
mUseContentProcess = source.readByte() == 1;
|
||||
mArgs = source.createStringArray();
|
||||
mExtras.readFromParcel(source);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<GeckoRuntimeSettings> CREATOR
|
||||
= new Parcelable.Creator<GeckoRuntimeSettings>() {
|
||||
@Override
|
||||
public GeckoRuntimeSettings createFromParcel(final Parcel in) {
|
||||
final GeckoRuntimeSettings settings = new GeckoRuntimeSettings();
|
||||
settings.readFromParcel(in);
|
||||
return settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GeckoRuntimeSettings[] newArray(final int size) {
|
||||
return new GeckoRuntimeSettings[size];
|
||||
}
|
||||
};
|
||||
}
|
|
@ -200,8 +200,12 @@ public class GeckoSession extends LayerSession
|
|||
throw new IllegalArgumentException("Must use an unopened GeckoSession instance");
|
||||
}
|
||||
|
||||
session.open(null);
|
||||
callback.sendSuccess(session.getId());
|
||||
if (GeckoSession.this.mWindow == null) {
|
||||
callback.sendError("Session is not attached to a window");
|
||||
} else {
|
||||
session.open(GeckoSession.this.mWindow.runtime);
|
||||
callback.sendSuccess(session.getId());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -467,10 +471,13 @@ public class GeckoSession extends LayerSession
|
|||
private final Listener mListener = new Listener();
|
||||
|
||||
/* package */ static final class Window extends JNIObject implements IInterface {
|
||||
public final GeckoRuntime runtime;
|
||||
private NativeQueue mNativeQueue;
|
||||
private Binder mBinder;
|
||||
|
||||
public Window(final NativeQueue nativeQueue) {
|
||||
public Window(final @NonNull GeckoRuntime runtime,
|
||||
final @NonNull NativeQueue nativeQueue) {
|
||||
this.runtime = runtime;
|
||||
mNativeQueue = nativeQueue;
|
||||
}
|
||||
|
||||
|
@ -618,7 +625,7 @@ public class GeckoSession extends LayerSession
|
|||
this(null);
|
||||
}
|
||||
|
||||
public GeckoSession(final GeckoSessionSettings settings) {
|
||||
public GeckoSession(final @Nullable GeckoSessionSettings settings) {
|
||||
mSettings = new GeckoSessionSettings(settings, this);
|
||||
mListener.registerListeners();
|
||||
|
||||
|
@ -627,7 +634,15 @@ public class GeckoSession extends LayerSession
|
|||
}
|
||||
}
|
||||
|
||||
private void transferFrom(final Window window, final GeckoSessionSettings settings,
|
||||
/* package */ @Nullable GeckoRuntime getRuntime() {
|
||||
if (mWindow == null) {
|
||||
return null;
|
||||
}
|
||||
return mWindow.runtime;
|
||||
}
|
||||
|
||||
private void transferFrom(final Window window,
|
||||
final GeckoSessionSettings settings,
|
||||
final String id) {
|
||||
if (isOpen()) {
|
||||
throw new IllegalStateException("Session is open");
|
||||
|
@ -701,43 +716,6 @@ public class GeckoSession extends LayerSession
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Preload GeckoSession by starting Gecko in the background, if Gecko is not already running.
|
||||
*
|
||||
* @param context Activity or Application Context for starting GeckoSession.
|
||||
*/
|
||||
public static void preload(final @NonNull Context context) {
|
||||
preload(context, /* geckoArgs */ null,
|
||||
/* extras */ null, /* multiprocess */ false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Preload GeckoSession by starting Gecko with the specified arguments in the background,
|
||||
* if Gecko is not already running.
|
||||
*
|
||||
* @param context Activity or Application Context for starting GeckoSession.
|
||||
* @param geckoArgs Arguments to be passed to Gecko, if Gecko is not already running.
|
||||
* @param multiprocess True if child process in multiprocess mode should be preloaded.
|
||||
*/
|
||||
public static void preload(final @NonNull Context context,
|
||||
final @Nullable String[] geckoArgs,
|
||||
final @Nullable Bundle extras,
|
||||
final boolean multiprocess) {
|
||||
final Context appContext = context.getApplicationContext();
|
||||
if (!appContext.equals(GeckoAppShell.getApplicationContext())) {
|
||||
GeckoAppShell.setApplicationContext(appContext);
|
||||
}
|
||||
|
||||
if (GeckoThread.isLaunched()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int flags = multiprocess ? GeckoThread.FLAG_PRELOAD_CHILD : 0;
|
||||
if (GeckoThread.initMainProcess(/* profile */ null, geckoArgs, extras, flags)) {
|
||||
GeckoThread.launch();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return mWindow != null;
|
||||
}
|
||||
|
@ -757,30 +735,24 @@ public class GeckoSession extends LayerSession
|
|||
*
|
||||
* Call this when you are ready to use a GeckoSession instance.
|
||||
*
|
||||
* @param appContext An application context
|
||||
* @param runtime The Gecko runtime to attach this session to.
|
||||
*/
|
||||
public void open(final @Nullable Context appContext) {
|
||||
public void open(final @NonNull GeckoRuntime runtime) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
if (isOpen()) {
|
||||
throw new IllegalStateException("Session is open");
|
||||
}
|
||||
|
||||
if (appContext != null) {
|
||||
final boolean multiprocess =
|
||||
mSettings.getBoolean(GeckoSessionSettings.USE_MULTIPROCESS);
|
||||
preload(appContext, /* geckoArgs */ null, /* extras */ null, multiprocess);
|
||||
}
|
||||
|
||||
openWindow();
|
||||
openWindow(runtime);
|
||||
}
|
||||
|
||||
private void openWindow() {
|
||||
private void openWindow(final @NonNull GeckoRuntime runtime) {
|
||||
final String chromeUri = mSettings.getString(GeckoSessionSettings.CHROME_URI);
|
||||
final int screenId = mSettings.getInt(GeckoSessionSettings.SCREEN_ID);
|
||||
final boolean isPrivate = mSettings.getBoolean(GeckoSessionSettings.USE_PRIVATE_MODE);
|
||||
|
||||
mWindow = new Window(mNativeQueue);
|
||||
mWindow = new Window(runtime, mNativeQueue);
|
||||
|
||||
onWindowChanged(WINDOW_OPEN, /* inProgress */ true);
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@ import android.os.Build;
|
|||
import android.os.Handler;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
|
@ -47,6 +49,7 @@ public class GeckoView extends FrameLayout {
|
|||
|
||||
protected final Display mDisplay = new Display();
|
||||
protected GeckoSession mSession;
|
||||
protected GeckoRuntime mRuntime;
|
||||
private boolean mStateSaved;
|
||||
|
||||
protected SurfaceView mSurfaceView;
|
||||
|
@ -217,15 +220,45 @@ public class GeckoView extends FrameLayout {
|
|||
return session;
|
||||
}
|
||||
|
||||
public void setSession(final GeckoSession session) {
|
||||
/**
|
||||
* Attach a session to this view. The session should be opened before
|
||||
* attaching.
|
||||
*
|
||||
* @param session The session to be attached.
|
||||
*/
|
||||
public void setSession(@NonNull final GeckoSession session) {
|
||||
if (!session.isOpen()) {
|
||||
throw new IllegalArgumentException("Session must be open before attaching");
|
||||
}
|
||||
|
||||
setSession(session, session.getRuntime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach a session to this view. The session should be opened before
|
||||
* attaching or a runtime needs to be provided for automatic opening.
|
||||
*
|
||||
* @param session The session to be attached.
|
||||
* @param runtime The runtime to be used for opening the session.
|
||||
*/
|
||||
public void setSession(@NonNull final GeckoSession session,
|
||||
@Nullable final GeckoRuntime runtime) {
|
||||
if (mSession != null && mSession.isOpen()) {
|
||||
throw new IllegalStateException("Current session is open");
|
||||
}
|
||||
|
||||
releaseSession();
|
||||
|
||||
mSession = session;
|
||||
if (mSession == null) {
|
||||
return;
|
||||
mRuntime = runtime;
|
||||
|
||||
if (session.isOpen()) {
|
||||
if (runtime != null && runtime != session.getRuntime()) {
|
||||
throw new IllegalArgumentException("Session was opened with non-matching runtime");
|
||||
}
|
||||
mRuntime = session.getRuntime();
|
||||
} else if (runtime == null) {
|
||||
throw new IllegalArgumentException("Session must be open before attaching");
|
||||
}
|
||||
|
||||
mDisplay.acquire(session.acquireDisplay());
|
||||
|
@ -272,10 +305,6 @@ public class GeckoView extends FrameLayout {
|
|||
return mSession.getEventDispatcher();
|
||||
}
|
||||
|
||||
public GeckoSessionSettings getSettings() {
|
||||
return mSession.getSettings();
|
||||
}
|
||||
|
||||
public PanZoomController getPanZoomController() {
|
||||
return mSession.getPanZoomController();
|
||||
}
|
||||
|
@ -287,11 +316,11 @@ public class GeckoView extends FrameLayout {
|
|||
@Override
|
||||
public void onAttachedToWindow() {
|
||||
if (mSession == null) {
|
||||
setSession(new GeckoSession());
|
||||
setSession(new GeckoSession(), GeckoRuntime.getDefault(getContext()));
|
||||
}
|
||||
|
||||
if (!mSession.isOpen()) {
|
||||
mSession.open(getContext().getApplicationContext());
|
||||
mSession.open(mRuntime);
|
||||
}
|
||||
|
||||
mSession.getTextInput().setView(this);
|
||||
|
@ -346,10 +375,11 @@ public class GeckoView extends FrameLayout {
|
|||
final SavedState ss = (SavedState) state;
|
||||
super.onRestoreInstanceState(ss.getSuperState());
|
||||
|
||||
if (mSession == null) {
|
||||
setSession(ss.session);
|
||||
if (mSession == null && ss.session != null) {
|
||||
setSession(ss.session, ss.session.getRuntime());
|
||||
} else if (ss.session != null) {
|
||||
mSession.transferFrom(ss.session);
|
||||
mRuntime = ss.session.getRuntime();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,12 +17,13 @@ import android.view.WindowManager;
|
|||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.mozilla.gecko.GeckoThread;
|
||||
import org.mozilla.geckoview.GeckoSession;
|
||||
import org.mozilla.geckoview.GeckoSessionSettings;
|
||||
import org.mozilla.geckoview.GeckoSession.Response;
|
||||
import org.mozilla.geckoview.GeckoSession.TrackingProtectionDelegate;
|
||||
import org.mozilla.geckoview.GeckoView;
|
||||
import org.mozilla.geckoview.GeckoRuntime;
|
||||
import org.mozilla.geckoview.GeckoRuntimeSettings;
|
||||
|
||||
public class GeckoViewActivity extends Activity {
|
||||
private static final String LOGTAG = "GeckoViewActivity";
|
||||
|
@ -36,6 +37,7 @@ public class GeckoViewActivity extends Activity {
|
|||
/* package */ static final int REQUEST_FILE_PICKER = 1;
|
||||
private static final int REQUEST_PERMISSIONS = 2;
|
||||
|
||||
private static GeckoRuntime sGeckoRuntime;
|
||||
private GeckoSession mGeckoSession;
|
||||
private GeckoView mGeckoView;
|
||||
|
||||
|
@ -45,24 +47,32 @@ public class GeckoViewActivity extends Activity {
|
|||
Log.i(LOGTAG, "zerdatime " + SystemClock.elapsedRealtime() +
|
||||
" - application start");
|
||||
|
||||
final String[] geckoArgs;
|
||||
setContentView(R.layout.geckoview_activity);
|
||||
mGeckoView = (GeckoView) findViewById(R.id.gecko_view);
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
// In debug builds, we want to load JavaScript resources fresh with each build.
|
||||
geckoArgs = new String[] { "-purgecaches" };
|
||||
} else {
|
||||
geckoArgs = null;
|
||||
final boolean useMultiprocess =
|
||||
getIntent().getBooleanExtra(USE_MULTIPROCESS_EXTRA, true);
|
||||
|
||||
if (sGeckoRuntime == null) {
|
||||
final GeckoRuntimeSettings geckoSettings = new GeckoRuntimeSettings();
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
// In debug builds, we want to load JavaScript resources fresh with
|
||||
// each build.
|
||||
geckoSettings.setArguments(new String[] { "-purgecaches" });
|
||||
}
|
||||
|
||||
geckoSettings.setUseContentProcessHint(useMultiprocess);
|
||||
geckoSettings.setExtras(getIntent().getExtras());
|
||||
sGeckoRuntime = GeckoRuntime.create(this, geckoSettings);
|
||||
}
|
||||
|
||||
final boolean useMultiprocess = getIntent().getBooleanExtra(USE_MULTIPROCESS_EXTRA,
|
||||
true);
|
||||
GeckoSession.preload(this, geckoArgs, getIntent().getExtras(), useMultiprocess);
|
||||
final GeckoSessionSettings sessionSettings = new GeckoSessionSettings();
|
||||
sessionSettings.setBoolean(GeckoSessionSettings.USE_MULTIPROCESS,
|
||||
useMultiprocess);
|
||||
mGeckoSession = new GeckoSession(sessionSettings);
|
||||
|
||||
setContentView(R.layout.geckoview_activity);
|
||||
|
||||
mGeckoView = (GeckoView) findViewById(R.id.gecko_view);
|
||||
mGeckoSession = new GeckoSession();
|
||||
mGeckoView.setSession(mGeckoSession);
|
||||
mGeckoView.setSession(mGeckoSession, sGeckoRuntime);
|
||||
|
||||
mGeckoSession.setContentDelegate(new MyGeckoViewContent());
|
||||
final MyTrackingProtection tp = new MyTrackingProtection();
|
||||
|
@ -78,9 +88,6 @@ public class GeckoViewActivity extends Activity {
|
|||
permission.androidPermissionRequestCode = REQUEST_PERMISSIONS;
|
||||
mGeckoSession.setPermissionDelegate(permission);
|
||||
|
||||
mGeckoSession.getSettings().setBoolean(GeckoSessionSettings.USE_MULTIPROCESS,
|
||||
useMultiprocess);
|
||||
|
||||
mGeckoSession.enableTrackingProtection(
|
||||
TrackingProtectionDelegate.CATEGORY_AD |
|
||||
TrackingProtectionDelegate.CATEGORY_ANALYTIC |
|
||||
|
@ -106,7 +113,9 @@ public class GeckoViewActivity extends Activity {
|
|||
|
||||
if (ACTION_SHUTDOWN.equals(intent.getAction())) {
|
||||
mKillProcessOnDestroy = true;
|
||||
GeckoThread.forceQuit();
|
||||
if (sGeckoRuntime != null) {
|
||||
sGeckoRuntime.shutdown();
|
||||
}
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
@ -125,7 +134,7 @@ public class GeckoViewActivity extends Activity {
|
|||
}
|
||||
|
||||
private void loadSettings(final Intent intent) {
|
||||
final GeckoSessionSettings settings = mGeckoView.getSettings();
|
||||
final GeckoSessionSettings settings = mGeckoSession.getSettings();
|
||||
settings.setBoolean(
|
||||
GeckoSessionSettings.USE_REMOTE_DEBUGGER,
|
||||
intent.getBooleanExtra(USE_REMOTE_DEBUGGER_EXTRA, false));
|
||||
|
|
|
@ -591,7 +591,6 @@ public:
|
|||
|
||||
private:
|
||||
friend struct IPC::ParamTraits<mozilla::TimeStamp>;
|
||||
friend void StartupTimelineRecordExternal(int, uint64_t);
|
||||
|
||||
MOZ_IMPLICIT TimeStamp(TimeStampValue aValue) : mValue(aValue) {}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ class TimeStampValue
|
|||
{
|
||||
friend struct IPC::ParamTraits<mozilla::TimeStampValue>;
|
||||
friend class TimeStamp;
|
||||
friend void StartupTimelineRecordExternal(int, uint64_t);
|
||||
|
||||
// Both QPC and GTC are kept in [mt] units.
|
||||
uint64_t mGTC;
|
||||
|
|
|
@ -1163,4 +1163,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
|
|||
|
||||
static const int32_t kUnknownId = -1;
|
||||
|
||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1531686800288000);
|
||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1531773471822000);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -8,7 +8,7 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
const PRTime gPreloadListExpirationTime = INT64_C(1534105987786000);
|
||||
const PRTime gPreloadListExpirationTime = INT64_C(1534192657699000);
|
||||
%%
|
||||
0-1.party, 1
|
||||
0.me.uk, 1
|
||||
|
@ -1250,6 +1250,7 @@ ac-town.com, 1
|
|||
ac0g.dyndns.org, 1
|
||||
academicexperts.us, 1
|
||||
academie-de-police.ch, 1
|
||||
academy4.net, 1
|
||||
academytv.com.au, 1
|
||||
acaeum.com, 1
|
||||
acampar.com.br, 1
|
||||
|
@ -1958,7 +1959,6 @@ alextsang.net, 1
|
|||
alexvdveen.nl, 1
|
||||
alexvetter.de, 1
|
||||
alexwardweb.com, 1
|
||||
alexyang.me, 1
|
||||
alfa-tech.su, 1
|
||||
alfaperfumes.com.br, 1
|
||||
alfaponny.se, 1
|
||||
|
@ -2241,6 +2241,7 @@ american.dating, 1
|
|||
americandistribuidora.com, 1
|
||||
americanfoundationbr.com, 1
|
||||
americanmediainstitute.com, 1
|
||||
americanoutlawjeepparts.com, 1
|
||||
americasbasementcontractor.com, 1
|
||||
americkykongres.cz, 1
|
||||
amerigroup.com, 1
|
||||
|
@ -3764,7 +3765,6 @@ baldur.cc, 1
|
|||
balenciaspa.com, 1
|
||||
balia.de, 1
|
||||
balicekzdravi.cz, 1
|
||||
balidesignshop.com.br, 1
|
||||
balikonos.cz, 1
|
||||
balinese.dating, 1
|
||||
balist.es, 1
|
||||
|
@ -5129,7 +5129,6 @@ bondskampeerder.nl, 1
|
|||
bondtofte.dk, 1
|
||||
bonesserver.com, 1
|
||||
bonfi.net, 1
|
||||
bonibuty.com, 1
|
||||
bonifacius.be, 1
|
||||
bonita.com.br, 1
|
||||
bonnant-associes.ch, 1
|
||||
|
@ -6345,7 +6344,6 @@ casinocashflow.ru, 1
|
|||
casinolistings.com, 1
|
||||
casinoonlinesicuri.com, 1
|
||||
casinoreal.com, 1
|
||||
casjay.cloud, 1
|
||||
casjay.com, 1
|
||||
casjay.info, 1
|
||||
casjaygames.com, 1
|
||||
|
@ -6520,6 +6518,7 @@ centos.pub, 1
|
|||
centos.tips, 1
|
||||
central4.me, 1
|
||||
centralbank.ae, 1
|
||||
centralcountiesservices.org, 1
|
||||
centralebigmat.eu, 1
|
||||
centralegedimat.eu, 1
|
||||
centralfor.me, 1
|
||||
|
@ -7673,6 +7672,7 @@ common.io, 1
|
|||
commoncode.com.au, 1
|
||||
commoncode.io, 1
|
||||
commoncore4kids.com, 1
|
||||
community-cupboard.org, 1
|
||||
communityblog.fedoraproject.org, 1
|
||||
communitycodeofconduct.com, 1
|
||||
communityflow.info, 1
|
||||
|
@ -7896,6 +7896,7 @@ coolpickz.com, 1
|
|||
coolprylar.se, 1
|
||||
coolrc.me, 1
|
||||
coolviewthermostat.com, 1
|
||||
coolvox.com, 1
|
||||
coopens.com, 1
|
||||
coor.fun, 1
|
||||
coore.jp, 1
|
||||
|
@ -7988,7 +7989,6 @@ cosni.co, 1
|
|||
cosplayer.com, 1
|
||||
cospol.ch, 1
|
||||
costa-rica-reisen.ch, 1
|
||||
costa-rica-reisen.de, 1
|
||||
costablancavoorjou.com, 1
|
||||
costcofinance.com, 1
|
||||
costinstefan.eu, 1
|
||||
|
@ -8787,6 +8787,7 @@ darkside.re, 1
|
|||
darktime.ru, 1
|
||||
darkwater.info, 1
|
||||
darkx.me, 1
|
||||
darlastudio66.com, 1
|
||||
darlo.co.uk, 0
|
||||
darom.jp, 1
|
||||
darookee.net, 1
|
||||
|
@ -10081,6 +10082,7 @@ doublestat.me, 1
|
|||
doubleup.com.au, 1
|
||||
doucheba.gs, 0
|
||||
dougferris.id.au, 1
|
||||
douglasstafford.com, 1
|
||||
doujin-domain.cz, 1
|
||||
doujin.nagoya, 1
|
||||
doujinshi.info, 1
|
||||
|
@ -10403,6 +10405,7 @@ dustygroove.com, 1
|
|||
dustyspokesbnb.ca, 1
|
||||
dutch.desi, 1
|
||||
dutch1.nl, 1
|
||||
dutchessuganda.com, 1
|
||||
dutchrank.nl, 1
|
||||
dutchwanderers.nl, 1
|
||||
dutchweballiance.nl, 1
|
||||
|
@ -10636,6 +10639,7 @@ echopaper.com, 1
|
|||
echosim.io, 1
|
||||
echosixmonkey.com, 1
|
||||
echosystem.fr, 1
|
||||
echoteam.gq, 1
|
||||
echoteen.com, 1
|
||||
echoworld.ch, 1
|
||||
ecirtam.net, 1
|
||||
|
@ -10652,6 +10656,7 @@ ecodedi.com, 1
|
|||
ecodigital.social, 1
|
||||
ecogen.com.au, 1
|
||||
ecogen.net.au, 1
|
||||
ecoheatcool.co.uk, 1
|
||||
ecohostingservices.uk, 1
|
||||
ecolala.my, 1
|
||||
ecole-attalens.ch, 1
|
||||
|
@ -10680,6 +10685,7 @@ ecovision.com.br, 1
|
|||
ecpannualmeeting.com, 1
|
||||
ecrandouble.ch, 1
|
||||
ectora.com, 1
|
||||
ecupcafe.com, 0
|
||||
ed.gs, 1
|
||||
ed4becky.net, 1
|
||||
edakoe.ru, 1
|
||||
|
@ -11338,30 +11344,7 @@ epmcentroitalia.it, 1
|
|||
epo32.ru, 1
|
||||
epoch.com, 1
|
||||
epolitiker.com, 1
|
||||
epos-distributor.co.uk, 1
|
||||
eposbirmingham.co.uk, 1
|
||||
eposbrighton.co.uk, 1
|
||||
eposbristol.co.uk, 1
|
||||
eposcardiff.co.uk, 1
|
||||
eposcloud.net, 1
|
||||
eposkent.co.uk, 1
|
||||
eposleeds.co.uk, 1
|
||||
eposleicester.co.uk, 1
|
||||
eposliverpool.co.uk, 1
|
||||
eposlondon.co.uk, 1
|
||||
eposmidlands.co.uk, 1
|
||||
eposnewport.co.uk, 1
|
||||
eposnottingham.co.uk, 1
|
||||
eposreading.co.uk, 1
|
||||
eposreview.co.uk, 1
|
||||
epossheffield.co.uk, 1
|
||||
epossurrey.co.uk, 1
|
||||
epossussex.co.uk, 1
|
||||
eposswansea.co.uk, 1
|
||||
epossystems.co.uk, 1
|
||||
epostplus.li, 1
|
||||
eposwales.co.uk, 1
|
||||
eposyork.co.uk, 1
|
||||
eppelblei.lu, 1
|
||||
eppelduerferjugend.lu, 1
|
||||
eppelpress.lu, 1
|
||||
|
@ -11383,7 +11366,6 @@ equinox.io, 1
|
|||
equipandoloja.net.br, 1
|
||||
equipedefrance.tv, 1
|
||||
equipeferramentas.com.br, 1
|
||||
equippers.de, 1
|
||||
equipsupply.com, 1
|
||||
er-music.com, 1
|
||||
er.tl, 1
|
||||
|
@ -11687,6 +11669,7 @@ estcequejailaflemme.fr, 1
|
|||
estcequonmetenprodaujourdhui.info, 1
|
||||
esteam.se, 1
|
||||
estedafah.com, 1
|
||||
estespr.com, 1
|
||||
esteticanorte.com.br, 1
|
||||
estetista.net, 1
|
||||
estilopack-loja.com.br, 1
|
||||
|
@ -12047,6 +12030,7 @@ extreme.co.th, 1
|
|||
extrememanual.net, 1
|
||||
exvs.org, 1
|
||||
exyplis.com, 1
|
||||
eyasc.nl, 1
|
||||
eydesignguidelines.com, 1
|
||||
eyecandy.gr, 1
|
||||
eyeglasses.com, 0
|
||||
|
@ -12307,7 +12291,6 @@ fassadenverkleidung24.de, 1
|
|||
fassi-sport.it, 1
|
||||
fastaim.de, 1
|
||||
fastbackmbg.be, 1
|
||||
fastbackmbm.be, 1
|
||||
fastcash.com.br, 1
|
||||
fastcommerce.org, 1
|
||||
fastconfirm.com, 1
|
||||
|
@ -12784,6 +12767,7 @@ flexinvesting.fi, 1
|
|||
flexport.com, 1
|
||||
flexstart.me, 1
|
||||
flextrack.dk, 1
|
||||
flextribly.xyz, 1
|
||||
fliacuello.com.ar, 1
|
||||
flightdeckfriend.com, 1
|
||||
flightmedx.com, 1
|
||||
|
@ -12843,7 +12827,6 @@ floth.at, 1
|
|||
flow.su, 1
|
||||
flowcom.de, 1
|
||||
flowcount.xyz, 1
|
||||
flowerandplant.org, 1
|
||||
flowersbylegacy.com, 1
|
||||
flowinvoice.com, 1
|
||||
flowreader.com, 1
|
||||
|
@ -13043,8 +13026,6 @@ forty8creates.com, 1
|
|||
fortytwo.cloud, 1
|
||||
forum-bonn.de, 1
|
||||
forum-heg.ch, 1
|
||||
forum-kinozal-tv.appspot.com, 1
|
||||
forum-kinozal.appspot.com, 1
|
||||
forum.linode.com, 0
|
||||
forum3.ru, 1
|
||||
forumvoordemocratie.nl, 1
|
||||
|
@ -13681,7 +13662,6 @@ gamerpoets.com, 1
|
|||
gamerz-stream.com, 1
|
||||
gamerzdot.com, 1
|
||||
games4theworld.org, 1
|
||||
gameserver-sponsor.me, 1
|
||||
gameshowchallenge.ie, 1
|
||||
gamesplanet.com, 1
|
||||
gamesputnik.ru, 1
|
||||
|
@ -14126,6 +14106,7 @@ giftedconsortium.com, 1
|
|||
giftking.nl, 0
|
||||
giftmaniabrilhos.com.br, 1
|
||||
gifts365.co.uk, 1
|
||||
giftservices.nl, 1
|
||||
giftsn.com.sg, 0
|
||||
gifzilla.net, 0
|
||||
gig-raiffeisen.de, 1
|
||||
|
@ -14216,7 +14197,7 @@ gjspunk.de, 0
|
|||
gjung.com, 0
|
||||
gkimanyar.org, 1
|
||||
gkralik.eu, 1
|
||||
gkvsc.de, 1
|
||||
gkvsc.de, 0
|
||||
gl.search.yahoo.com, 0
|
||||
glabiatoren-kst.de, 1
|
||||
glaciernursery.com, 1
|
||||
|
@ -14324,7 +14305,6 @@ gnetwork.eu, 1
|
|||
gnhub.org, 1
|
||||
gnilebein.de, 1
|
||||
gnom.me, 1
|
||||
gnosticjade.net, 1
|
||||
gnucashtoqif.us, 1
|
||||
gnunet.org, 1
|
||||
gnwp.eu, 1
|
||||
|
@ -14667,7 +14647,6 @@ grexx.de, 1
|
|||
grey.house, 1
|
||||
greybit.net, 1
|
||||
greyhash.se, 1
|
||||
greysky.me, 1
|
||||
greyskymedia.com, 1
|
||||
greysolutions.it, 1
|
||||
greywizard.com, 1
|
||||
|
@ -15027,7 +15006,6 @@ halkirkbouncycastles.co.uk, 1
|
|||
halkyon.net, 1
|
||||
hallelujahsoftware.com, 1
|
||||
halletienne.fr, 1
|
||||
hallettxn.com, 1
|
||||
hallhuber.com, 1
|
||||
halliday.work, 1
|
||||
halligladen.de, 1
|
||||
|
@ -15543,7 +15521,6 @@ heyfringe.com, 1
|
|||
heyjournal.com, 1
|
||||
hf-tekst.nl, 1
|
||||
hf51.nl, 1
|
||||
hfbg.nl, 1
|
||||
hfi.me, 0
|
||||
hfu.io, 1
|
||||
hg.python.org, 1
|
||||
|
@ -15796,6 +15773,7 @@ holidaysportugal.eu, 1
|
|||
holisticacupuncture.com.au, 1
|
||||
holistichealer.in, 1
|
||||
holisticon.de, 1
|
||||
hollandguns.com, 1
|
||||
hollermann.eu, 1
|
||||
hollo.me, 1
|
||||
hollowpoint.xyz, 1
|
||||
|
@ -15858,6 +15836,7 @@ hommeatoutfaire.be, 1
|
|||
homoglyph.net, 1
|
||||
homophoni.com, 1
|
||||
hompus.nl, 0
|
||||
homyremedies.com, 1
|
||||
honda-centrum.cz, 1
|
||||
hondart.cz, 1
|
||||
hondenoppasfraneker.nl, 1
|
||||
|
@ -16202,6 +16181,7 @@ hustle.life, 1
|
|||
hustlehope.com, 1
|
||||
hustunique.com, 1
|
||||
huto.ml, 1
|
||||
huutonauru.net, 1
|
||||
huwcbjones.co.uk, 1
|
||||
huwcbjones.uk, 1
|
||||
huwjones.me, 1
|
||||
|
@ -16496,7 +16476,6 @@ ig.com, 1
|
|||
iga-semi.jp, 1
|
||||
igamingforums.com, 1
|
||||
igcc.jp, 1
|
||||
igd.chat, 1
|
||||
igglabs.com, 1
|
||||
iggprivate.com, 1
|
||||
iggsoft.com, 1
|
||||
|
@ -16758,6 +16737,7 @@ indianaberry.com, 1
|
|||
indianaffairs.gov, 0
|
||||
indiawise.co.uk, 1
|
||||
indicateurs-flash.fr, 1
|
||||
indieethos.com, 1
|
||||
indiegame.space, 1
|
||||
indievelopment.nl, 1
|
||||
indigoinflatables.com, 1
|
||||
|
@ -16804,7 +16784,6 @@ infinitiofmarinparts.com, 1
|
|||
infinity.to, 1
|
||||
infinitybas.com, 1
|
||||
infinityengine.org, 1
|
||||
infinityepos.co.uk, 1
|
||||
infirmiere-canadienne.com, 1
|
||||
infirmieredevie.ch, 1
|
||||
inflatablehire-scotland.co.uk, 1
|
||||
|
@ -17302,6 +17281,7 @@ islam.si, 1
|
|||
islandhosting.com, 1
|
||||
islandinthenet.com, 1
|
||||
islandoilsupply.com, 1
|
||||
islandpumpandtank.com, 1
|
||||
islazia.fr, 1
|
||||
isletech.net, 1
|
||||
isliada.org, 1
|
||||
|
@ -17556,6 +17536,7 @@ jaberg-rutschi.ch, 1
|
|||
jabergrutschi.ch, 1
|
||||
jability.ovh, 1
|
||||
jabjab.de, 1
|
||||
jaccblog.com, 1
|
||||
jacekowski.org, 1
|
||||
jackdawphoto.co.uk, 1
|
||||
jackdelik.de, 1
|
||||
|
@ -18364,7 +18345,6 @@ jurassicgolf.nl, 1
|
|||
juridiqueo.com, 1
|
||||
juridoc.com.br, 1
|
||||
jurijbuga.de, 1
|
||||
jurisprudent.by, 1
|
||||
juristeo.com, 1
|
||||
jurko.cz, 1
|
||||
jurriaan.ninja, 1
|
||||
|
@ -18776,6 +18756,7 @@ kenny-peck.com, 1
|
|||
kennynet.co.uk, 1
|
||||
keno.im, 1
|
||||
kenokallinger.at, 1
|
||||
kenoschwalb.com, 1
|
||||
kenrogers.co, 0
|
||||
kens.pics, 1
|
||||
kensbouncycastles.co.uk, 1
|
||||
|
@ -19417,7 +19398,7 @@ kropkait.pl, 1
|
|||
krouzkyliduska.cz, 1
|
||||
krsn.de, 1
|
||||
krugermillions.org, 1
|
||||
krugoval.hr, 1
|
||||
krugoval.hr, 0
|
||||
kruin.net, 1
|
||||
kruisselbrink.com, 1
|
||||
kruk.co, 1
|
||||
|
@ -21124,7 +21105,6 @@ mabulledu.net, 1
|
|||
mac-i-tea.ch, 1
|
||||
mac-world.pl, 1
|
||||
mac1.net, 1
|
||||
macandtonic.com, 1
|
||||
macaque.io, 0
|
||||
macaw.nl, 1
|
||||
macaws.org, 1
|
||||
|
@ -21775,7 +21755,6 @@ mattli.us, 1
|
|||
mattmccutchen.net, 1
|
||||
mattmcshane.com, 1
|
||||
mattonline.me, 1
|
||||
mattwb65.com, 1
|
||||
mattwservices.co.uk, 1
|
||||
matviet.vn, 1
|
||||
matze.co, 1
|
||||
|
@ -21796,6 +21775,7 @@ mawidaca.com, 1
|
|||
max-moeglich.de, 1
|
||||
max-went.pl, 1
|
||||
max.gov, 1
|
||||
maxbeenen.de, 1
|
||||
maxbruckner.de, 1
|
||||
maxbruckner.org, 1
|
||||
maxbytes.nl, 0
|
||||
|
@ -22016,6 +21996,7 @@ medicinskavranje.edu.rs, 1
|
|||
medicocompetente.it, 1
|
||||
medicoresponde.com.br, 1
|
||||
medienweite.de, 1
|
||||
medifab.online, 1
|
||||
medifi.com, 1
|
||||
medigap-quote.net, 1
|
||||
medinside.ch, 1
|
||||
|
@ -22115,7 +22096,6 @@ meisterritter.de, 1
|
|||
meizufans.eu, 1
|
||||
meklon.net, 1
|
||||
mekongeye.com, 1
|
||||
melakaltenegger.at, 1
|
||||
melaniebernhardt.com, 1
|
||||
melaniegruber.de, 1
|
||||
melbourne.dating, 1
|
||||
|
@ -22547,6 +22527,7 @@ minesouls.fr, 1
|
|||
minetude.com, 1
|
||||
minez-nightswatch.com, 0
|
||||
minf3-games.de, 1
|
||||
mingming.info, 1
|
||||
mingram.net, 1
|
||||
mingwah.ch, 1
|
||||
mingy.ddns.net, 1
|
||||
|
@ -22604,7 +22585,6 @@ mirkofranz.de, 1
|
|||
mirodasilva.be, 1
|
||||
mironet.cz, 1
|
||||
mirrorsedgearchive.de, 1
|
||||
mirrorsedgearchive.ga, 1
|
||||
mirshak.com, 1
|
||||
mirtes.cz, 1
|
||||
mirtouf.fr, 1
|
||||
|
@ -23148,6 +23128,7 @@ mrkapowski.com, 1
|
|||
mrketolocksmith.com, 1
|
||||
mrknee.gr, 1
|
||||
mrksk.com, 1
|
||||
mrleonardo.com, 1
|
||||
mrliu.me, 1
|
||||
mrmoregame.de, 1
|
||||
mrnh.de, 1
|
||||
|
@ -23927,6 +23908,7 @@ ncconsumer.org, 1
|
|||
ncdesigns-studio.com, 1
|
||||
ncea.net.au, 1
|
||||
nchangfong.com, 1
|
||||
nchristo.com, 1
|
||||
nclvle.co.uk, 1
|
||||
ncrmnt.org, 1
|
||||
ncsccs.com, 1
|
||||
|
@ -24121,6 +24103,7 @@ netraising.com, 1
|
|||
netrelay.email, 1
|
||||
netrider.net.au, 0
|
||||
netronix.be, 1
|
||||
netsafeid.biz, 1
|
||||
netscaler.expert, 1
|
||||
netsight.org, 1
|
||||
netsigna.de, 1
|
||||
|
@ -24212,7 +24195,6 @@ newizv.ru, 1
|
|||
newjianzhi.com, 1
|
||||
newkaliningrad.ru, 1
|
||||
newknd.com, 1
|
||||
newline.online, 1
|
||||
newmarketbouncycastlehire.co.uk, 1
|
||||
newmed.com.br, 1
|
||||
newmediaone.net, 1
|
||||
|
@ -26146,6 +26128,7 @@ penetrationstest.se, 1
|
|||
penfold.fr, 1
|
||||
pengi.me, 1
|
||||
pengisatelier.net, 1
|
||||
pengui.uk, 1
|
||||
penguinprotocols.com, 1
|
||||
pengumuman.id, 1
|
||||
penispumpen.se, 1
|
||||
|
@ -26254,6 +26237,7 @@ peterhuetz.com, 1
|
|||
peterjohnson.io, 1
|
||||
peterlew.is, 1
|
||||
petersontoscano.com, 1
|
||||
pethelpers.org, 1
|
||||
petit-archer.com, 1
|
||||
petite-maison.ch, 1
|
||||
petitsfrenchies.com, 1
|
||||
|
@ -26772,7 +26756,6 @@ plumlocosoft.com, 1
|
|||
plumnet.ch, 1
|
||||
plumpie.net, 0
|
||||
plur.com.au, 1
|
||||
plural.cafe, 1
|
||||
plus-5.com, 1
|
||||
plus.google.com, 1
|
||||
plus.sandbox.google.com, 1
|
||||
|
@ -27006,7 +26989,6 @@ portalkla.com.br, 1
|
|||
portalmundo.xyz, 1
|
||||
portalzine.de, 1
|
||||
porte.roma.it, 1
|
||||
portefeuillesignalen.nl, 1
|
||||
portercup.com, 1
|
||||
porterranchelectrical.com, 1
|
||||
portofacil.com, 1
|
||||
|
@ -27022,7 +27004,6 @@ portvaletickets.com, 1
|
|||
porybox.com, 1
|
||||
porzgmbh.de, 1
|
||||
posaunenchor-senden.de, 1
|
||||
posbank.co.uk, 1
|
||||
poseidonwaterproofing.com, 1
|
||||
poshcastles.co.uk, 1
|
||||
poshlashes.se, 1
|
||||
|
@ -27081,6 +27062,7 @@ pouet.it, 1
|
|||
pouets.ovh, 1
|
||||
poupatempo.org, 1
|
||||
pourlesenfants.info, 1
|
||||
pourout.org, 1
|
||||
povareschka.ru, 1
|
||||
povesham.tk, 1
|
||||
powaclub.com, 1
|
||||
|
@ -27800,6 +27782,7 @@ quanwuji.com, 1
|
|||
quanyin.eu.org, 1
|
||||
quareal.ru, 1
|
||||
quarkdose.de, 1
|
||||
quarryhillrentals.com, 1
|
||||
quarterfull.com, 1
|
||||
quartix.com, 1
|
||||
quartzclinical.com, 1
|
||||
|
@ -28214,7 +28197,7 @@ recetasfacilesdehacer.com, 1
|
|||
rechenknaecht.de, 1
|
||||
rechenwerk.net, 1
|
||||
recht-freundlich.de, 1
|
||||
rechtenliteratuurleiden.nl, 1
|
||||
rechtenliteratuurleiden.nl, 0
|
||||
rechtsanwaeltin-vollmer.de, 1
|
||||
rechtsanwalt-koeppen-feucht.de, 1
|
||||
rechtschreibpruefung24.de, 1
|
||||
|
@ -28294,6 +28277,7 @@ redneck-gaming.de, 1
|
|||
redneragenturen.org, 1
|
||||
rednoseday.com, 1
|
||||
rednsx.org, 1
|
||||
redperegrine.com, 1
|
||||
redporno.cz, 1
|
||||
redprice.by, 1
|
||||
redshield.co, 1
|
||||
|
@ -28469,6 +28453,7 @@ rentbrowser.com, 1
|
|||
rentinsingapore.com.sg, 1
|
||||
rentourhomeinprovence.com, 1
|
||||
renuo.ch, 1
|
||||
renyiyou.com, 1
|
||||
reorz.com, 1
|
||||
reox.at, 0
|
||||
repaik.com, 1
|
||||
|
@ -28802,7 +28787,7 @@ roave.com, 1
|
|||
rob.uk.com, 1
|
||||
rob006.net, 1
|
||||
robandjanine.com, 1
|
||||
robbertt.com, 1
|
||||
robbertt.com, 0
|
||||
robdavidson.network, 1
|
||||
robert-flynn.de, 1
|
||||
robertabittle.com, 1
|
||||
|
@ -28815,7 +28800,6 @@ robertlysik.com, 1
|
|||
robertnemec.com, 1
|
||||
roberto-webhosting.nl, 1
|
||||
robertocasares.no-ip.biz, 1
|
||||
robertoentringer.com, 1
|
||||
robertof.ovh, 1
|
||||
robertreiser.photography, 1
|
||||
robertrijnders.nl, 1
|
||||
|
@ -28873,7 +28857,6 @@ rockymountainspice.com, 1
|
|||
rocssti.net, 1
|
||||
rodafe.sk, 1
|
||||
rodarion.pl, 1
|
||||
roddis.net, 1
|
||||
rodehutskors.net, 1
|
||||
rodeobull.biz, 1
|
||||
rodeohire.com, 1
|
||||
|
@ -28922,6 +28905,7 @@ rohitagr.com, 1
|
|||
rointe.online, 1
|
||||
roiscroll.com, 1
|
||||
roka9.de, 1
|
||||
roketix.co.uk, 1
|
||||
rokki.ch, 1
|
||||
rokort.dk, 1
|
||||
roksolana.be, 1
|
||||
|
@ -29021,7 +29005,6 @@ rosewoodranch.com, 1
|
|||
rosi-royal.com, 1
|
||||
roslynpad.net, 1
|
||||
rospa100.com, 1
|
||||
rossclark.com, 1
|
||||
rosset.me, 1
|
||||
rosset.net, 1
|
||||
rosslug.org.uk, 1
|
||||
|
@ -29407,7 +29390,6 @@ sallysubs.com, 1
|
|||
salmo23.com.br, 1
|
||||
salmododia.net, 1
|
||||
salmonella.co.uk, 1
|
||||
salmonrecovery.gov, 1
|
||||
salmonvision.com.tw, 0
|
||||
salmos91.com, 1
|
||||
salmotierra-salvatierra.com, 1
|
||||
|
@ -29544,6 +29526,7 @@ sapac.es, 1
|
|||
sapereaude.com.pl, 1
|
||||
sapien-ci.com, 1
|
||||
sapience.com, 1
|
||||
sapk.fr, 1
|
||||
saposute-s.jp, 1
|
||||
sapphireblue.me, 1
|
||||
sapphirepearl.com.sg, 1
|
||||
|
@ -30125,6 +30108,7 @@ selectel.ru, 1
|
|||
selectorders.com, 1
|
||||
selegiline.com, 1
|
||||
selent.me, 1
|
||||
seleondar.ru, 1
|
||||
self-evident.org, 1
|
||||
self-signed.com, 1
|
||||
self-xss.info, 1
|
||||
|
@ -30204,6 +30188,7 @@ seocomposer.com, 1
|
|||
seoexperte.berlin, 1
|
||||
seogeek.nl, 1
|
||||
seohochschule.de, 1
|
||||
seoinc.com, 1
|
||||
seoium.com, 1
|
||||
seokay.com, 1
|
||||
seolib.org, 1
|
||||
|
@ -30325,7 +30310,6 @@ sevsey.ru, 1
|
|||
sevsopr.ru, 1
|
||||
sewafineseam.com, 1
|
||||
sewinginsight.com, 1
|
||||
sewoo.co.uk, 1
|
||||
sex-education.com, 1
|
||||
sexaki.com, 1
|
||||
sexdocka.nu, 1
|
||||
|
@ -30432,6 +30416,7 @@ shaobin.wang, 1
|
|||
sharanyamunsi.net, 1
|
||||
sharealo.org, 1
|
||||
sharedhost.de, 1
|
||||
shareeri.com, 1
|
||||
sharelovenotsecrets.com, 1
|
||||
sharemessage.net, 1
|
||||
shareoffice.ch, 1
|
||||
|
@ -30462,6 +30447,7 @@ shavegazette.com, 1
|
|||
shavingks.com, 1
|
||||
shawcentral.ca, 0
|
||||
shawnhogan.com, 1
|
||||
shawnstarrcustomhomes.com, 1
|
||||
shawnwilkerson.com, 1
|
||||
shawnwilson.info, 1
|
||||
shazbots.org, 1
|
||||
|
@ -30790,6 +30776,7 @@ silverlinkz.net, 1
|
|||
silverseen.com, 1
|
||||
silverstartup.sk, 1
|
||||
silverwind.io, 1
|
||||
silviamacallister.com, 1
|
||||
silvine.xyz, 1
|
||||
silvistefi.com, 1
|
||||
silvobeat.blog, 1
|
||||
|
@ -31122,6 +31109,7 @@ slotfara.com, 1
|
|||
slotfara.net, 1
|
||||
sloths.org, 1
|
||||
slotlist.info, 1
|
||||
slovakiana.sk, 1
|
||||
slovenskycestovatel.sk, 1
|
||||
slow.zone, 1
|
||||
slowb.ro, 1
|
||||
|
@ -31154,7 +31142,6 @@ smaltimento-rifiuti.org, 1
|
|||
smaltimento.caserta.it, 1
|
||||
smaltimento.napoli.it, 1
|
||||
smaltimentoamianto.latina.it, 1
|
||||
smaltimentorifiuti.veneto.it, 1
|
||||
smares.de, 1
|
||||
smart-cp.jp, 1
|
||||
smart-informatics.com, 1
|
||||
|
@ -31247,6 +31234,7 @@ smutba.se, 1
|
|||
smutek.net, 1
|
||||
smx.net.br, 1
|
||||
snackbesteld.nl, 1
|
||||
snafarms.com, 1
|
||||
snafu.cz, 1
|
||||
snakafya.com, 1
|
||||
snake.dog, 1
|
||||
|
@ -31556,7 +31544,6 @@ sourcebox.be, 1
|
|||
sourcecode.love, 1
|
||||
sourcely.net, 1
|
||||
sourceway.de, 1
|
||||
sourcitec.com, 1
|
||||
souris.ch, 1
|
||||
sous-surveillance.net, 1
|
||||
southafrican.dating, 1
|
||||
|
@ -31730,7 +31717,6 @@ spornkuller.de, 1
|
|||
sport-in-sundern.de, 1
|
||||
sport-potreby.cz, 1
|
||||
sport-potreby.sk, 1
|
||||
sport-socken.net, 1
|
||||
sport247.bet, 1
|
||||
sporter.com, 1
|
||||
sportflash.info, 1
|
||||
|
@ -32127,7 +32113,6 @@ stevenski.com, 0
|
|||
steventress.com, 1
|
||||
steventruesdell.com, 1
|
||||
stevenwooding.com, 1
|
||||
stevenz.science, 1
|
||||
stevesdrivingschooltyneside.com, 1
|
||||
stewartswines.com, 1
|
||||
stewonet.nl, 1
|
||||
|
@ -32190,6 +32175,7 @@ stoianlawfirm.com, 1
|
|||
stolina.de, 0
|
||||
stolkpotplanten.nl, 1
|
||||
stolkschepen.nl, 1
|
||||
stomadental.com, 1
|
||||
stomt.com, 1
|
||||
stonedworms.de, 1
|
||||
stonefusion.org.uk, 1
|
||||
|
@ -32200,7 +32186,6 @@ stonewuu.com, 1
|
|||
stony.com, 1
|
||||
stonystratford.org, 1
|
||||
stopakwardhandshakes.org, 1
|
||||
stopbreakupnow.org, 1
|
||||
stopbullying.gov, 1
|
||||
stopfraud.gov, 1
|
||||
stopthethyroidmadness.com, 1
|
||||
|
@ -32455,7 +32440,6 @@ sundayfundayjapan.com, 1
|
|||
suneilpatel.com, 1
|
||||
sunfeathers.net, 1
|
||||
sunfireshop.com.br, 1
|
||||
sunflyer.cn, 0
|
||||
sunfox.cz, 1
|
||||
sunfulong.blog, 1
|
||||
sunfulong.me, 1
|
||||
|
@ -32962,7 +32946,6 @@ taunhanh.us, 1
|
|||
tavolaquadrada.com.br, 1
|
||||
tavsys.net, 1
|
||||
taxaroo.com, 1
|
||||
taxi-24std.de, 1
|
||||
taxi-chamonix.fr, 1
|
||||
taxi-collectif.ch, 1
|
||||
taxi-puck.pl, 1
|
||||
|
@ -33076,6 +33059,7 @@ tech-essential.com, 1
|
|||
tech-rat.com, 1
|
||||
tech-seminar.jp, 1
|
||||
tech-value.eu, 1
|
||||
tech-zealots.com, 1
|
||||
techace.jp, 1
|
||||
techademy.nl, 1
|
||||
techarea.fr, 1
|
||||
|
@ -33161,6 +33145,7 @@ teemperor.de, 1
|
|||
teemulintula.fi, 1
|
||||
teencounseling.com, 1
|
||||
teenerotic.net, 1
|
||||
teeplelaw.com, 1
|
||||
teesypeesy.com, 1
|
||||
teeworlds-friends.de, 1
|
||||
tefek.cz, 1
|
||||
|
@ -33429,6 +33414,7 @@ thebodyprinciple.com, 1
|
|||
thebouncedepartment.co.uk, 1
|
||||
thebouncyman.co.uk, 1
|
||||
theboxofcarlos.com, 1
|
||||
thebreakhotel.com, 1
|
||||
thebreakroom.org, 1
|
||||
thebte.com, 1
|
||||
thebuffalotavern.com, 1
|
||||
|
@ -33574,6 +33560,7 @@ theobromos.fr, 1
|
|||
theocharis.org, 1
|
||||
theodorahome.co, 1
|
||||
theodorahome.com.br, 1
|
||||
theofleck.com, 1
|
||||
theojones.name, 1
|
||||
theokonst.tk, 1
|
||||
theokouzelis.com, 1
|
||||
|
@ -34100,6 +34087,7 @@ todocracy.com, 1
|
|||
todoescine.com, 1
|
||||
todoist.com, 1
|
||||
todon.fr, 1
|
||||
todoscomciro.com, 1
|
||||
todosrv.com, 1
|
||||
toeglhofer.at, 1
|
||||
toeightycountries.com, 1
|
||||
|
@ -34290,7 +34278,6 @@ toptexture.com, 1
|
|||
toptheto.com, 1
|
||||
topvertimai.lt, 1
|
||||
topwin.la, 1
|
||||
topwindowcleaners.co.uk, 1
|
||||
topworktops.co.uk, 1
|
||||
tor2web.org, 1
|
||||
toracon.org, 1
|
||||
|
@ -34351,7 +34338,6 @@ touch-up-net.com, 1
|
|||
touch.facebook.com, 0
|
||||
touch.mail.ru, 1
|
||||
touchoflife.in, 1
|
||||
touchscreentills.com, 1
|
||||
touchweb.fr, 1
|
||||
touchwoodtrees.com.au, 1
|
||||
tougetu.com, 1
|
||||
|
@ -34949,7 +34935,6 @@ tysye.ca, 1
|
|||
tyuo-keibi.co.jp, 1
|
||||
tzifas.com, 1
|
||||
tzwe.com, 1
|
||||
u-master.net, 1
|
||||
u-metals.com, 1
|
||||
u-tokyo.club, 1
|
||||
u.nu, 1
|
||||
|
@ -34992,6 +34977,7 @@ uc.ac.id, 1
|
|||
ucac.nz, 0
|
||||
ucangiller.com, 1
|
||||
ucch.be, 1
|
||||
ucfirst.nl, 1
|
||||
uchargeapp.com, 1
|
||||
uclanmasterplan.co.uk, 1
|
||||
uclip.club, 1
|
||||
|
@ -35285,7 +35271,6 @@ urbanmelbourne.info, 1
|
|||
urbanmic.com, 1
|
||||
urbannewsservice.com, 1
|
||||
urbansparrow.in, 1
|
||||
urbanstylestaging.com, 1
|
||||
urbanwildlifealliance.org, 0
|
||||
urbexdk.nl, 1
|
||||
urcentral.com, 1
|
||||
|
@ -35954,6 +35939,7 @@ vivamusic.es, 1
|
|||
vivanosports.com.br, 1
|
||||
vivatv.com.tw, 1
|
||||
vivendi.de, 1
|
||||
vivianmaier.cn, 1
|
||||
vivid-academy.com, 1
|
||||
vividinflatables.co.uk, 1
|
||||
vividlumen.com, 1
|
||||
|
@ -36790,7 +36776,6 @@ whisperinghoperanch.org, 1
|
|||
whisperlab.org, 1
|
||||
whistleb.com, 1
|
||||
whistleblower.gov, 1
|
||||
whistler-transfers.com, 1
|
||||
whitby-brewery.com, 1
|
||||
whitealps.at, 1
|
||||
whitealps.be, 1
|
||||
|
@ -37170,7 +37155,6 @@ workwithgo.com, 1
|
|||
world-education-association.org, 1
|
||||
world-in-my-eyes.com, 1
|
||||
worldcareers.dk, 1
|
||||
worldchess.london, 1
|
||||
worldcigars.com.br, 1
|
||||
worldcrafts.org, 1
|
||||
worldcubeassociation.org, 1
|
||||
|
@ -37550,7 +37534,6 @@ xing.ml, 1
|
|||
xingiahanvisa.net, 1
|
||||
xiqi.us, 1
|
||||
xirion.net, 1
|
||||
xiyu.it, 0
|
||||
xiyu.moe, 1
|
||||
xj8876.com, 1
|
||||
xjd.vision, 1
|
||||
|
@ -37876,6 +37859,7 @@ ybscareers.co.uk, 1
|
|||
ybsul.com, 1
|
||||
ybti.net, 1
|
||||
ybzhao.com, 1
|
||||
ycaaz.com, 1
|
||||
ych.art, 1
|
||||
ycherbonnel.fr, 1
|
||||
ychon.com, 1
|
||||
|
@ -38174,7 +38158,7 @@ yumeconcert.com, 1
|
|||
yumli.net, 1
|
||||
yummylooks.com, 1
|
||||
yuna.love, 1
|
||||
yuna.tg, 1
|
||||
yuna.tg, 0
|
||||
yunity.org, 1
|
||||
yunjishou.pro, 1
|
||||
yunzhu.li, 1
|
||||
|
@ -38270,6 +38254,7 @@ zargaripour.com, 1
|
|||
zargescases.co.uk, 1
|
||||
zarmarket.org, 1
|
||||
zarpo.com.br, 1
|
||||
zary.me, 1
|
||||
zatsepin.by, 1
|
||||
zaufanatrzeciastrona.pl, 1
|
||||
zavec.com.ec, 1
|
||||
|
@ -38374,6 +38359,7 @@ zhangfangzhou.com, 1
|
|||
zhangge.net, 1
|
||||
zhanghao.me, 1
|
||||
zhangheda.cf, 1
|
||||
zhangsidan.com, 0
|
||||
zhangsir.net, 1
|
||||
zhangyuhao.com, 1
|
||||
zhaochen.xyz, 1
|
||||
|
|
|
@ -7,12 +7,102 @@
|
|||
#include "SandboxInitialization.h"
|
||||
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "nsWindowsDllInterceptor.h"
|
||||
#include "sandbox/win/src/sandbox_factory.h"
|
||||
#include "mozilla/sandboxing/permissionsService.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace sandboxing {
|
||||
|
||||
typedef BOOL(WINAPI* CloseHandle_func) (HANDLE hObject);
|
||||
static CloseHandle_func stub_CloseHandle = nullptr;
|
||||
|
||||
typedef BOOL(WINAPI* DuplicateHandle_func)(HANDLE hSourceProcessHandle,
|
||||
HANDLE hSourceHandle,
|
||||
HANDLE hTargetProcessHandle,
|
||||
LPHANDLE lpTargetHandle,
|
||||
DWORD dwDesiredAccess,
|
||||
BOOL bInheritHandle,
|
||||
DWORD dwOptions);
|
||||
static DuplicateHandle_func stub_DuplicateHandle = nullptr;
|
||||
|
||||
static BOOL WINAPI
|
||||
patched_CloseHandle(HANDLE hObject)
|
||||
{
|
||||
// Check all handles being closed against the sandbox's tracked handles.
|
||||
base::win::OnHandleBeingClosed(hObject);
|
||||
return stub_CloseHandle(hObject);
|
||||
}
|
||||
|
||||
static BOOL WINAPI
|
||||
patched_DuplicateHandle(HANDLE hSourceProcessHandle,
|
||||
HANDLE hSourceHandle,
|
||||
HANDLE hTargetProcessHandle,
|
||||
LPHANDLE lpTargetHandle,
|
||||
DWORD dwDesiredAccess,
|
||||
BOOL bInheritHandle,
|
||||
DWORD dwOptions)
|
||||
{
|
||||
// If closing a source handle from our process check it against the sandbox's
|
||||
// tracked handles.
|
||||
if ((dwOptions & DUPLICATE_CLOSE_SOURCE) &&
|
||||
(GetProcessId(hSourceProcessHandle) == ::GetCurrentProcessId())) {
|
||||
base::win::OnHandleBeingClosed(hSourceHandle);
|
||||
}
|
||||
|
||||
return stub_DuplicateHandle(hSourceProcessHandle, hSourceHandle,
|
||||
hTargetProcessHandle, lpTargetHandle,
|
||||
dwDesiredAccess, bInheritHandle, dwOptions);
|
||||
}
|
||||
|
||||
static WindowsDllInterceptor Kernel32Intercept;
|
||||
|
||||
static bool
|
||||
EnableHandleCloseMonitoring()
|
||||
{
|
||||
Kernel32Intercept.Init("kernel32.dll");
|
||||
bool hooked =
|
||||
Kernel32Intercept.AddHook("CloseHandle",
|
||||
reinterpret_cast<intptr_t>(patched_CloseHandle),
|
||||
(void**)&stub_CloseHandle);
|
||||
if (!hooked) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hooked =
|
||||
Kernel32Intercept.AddHook("DuplicateHandle",
|
||||
reinterpret_cast<intptr_t>(patched_DuplicateHandle),
|
||||
(void**)&stub_DuplicateHandle);
|
||||
if (!hooked) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
ShouldDisableHandleVerifier()
|
||||
{
|
||||
#if defined(_X86_) && (defined(NIGHTLY_BUILD) || defined(DEBUG))
|
||||
// Chromium only has the verifier enabled for 32-bit and our close monitoring
|
||||
// hooks cause debug assertions for 64-bit anyway.
|
||||
// For x86 keep the verifier enabled by default only for Nightly or debug.
|
||||
return false;
|
||||
#else
|
||||
return !getenv("MOZ_ENABLE_HANDLE_VERIFIER");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
InitializeHandleVerifier()
|
||||
{
|
||||
// Disable the handle verifier if we don't want it or can't enable the close
|
||||
// monitoring hooks.
|
||||
if (ShouldDisableHandleVerifier() || !EnableHandleCloseMonitoring()) {
|
||||
base::win::DisableHandleVerifier();
|
||||
}
|
||||
}
|
||||
|
||||
static sandbox::TargetServices*
|
||||
InitializeTargetServices()
|
||||
{
|
||||
|
@ -26,6 +116,8 @@ InitializeTargetServices()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
InitializeHandleVerifier();
|
||||
|
||||
return targetServices;
|
||||
}
|
||||
|
||||
|
@ -66,6 +158,8 @@ InitializeBrokerServices()
|
|||
scoped_refptr<sandbox::TargetPolicy> policy = brokerServices->CreatePolicy();
|
||||
sandbox::ResultCode result = policy->CreateAlternateDesktop(true);
|
||||
|
||||
InitializeHandleVerifier();
|
||||
|
||||
return brokerServices;
|
||||
}
|
||||
|
||||
|
|
|
@ -436,6 +436,20 @@ bool TestTlsFree(void* aFunc)
|
|||
return sTlsIndex != 0 && patchedTlsFree(sTlsIndex);
|
||||
}
|
||||
|
||||
bool TestCloseHandle(void* aFunc)
|
||||
{
|
||||
auto patchedCloseHandle =
|
||||
reinterpret_cast<decltype(&CloseHandle)>(aFunc);
|
||||
return patchedCloseHandle(0) == FALSE;
|
||||
}
|
||||
|
||||
bool TestDuplicateHandle(void* aFunc)
|
||||
{
|
||||
auto patchedDuplicateHandle =
|
||||
reinterpret_cast<decltype(&DuplicateHandle)>(aFunc);
|
||||
return patchedDuplicateHandle(0, 0, 0, 0, 0, 0, 0) == FALSE;
|
||||
}
|
||||
|
||||
bool TestPrintDlgW(void* aFunc)
|
||||
{
|
||||
auto patchedPrintDlgW =
|
||||
|
@ -694,6 +708,8 @@ int main()
|
|||
TestHook(TestSetCursorPos, "user32.dll", "SetCursorPos") &&
|
||||
TestHook(TestTlsAlloc, "kernel32.dll", "TlsAlloc") &&
|
||||
TestHook(TestTlsFree, "kernel32.dll", "TlsFree") &&
|
||||
TestHook(TestCloseHandle, "kernel32.dll", "CloseHandle") &&
|
||||
TestHook(TestDuplicateHandle, "kernel32.dll", "DuplicateHandle") &&
|
||||
|
||||
TestHook(TestInternetOpenA, "wininet.dll", "InternetOpenA") &&
|
||||
TestHook(TestInternetCloseHandle, "wininet.dll", "InternetCloseHandle") &&
|
||||
|
|
Загрузка…
Ссылка в новой задаче