Merge mozilla-central to autoland. a=merge on a CLOSED TREE

This commit is contained in:
Andreea Pavel 2018-04-10 00:57:43 +03:00
Родитель b53e658206 8e723a7457
Коммит edc60268bf
60 изменённых файлов: 1229 добавлений и 572 удалений

Просмотреть файл

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