зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound
This commit is contained in:
Коммит
28276b7127
|
@ -502,7 +502,8 @@ const gExtensionsNotifications = {
|
|||
|
||||
updateAlerts() {
|
||||
let sideloaded = ExtensionsUI.sideloaded;
|
||||
if (sideloaded.size == 0) {
|
||||
let updates = ExtensionsUI.updates;
|
||||
if (sideloaded.size + updates.size == 0) {
|
||||
gMenuButtonBadgeManager.removeBadge(gMenuButtonBadgeManager.BADGEID_ADDONS);
|
||||
} else {
|
||||
gMenuButtonBadgeManager.addBadge(gMenuButtonBadgeManager.BADGEID_ADDONS,
|
||||
|
@ -519,6 +520,23 @@ const gExtensionsNotifications = {
|
|||
const DEFAULT_EXTENSION_ICON =
|
||||
"chrome://mozapps/skin/extensions/extensionGeneric.svg";
|
||||
let items = 0;
|
||||
for (let update of updates) {
|
||||
if (++items > 4) {
|
||||
break;
|
||||
}
|
||||
let button = document.createElement("toolbarbutton");
|
||||
button.setAttribute("label", `"${update.addon.name}" requires new permissions`);
|
||||
|
||||
let icon = update.addon.iconURL || DEFAULT_EXTENSION_ICON;
|
||||
button.setAttribute("image", icon);
|
||||
|
||||
button.addEventListener("click", evt => {
|
||||
ExtensionsUI.showUpdate(gBrowser, update);
|
||||
});
|
||||
|
||||
container.appendChild(button);
|
||||
}
|
||||
|
||||
for (let addon of sideloaded) {
|
||||
if (++items > 4) {
|
||||
break;
|
||||
|
|
|
@ -7412,10 +7412,12 @@ var gIdentityHandler = {
|
|||
// If the permission item we were looking for doesn't exist,
|
||||
// the user has temporarily allowed sharing and we need to add
|
||||
// an item in the permissions array to reflect this.
|
||||
let permission =
|
||||
SitePermissions.getPermissionDetails(id, SitePermissions.SCOPE_REQUEST);
|
||||
permission.inUse = true;
|
||||
permissions.push(permission);
|
||||
permissions.push({
|
||||
id,
|
||||
state: SitePermissions.ALLOW,
|
||||
scope: SitePermissions.SCOPE_REQUEST,
|
||||
inUse: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7476,7 +7478,7 @@ var gIdentityHandler = {
|
|||
state = SitePermissions.ALLOW;
|
||||
scope = SitePermissions.SCOPE_REQUEST;
|
||||
}
|
||||
stateLabel.textContent = SitePermissions.getStateLabel(state, scope);
|
||||
stateLabel.textContent = SitePermissions.getCurrentStateLabel(state, scope);
|
||||
|
||||
let button = document.createElement("button");
|
||||
button.setAttribute("class", "identity-popup-permission-remove-button");
|
||||
|
|
|
@ -135,7 +135,7 @@ function createRow(aPartId) {
|
|||
for (let state of SitePermissions.getAvailableStates(aPartId)) {
|
||||
let radio = document.createElement("radio");
|
||||
radio.setAttribute("id", aPartId + "#" + state);
|
||||
radio.setAttribute("label", SitePermissions.getStateLabel(state));
|
||||
radio.setAttribute("label", SitePermissions.getMultichoiceStateLabel(state));
|
||||
radio.setAttribute("command", commandId);
|
||||
radiogroup.appendChild(radio);
|
||||
}
|
||||
|
|
|
@ -118,6 +118,9 @@ support-files =
|
|||
file_install_extensions.html
|
||||
browser_webext_permissions.xpi
|
||||
browser_webext_nopermissions.xpi
|
||||
browser_webext_update1.xpi
|
||||
browser_webext_update2.xpi
|
||||
browser_webext_update.json
|
||||
!/image/test/mochitest/blue.png
|
||||
!/toolkit/components/passwordmgr/test/browser/form_basic.html
|
||||
!/toolkit/components/passwordmgr/test/browser/insecure_test.html
|
||||
|
@ -304,6 +307,7 @@ skip-if = os == "mac" # decoder doctor isn't implemented on osx
|
|||
skip-if = true # browser_drag.js is disabled, as it needs to be updated for the new behavior from bug 320638.
|
||||
[browser_extension_permissions.js]
|
||||
[browser_extension_sideloading.js]
|
||||
[browser_extension_update.js]
|
||||
[browser_favicon_change.js]
|
||||
[browser_favicon_change_not_in_document.js]
|
||||
[browser_findbarClose.js]
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
const {AddonManagerPrivate} = Cu.import("resource://gre/modules/AddonManager.jsm", {});
|
||||
|
||||
const URL_BASE = "https://example.com/browser/browser/base/content/test/general";
|
||||
const ID = "update@tests.mozilla.org";
|
||||
|
||||
function promiseViewLoaded(tab, viewid) {
|
||||
let win = tab.linkedBrowser.contentWindow;
|
||||
if (win.gViewController && !win.gViewController.isLoading &&
|
||||
win.gViewController.currentViewId == viewid) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
function listener() {
|
||||
if (win.gViewController.currentViewId != viewid) {
|
||||
return;
|
||||
}
|
||||
win.document.removeEventListener("ViewChanged", listener);
|
||||
resolve();
|
||||
}
|
||||
win.document.addEventListener("ViewChanged", listener);
|
||||
});
|
||||
}
|
||||
|
||||
function promisePopupNotificationShown(name) {
|
||||
return new Promise(resolve => {
|
||||
function popupshown() {
|
||||
let notification = PopupNotifications.getNotification(name);
|
||||
if (!notification) { return; }
|
||||
|
||||
ok(notification, `${name} notification shown`);
|
||||
ok(PopupNotifications.isPanelOpen, "notification panel open");
|
||||
|
||||
PopupNotifications.panel.removeEventListener("popupshown", popupshown);
|
||||
resolve(PopupNotifications.panel.firstChild);
|
||||
}
|
||||
|
||||
PopupNotifications.panel.addEventListener("popupshown", popupshown);
|
||||
});
|
||||
}
|
||||
|
||||
function getBadgeStatus() {
|
||||
let menuButton = document.getElementById("PanelUI-menu-button");
|
||||
return menuButton.getAttribute("badge-status");
|
||||
}
|
||||
|
||||
function promiseUpdateDownloaded(addon) {
|
||||
return new Promise(resolve => {
|
||||
let listener = {
|
||||
onDownloadEnded(install) {
|
||||
if (install.addon.id == addon.id) {
|
||||
AddonManager.removeInstallListener(listener);
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
};
|
||||
AddonManager.addInstallListener(listener);
|
||||
});
|
||||
}
|
||||
|
||||
function promiseUpgrade(addon) {
|
||||
return new Promise(resolve => {
|
||||
let listener = {
|
||||
onInstallEnded(install, newAddon) {
|
||||
if (newAddon.id == addon.id) {
|
||||
AddonManager.removeInstallListener(listener);
|
||||
resolve(newAddon);
|
||||
}
|
||||
},
|
||||
};
|
||||
AddonManager.addInstallListener(listener);
|
||||
});
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
yield SpecialPowers.pushPrefEnv({set: [
|
||||
// Turn on background updates
|
||||
["extensions.update.enabled", true],
|
||||
|
||||
// Point updates to the local mochitest server
|
||||
["extensions.update.background.url", `${URL_BASE}/browser_webext_update.json`],
|
||||
|
||||
// We don't have pre-pinned certificates for the local mochitest server
|
||||
["extensions.install.requireBuiltInCerts", false],
|
||||
["extensions.update.requireBuiltInCerts", false],
|
||||
|
||||
// XXX remove this when prompts are enabled by default
|
||||
["extensions.webextPermissionPrompts", true],
|
||||
]});
|
||||
|
||||
// Install version 1.0 of the test extension
|
||||
let url1 = `${URL_BASE}/browser_webext_update1.xpi`;
|
||||
let install = yield AddonManager.getInstallForURL(url1, null, "application/x-xpinstall");
|
||||
ok(install, "Created install");
|
||||
|
||||
let addon = yield new Promise(resolve => {
|
||||
install.addListener({
|
||||
onInstallEnded(_install, _addon) {
|
||||
resolve(_addon);
|
||||
},
|
||||
});
|
||||
install.install();
|
||||
});
|
||||
|
||||
ok(addon, "Addon was installed");
|
||||
is(getBadgeStatus(), "", "Should not start out with an addon alert badge");
|
||||
|
||||
// Trigger an update check and wait for the update for this addon
|
||||
// to be downloaded.
|
||||
let updatePromise = promiseUpdateDownloaded(addon);
|
||||
AddonManagerPrivate.backgroundUpdateCheck();
|
||||
yield updatePromise;
|
||||
|
||||
is(getBadgeStatus(), "addon-alert", "Should have addon alert badge");
|
||||
|
||||
// Find the menu entry for the update
|
||||
yield PanelUI.show();
|
||||
|
||||
let addons = document.getElementById("PanelUI-footer-addons");
|
||||
is(addons.children.length, 1, "Have a menu entry for the update");
|
||||
|
||||
// Click the menu item
|
||||
let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:addons");
|
||||
let popupPromise = promisePopupNotificationShown("addon-webext-permissions");
|
||||
addons.children[0].click();
|
||||
|
||||
// about:addons should load and go to the list of extensions
|
||||
let tab = yield tabPromise;
|
||||
is(tab.linkedBrowser.currentURI.spec, "about:addons");
|
||||
|
||||
const VIEW = "addons://list/extension";
|
||||
yield promiseViewLoaded(tab, VIEW);
|
||||
let win = tab.linkedBrowser.contentWindow;
|
||||
ok(!win.gViewController.isLoading, "about:addons view is fully loaded");
|
||||
is(win.gViewController.currentViewId, VIEW, "about:addons is at extensions list");
|
||||
|
||||
// Wait for the permission prompt and cancel it
|
||||
let panel = yield popupPromise;
|
||||
panel.secondaryButton.click();
|
||||
|
||||
addon = yield AddonManager.getAddonByID(ID);
|
||||
is(addon.version, "1.0", "Should still be running the old version");
|
||||
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
|
||||
// Alert badge and hamburger menu items should be gone
|
||||
is(getBadgeStatus(), "", "Addon alert badge should be gone");
|
||||
|
||||
yield PanelUI.show();
|
||||
addons = document.getElementById("PanelUI-footer-addons");
|
||||
is(addons.children.length, 0, "Update menu entries should be gone");
|
||||
yield PanelUI.hide();
|
||||
|
||||
// Re-check for an update
|
||||
updatePromise = promiseUpdateDownloaded(addon);
|
||||
yield AddonManagerPrivate.backgroundUpdateCheck();
|
||||
yield updatePromise;
|
||||
|
||||
is(getBadgeStatus(), "addon-alert", "Should have addon alert badge");
|
||||
|
||||
// Find the menu entry for the update
|
||||
yield PanelUI.show();
|
||||
|
||||
addons = document.getElementById("PanelUI-footer-addons");
|
||||
is(addons.children.length, 1, "Have a menu entry for the update");
|
||||
|
||||
// Click the menu item
|
||||
tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:addons");
|
||||
popupPromise = promisePopupNotificationShown("addon-webext-permissions");
|
||||
addons.children[0].click();
|
||||
|
||||
// Wait for about:addons to load
|
||||
tab = yield tabPromise;
|
||||
is(tab.linkedBrowser.currentURI.spec, "about:addons");
|
||||
|
||||
yield promiseViewLoaded(tab, VIEW);
|
||||
win = tab.linkedBrowser.contentWindow;
|
||||
ok(!win.gViewController.isLoading, "about:addons view is fully loaded");
|
||||
is(win.gViewController.currentViewId, VIEW, "about:addons is at extensions list");
|
||||
|
||||
// Wait for the permission prompt and accept it this time
|
||||
updatePromise = promiseUpgrade(addon);
|
||||
panel = yield popupPromise;
|
||||
panel.button.click();
|
||||
|
||||
addon = yield updatePromise;
|
||||
is(addon.version, "2.0", "Should have upgraded to the new version");
|
||||
|
||||
yield BrowserTestUtils.removeTab(tab);
|
||||
|
||||
is(getBadgeStatus(), "", "Addon alert badge should be gone");
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"addons": {
|
||||
"update@tests.mozilla.org": {
|
||||
"updates": [
|
||||
{
|
||||
"version": "2.0",
|
||||
"update_link": "https://example.com/browser/browser/base/content/test/general/browser_webext_update2.xpi",
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"strict_min_version": "1",
|
||||
"advisory_max_version": "55.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -2,12 +2,28 @@
|
|||
# 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/.
|
||||
|
||||
allow = Allow
|
||||
allowForSession = Allow for Session
|
||||
allowTemporarily = Allow Temporarily
|
||||
block = Block
|
||||
blockTemporarily = Block Temporarily
|
||||
alwaysAsk = Always Ask
|
||||
# LOCALIZATION NOTE (state.current.allowed,
|
||||
# state.current.allowedForSession,
|
||||
# state.current.allowedTemporarily,
|
||||
# state.current.blockedTemporarily,
|
||||
# state.current.blocked):
|
||||
# This label is used to display active permission states in the site
|
||||
# identity popup (which does not have a lot of screen space).
|
||||
state.current.allowed = Allowed
|
||||
state.current.allowedForSession = Allowed for Session
|
||||
state.current.allowedTemporarily = Allowed Temporarily
|
||||
state.current.blockedTemporarily = Blocked Temporarily
|
||||
state.current.blocked = Blocked
|
||||
|
||||
# LOCALIZATION NOTE (state.multichoice.alwaysAsk,
|
||||
# state.multichoice.allow,
|
||||
# state.multichoice.allowForSession,
|
||||
# state.multichoice.block):
|
||||
# Used to label permission state checkboxes in the page info dialog.
|
||||
state.multichoice.alwaysAsk = Always Ask
|
||||
state.multichoice.allow = Allow
|
||||
state.multichoice.allowForSession = Allow for Session
|
||||
state.multichoice.block = Block
|
||||
|
||||
permission.cookie.label = Set Cookies
|
||||
permission.desktop-notification2.label = Receive Notifications
|
||||
|
|
|
@ -26,9 +26,11 @@ const HTML_NS = "http://www.w3.org/1999/xhtml";
|
|||
|
||||
this.ExtensionsUI = {
|
||||
sideloaded: new Set(),
|
||||
updates: new Set(),
|
||||
|
||||
init() {
|
||||
Services.obs.addObserver(this, "webextension-permission-prompt", false);
|
||||
Services.obs.addObserver(this, "webextension-update-permissions", false);
|
||||
|
||||
this._checkForSideloaded();
|
||||
},
|
||||
|
@ -60,11 +62,7 @@ this.ExtensionsUI = {
|
|||
});
|
||||
},
|
||||
|
||||
showSideloaded(browser, addon) {
|
||||
addon.markAsSeen();
|
||||
this.sideloaded.delete(addon);
|
||||
this.emit("change");
|
||||
|
||||
showAddonsManager(browser, info) {
|
||||
let loadPromise = new Promise(resolve => {
|
||||
let listener = (subject, topic) => {
|
||||
if (subject.location.href == "about:addons") {
|
||||
|
@ -76,16 +74,41 @@ this.ExtensionsUI = {
|
|||
});
|
||||
let tab = browser.addTab("about:addons");
|
||||
browser.selectedTab = tab;
|
||||
loadPromise.then(win => {
|
||||
|
||||
return loadPromise.then(win => {
|
||||
win.loadView("addons://list/extension");
|
||||
let info = {
|
||||
addon,
|
||||
icon: addon.iconURL,
|
||||
type: "sideload",
|
||||
};
|
||||
this.showPermissionsPrompt(browser.selectedBrowser, info).then(answer => {
|
||||
addon.userDisabled = !answer;
|
||||
});
|
||||
return this.showPermissionsPrompt(browser.selectedBrowser, info);
|
||||
});
|
||||
},
|
||||
|
||||
showSideloaded(browser, addon) {
|
||||
addon.markAsSeen();
|
||||
this.sideloaded.delete(addon);
|
||||
this.emit("change");
|
||||
|
||||
let info = {
|
||||
addon,
|
||||
permissions: addon.userPermissions,
|
||||
icon: addon.iconURL,
|
||||
type: "sideload",
|
||||
};
|
||||
this.showAddonsManager(browser, info).then(answer => {
|
||||
addon.userDisabled = !answer;
|
||||
});
|
||||
},
|
||||
|
||||
showUpdate(browser, info) {
|
||||
info.type = "update";
|
||||
this.showAddonsManager(browser, info).then(answer => {
|
||||
if (answer) {
|
||||
info.resolve();
|
||||
} else {
|
||||
info.reject();
|
||||
}
|
||||
// At the moment, this prompt will re-appear next time we do an update
|
||||
// check. See bug 1332360 for proposal to avoid this.
|
||||
this.updates.delete(info);
|
||||
this.emit("change");
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -101,15 +124,26 @@ this.ExtensionsUI = {
|
|||
progressNotification.remove();
|
||||
}
|
||||
|
||||
this.showPermissionsPrompt(target, info).then(answer => {
|
||||
let reply = answer => {
|
||||
Services.obs.notifyObservers(subject, "webextension-permission-response",
|
||||
JSON.stringify(answer));
|
||||
});
|
||||
};
|
||||
|
||||
let perms = info.addon.userPermissions;
|
||||
if (!perms) {
|
||||
reply(true);
|
||||
} else {
|
||||
info.permissions = perms;
|
||||
this.showPermissionsPrompt(target, info).then(reply);
|
||||
}
|
||||
} else if (topic == "webextension-update-permissions") {
|
||||
this.updates.add(subject.wrappedJSObject);
|
||||
this.emit("change");
|
||||
}
|
||||
},
|
||||
|
||||
showPermissionsPrompt(target, info) {
|
||||
let perms = info.addon.userPermissions;
|
||||
let perms = info.permissions;
|
||||
if (!perms) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
@ -147,6 +181,11 @@ this.ExtensionsUI = {
|
|||
acceptKey = "E";
|
||||
cancelText = "Disable";
|
||||
cancelKey = "D";
|
||||
} else if (info.type == "update") {
|
||||
header = "";
|
||||
text = `${name} has been updated. You must approve new permissions before the updated version will install.`;
|
||||
acceptText = "Update";
|
||||
acceptKey = "U";
|
||||
}
|
||||
|
||||
let formatPermission = perm => {
|
||||
|
|
|
@ -183,34 +183,6 @@ this.SitePermissions = {
|
|||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns detailed information on the specified permission.
|
||||
*
|
||||
* @param {String} id
|
||||
* The permissionID of the permission.
|
||||
* @param {SitePermissions scope} scope
|
||||
* The current scope of the permission.
|
||||
* @param {SitePermissions state} state (optional)
|
||||
* The current state of the permission.
|
||||
* Will default to the default state if omitted.
|
||||
*
|
||||
* @return {Object} an object with the keys:
|
||||
* - id: the permissionID of the permission
|
||||
* - label: the localized label
|
||||
* - state: the passed in state argument
|
||||
* - scope: the passed in scope argument
|
||||
* - availableStates: an array of all available states for that permission,
|
||||
* represented as objects with the keys:
|
||||
* - id: the state constant
|
||||
* - label: the translated label of that state
|
||||
*/
|
||||
getPermissionDetails(id, scope, state = this.getDefault(id)) {
|
||||
let availableStates = this.getAvailableStates(id).map(val => {
|
||||
return { id: val, label: this.getStateLabel(val) };
|
||||
});
|
||||
return {id, label: this.getPermissionLabel(id), state, scope, availableStates};
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns all custom permissions for a given browser.
|
||||
*
|
||||
|
@ -249,11 +221,17 @@ this.SitePermissions = {
|
|||
* @param {Browser} browser
|
||||
* The browser to fetch permission for.
|
||||
*
|
||||
* @return {Array} a list of objects. See getPermissionDetails for the content of each object.
|
||||
* @return {Array<Object>} a list of objects with the keys:
|
||||
* - id: the permissionID of the permission
|
||||
* - state: a constant representing the current permission state
|
||||
* (e.g. SitePermissions.ALLOW)
|
||||
* - scope: a constant representing how long the permission will
|
||||
* be kept.
|
||||
* - label: the localized label
|
||||
*/
|
||||
getAllPermissionDetailsForBrowser(browser) {
|
||||
return this.getAllForBrowser(browser).map(({id, scope, state}) =>
|
||||
this.getPermissionDetails(id, scope, state));
|
||||
({id, scope, state, label: this.getPermissionLabel(id)}));
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -489,29 +467,52 @@ this.SitePermissions = {
|
|||
*
|
||||
* @param {SitePermissions state} state
|
||||
* The state to get the label for.
|
||||
* @param {SitePermissions scope} scope (optional)
|
||||
* The scope to get the label for.
|
||||
*
|
||||
* @return {String} the localized label.
|
||||
* @return {String|null} the localized label or null if an
|
||||
* unknown state was passed.
|
||||
*/
|
||||
getStateLabel(state, scope = null) {
|
||||
getMultichoiceStateLabel(state) {
|
||||
switch (state) {
|
||||
case this.UNKNOWN:
|
||||
return gStringBundle.GetStringFromName("alwaysAsk");
|
||||
return gStringBundle.GetStringFromName("state.multichoice.alwaysAsk");
|
||||
case this.ALLOW:
|
||||
if (scope && scope != this.SCOPE_PERSISTENT)
|
||||
return gStringBundle.GetStringFromName("allowTemporarily");
|
||||
return gStringBundle.GetStringFromName("allow");
|
||||
return gStringBundle.GetStringFromName("state.multichoice.allow");
|
||||
case this.ALLOW_COOKIES_FOR_SESSION:
|
||||
return gStringBundle.GetStringFromName("allowForSession");
|
||||
return gStringBundle.GetStringFromName("state.multichoice.allowForSession");
|
||||
case this.BLOCK:
|
||||
if (scope && scope != this.SCOPE_PERSISTENT)
|
||||
return gStringBundle.GetStringFromName("blockTemporarily");
|
||||
return gStringBundle.GetStringFromName("block");
|
||||
return gStringBundle.GetStringFromName("state.multichoice.block");
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the localized label for a permission's current state.
|
||||
*
|
||||
* @param {SitePermissions state} state
|
||||
* The state to get the label for.
|
||||
* @param {SitePermissions scope} scope (optional)
|
||||
* The scope to get the label for.
|
||||
*
|
||||
* @return {String|null} the localized label or null if an
|
||||
* unknown state was passed.
|
||||
*/
|
||||
getCurrentStateLabel(state, scope = null) {
|
||||
switch (state) {
|
||||
case this.ALLOW:
|
||||
if (scope && scope != this.SCOPE_PERSISTENT)
|
||||
return gStringBundle.GetStringFromName("state.current.allowedTemporarily");
|
||||
return gStringBundle.GetStringFromName("state.current.allowed");
|
||||
case this.ALLOW_COOKIES_FOR_SESSION:
|
||||
return gStringBundle.GetStringFromName("state.current.allowedForSession");
|
||||
case this.BLOCK:
|
||||
if (scope && scope != this.SCOPE_PERSISTENT)
|
||||
return gStringBundle.GetStringFromName("state.current.blockedTemporarily");
|
||||
return gStringBundle.GetStringFromName("state.current.blocked");
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
var gPermissionObject = {
|
||||
|
|
|
@ -38,33 +38,21 @@ add_task(function* testGetAllPermissionDetailsForBrowser() {
|
|||
label: "Use the Camera",
|
||||
state: SitePermissions.ALLOW,
|
||||
scope: SitePermissions.SCOPE_PERSISTENT,
|
||||
availableStates: [
|
||||
{ id: SitePermissions.UNKNOWN, label: "Always Ask" },
|
||||
{ id: SitePermissions.ALLOW, label: "Allow" },
|
||||
{ id: SitePermissions.BLOCK, label: "Block" },
|
||||
]
|
||||
});
|
||||
|
||||
// check that removed permissions (State.UNKNOWN) are skipped
|
||||
// Check that removed permissions (State.UNKNOWN) are skipped.
|
||||
SitePermissions.remove(uri, "camera");
|
||||
permissions = SitePermissions.getAllPermissionDetailsForBrowser(tab.linkedBrowser);
|
||||
|
||||
camera = permissions.find(({id}) => id === "camera");
|
||||
Assert.equal(camera, undefined);
|
||||
|
||||
// check that different available state values are represented
|
||||
|
||||
let cookie = permissions.find(({id}) => id === "cookie");
|
||||
Assert.deepEqual(cookie, {
|
||||
id: "cookie",
|
||||
label: "Set Cookies",
|
||||
state: SitePermissions.ALLOW_COOKIES_FOR_SESSION,
|
||||
scope: SitePermissions.SCOPE_PERSISTENT,
|
||||
availableStates: [
|
||||
{ id: SitePermissions.ALLOW, label: "Allow" },
|
||||
{ id: SitePermissions.ALLOW_COOKIES_FOR_SESSION, label: "Allow for Session" },
|
||||
{ id: SitePermissions.BLOCK, label: "Block" },
|
||||
]
|
||||
});
|
||||
|
||||
let popup = permissions.find(({id}) => id === "popup");
|
||||
|
@ -73,10 +61,6 @@ add_task(function* testGetAllPermissionDetailsForBrowser() {
|
|||
label: "Open Pop-up Windows",
|
||||
state: SitePermissions.BLOCK,
|
||||
scope: SitePermissions.SCOPE_PERSISTENT,
|
||||
availableStates: [
|
||||
{ id: SitePermissions.ALLOW, label: "Allow" },
|
||||
{ id: SitePermissions.BLOCK, label: "Block" },
|
||||
]
|
||||
});
|
||||
|
||||
let geo = permissions.find(({id}) => id === "geo");
|
||||
|
@ -85,11 +69,6 @@ add_task(function* testGetAllPermissionDetailsForBrowser() {
|
|||
label: "Access Your Location",
|
||||
state: SitePermissions.ALLOW,
|
||||
scope: SitePermissions.SCOPE_SESSION,
|
||||
availableStates: [
|
||||
{ id: SitePermissions.UNKNOWN, label: "Always Ask" },
|
||||
{ id: SitePermissions.ALLOW, label: "Allow" },
|
||||
{ id: SitePermissions.BLOCK, label: "Block" },
|
||||
]
|
||||
});
|
||||
|
||||
SitePermissions.remove(uri, "cookie");
|
||||
|
|
|
@ -51,3 +51,19 @@ add_task(function* testGetAllByURI() {
|
|||
Assert.deepEqual(SitePermissions.getAllByURI(uri), []);
|
||||
SitePermissions.remove(uri, "addon");
|
||||
});
|
||||
|
||||
add_task(function* testGetAvailableStates() {
|
||||
Assert.deepEqual(SitePermissions.getAvailableStates("camera"),
|
||||
[ SitePermissions.UNKNOWN,
|
||||
SitePermissions.ALLOW,
|
||||
SitePermissions.BLOCK ]);
|
||||
|
||||
Assert.deepEqual(SitePermissions.getAvailableStates("cookie"),
|
||||
[ SitePermissions.ALLOW,
|
||||
SitePermissions.ALLOW_COOKIES_FOR_SESSION,
|
||||
SitePermissions.BLOCK ]);
|
||||
|
||||
Assert.deepEqual(SitePermissions.getAvailableStates("popup"),
|
||||
[ SitePermissions.ALLOW,
|
||||
SitePermissions.BLOCK ]);
|
||||
});
|
||||
|
|
|
@ -8930,7 +8930,7 @@ nsGlobalWindow::EnterModalState()
|
|||
|
||||
topWin->mSuspendedDoc = topDoc;
|
||||
if (topDoc) {
|
||||
topDoc->SuppressEventHandling(nsIDocument::eEvents);
|
||||
topDoc->SuppressEventHandling(nsIDocument::eAnimationsOnly);
|
||||
}
|
||||
|
||||
nsGlobalWindow* inner = topWin->GetCurrentInnerWindowInternal();
|
||||
|
@ -8967,7 +8967,7 @@ nsGlobalWindow::LeaveModalState()
|
|||
|
||||
if (topWin->mSuspendedDoc) {
|
||||
nsCOMPtr<nsIDocument> currentDoc = topWin->GetExtantDoc();
|
||||
topWin->mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eEvents,
|
||||
topWin->mSuspendedDoc->UnsuppressEventHandlingAndFireEvents(nsIDocument::eAnimationsOnly,
|
||||
currentDoc == topWin->mSuspendedDoc);
|
||||
topWin->mSuspendedDoc = nullptr;
|
||||
}
|
||||
|
|
|
@ -1277,56 +1277,11 @@ EventStateManager::IsRemoteTarget(nsIContent* target) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
CrossProcessSafeEvent(const WidgetEvent& aEvent)
|
||||
{
|
||||
switch (aEvent.mClass) {
|
||||
case eKeyboardEventClass:
|
||||
case eWheelEventClass:
|
||||
return true;
|
||||
case eMouseEventClass:
|
||||
switch (aEvent.mMessage) {
|
||||
case eMouseDown:
|
||||
case eMouseUp:
|
||||
case eMouseMove:
|
||||
case eContextMenu:
|
||||
case eMouseEnterIntoWidget:
|
||||
case eMouseExitFromWidget:
|
||||
case eMouseTouchDrag:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
case eTouchEventClass:
|
||||
switch (aEvent.mMessage) {
|
||||
case eTouchStart:
|
||||
case eTouchMove:
|
||||
case eTouchEnd:
|
||||
case eTouchCancel:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
case eDragEventClass:
|
||||
switch (aEvent.mMessage) {
|
||||
case eDragOver:
|
||||
case eDragExit:
|
||||
case eDrop:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
EventStateManager::HandleCrossProcessEvent(WidgetEvent* aEvent,
|
||||
nsEventStatus *aStatus) {
|
||||
if (*aStatus == nsEventStatus_eConsumeNoDefault ||
|
||||
aEvent->mFlags.mNoCrossProcessBoundaryForwarding ||
|
||||
!CrossProcessSafeEvent(*aEvent)) {
|
||||
!aEvent->CanBeSentToRemoteProcess()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1566,9 +1566,11 @@ TabChild::RecvMouseEvent(const nsString& aType,
|
|||
const int32_t& aModifiers,
|
||||
const bool& aIgnoreRootScrollFrame)
|
||||
{
|
||||
APZCCallbackHelper::DispatchMouseEvent(GetPresShell(), aType, CSSPoint(aX, aY),
|
||||
aButton, aClickCount, aModifiers, aIgnoreRootScrollFrame,
|
||||
nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN, 0 /* Use the default value here. */);
|
||||
APZCCallbackHelper::DispatchMouseEvent(GetPresShell(), aType,
|
||||
CSSPoint(aX, aY), aButton, aClickCount,
|
||||
aModifiers, aIgnoreRootScrollFrame,
|
||||
nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN,
|
||||
0 /* Use the default value here. */);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -1603,13 +1605,15 @@ TabChild::RecvRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
|
|||
// process EventStateManager code, have an input block id which they get from
|
||||
// the InputAPZContext in the parent process stack. However, they did not
|
||||
// actually go through the APZ code and so their mHandledByAPZ flag is false.
|
||||
// Since thos events didn't go through APZ, we don't need to send notifications
|
||||
// for them.
|
||||
// Since thos events didn't go through APZ, we don't need to send
|
||||
// notifications for them.
|
||||
bool pendingLayerization = false;
|
||||
if (aInputBlockId && aEvent.mFlags.mHandledByAPZ) {
|
||||
nsCOMPtr<nsIDocument> document(GetDocument());
|
||||
pendingLayerization = APZCCallbackHelper::SendSetTargetAPZCNotification(
|
||||
mPuppetWidget, document, aEvent, aGuid, aInputBlockId);
|
||||
pendingLayerization =
|
||||
APZCCallbackHelper::SendSetTargetAPZCNotification(mPuppetWidget, document,
|
||||
aEvent, aGuid,
|
||||
aInputBlockId);
|
||||
}
|
||||
|
||||
nsEventStatus unused;
|
||||
|
@ -1644,7 +1648,7 @@ TabChild::RecvMouseWheelEvent(const WidgetWheelEvent& aEvent,
|
|||
WidgetWheelEvent localEvent(aEvent);
|
||||
localEvent.mWidget = mPuppetWidget;
|
||||
APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
|
||||
mPuppetWidget->GetDefaultScale());
|
||||
mPuppetWidget->GetDefaultScale());
|
||||
APZCCallbackHelper::DispatchWidgetEvent(localEvent);
|
||||
|
||||
if (localEvent.mCanTriggerSwipe) {
|
||||
|
@ -1669,16 +1673,18 @@ TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
|
|||
localEvent.mWidget = mPuppetWidget;
|
||||
|
||||
APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
|
||||
mPuppetWidget->GetDefaultScale());
|
||||
mPuppetWidget->GetDefaultScale());
|
||||
|
||||
if (localEvent.mMessage == eTouchStart && AsyncPanZoomEnabled()) {
|
||||
nsCOMPtr<nsIDocument> document = GetDocument();
|
||||
if (gfxPrefs::TouchActionEnabled()) {
|
||||
APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(mPuppetWidget,
|
||||
document, localEvent, aInputBlockId, mSetAllowedTouchBehaviorCallback);
|
||||
APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(
|
||||
mPuppetWidget, document, localEvent, aInputBlockId,
|
||||
mSetAllowedTouchBehaviorCallback);
|
||||
}
|
||||
APZCCallbackHelper::SendSetTargetAPZCNotification(mPuppetWidget, document,
|
||||
localEvent, aGuid, aInputBlockId);
|
||||
localEvent, aGuid,
|
||||
aInputBlockId);
|
||||
}
|
||||
|
||||
// Dispatch event to content (potentially a long-running operation)
|
||||
|
@ -1692,7 +1698,7 @@ TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
|
|||
}
|
||||
|
||||
mAPZEventState->ProcessTouchEvent(localEvent, aGuid, aInputBlockId,
|
||||
aApzResponse, status);
|
||||
aApzResponse, status);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -1782,7 +1788,8 @@ mozilla::ipc::IPCResult
|
|||
TabChild::RecvNativeSynthesisResponse(const uint64_t& aObserverId,
|
||||
const nsCString& aResponse)
|
||||
{
|
||||
mozilla::widget::AutoObserverNotifier::NotifySavedObserver(aObserverId, aResponse.get());
|
||||
mozilla::widget::AutoObserverNotifier::NotifySavedObserver(aObserverId,
|
||||
aResponse.get());
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -1825,16 +1832,16 @@ TabChild::UpdateRepeatedKeyEventEndTime(const WidgetKeyboardEvent& aEvent)
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvRealKeyEvent(const WidgetKeyboardEvent& event,
|
||||
TabChild::RecvRealKeyEvent(const WidgetKeyboardEvent& aEvent,
|
||||
const MaybeNativeKeyBinding& aBindings)
|
||||
{
|
||||
if (SkipRepeatedKeyEvent(event)) {
|
||||
if (SkipRepeatedKeyEvent(aEvent)) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
AutoCacheNativeKeyCommands autoCache(mPuppetWidget);
|
||||
|
||||
if (event.mMessage == eKeyPress) {
|
||||
if (aEvent.mMessage == eKeyPress) {
|
||||
// If content code called preventDefault() on a keydown event, then we don't
|
||||
// want to process any following keypress events.
|
||||
if (mIgnoreKeyPressEvent) {
|
||||
|
@ -1850,7 +1857,7 @@ TabChild::RecvRealKeyEvent(const WidgetKeyboardEvent& event,
|
|||
}
|
||||
}
|
||||
|
||||
WidgetKeyboardEvent localEvent(event);
|
||||
WidgetKeyboardEvent localEvent(aEvent);
|
||||
localEvent.mWidget = mPuppetWidget;
|
||||
nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
|
||||
|
||||
|
@ -1858,7 +1865,7 @@ TabChild::RecvRealKeyEvent(const WidgetKeyboardEvent& event,
|
|||
// some incoming events in case event handling took long time.
|
||||
UpdateRepeatedKeyEventEndTime(localEvent);
|
||||
|
||||
if (event.mMessage == eKeyDown) {
|
||||
if (aEvent.mMessage == eKeyDown) {
|
||||
mIgnoreKeyPressEvent = status == nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
||||
|
@ -1894,22 +1901,22 @@ TabChild::RecvKeyEvent(const nsString& aType,
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvCompositionEvent(const WidgetCompositionEvent& event)
|
||||
TabChild::RecvCompositionEvent(const WidgetCompositionEvent& aEvent)
|
||||
{
|
||||
WidgetCompositionEvent localEvent(event);
|
||||
WidgetCompositionEvent localEvent(aEvent);
|
||||
localEvent.mWidget = mPuppetWidget;
|
||||
APZCCallbackHelper::DispatchWidgetEvent(localEvent);
|
||||
Unused << SendOnEventNeedingAckHandled(event.mMessage);
|
||||
Unused << SendOnEventNeedingAckHandled(aEvent.mMessage);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabChild::RecvSelectionEvent(const WidgetSelectionEvent& event)
|
||||
TabChild::RecvSelectionEvent(const WidgetSelectionEvent& aEvent)
|
||||
{
|
||||
WidgetSelectionEvent localEvent(event);
|
||||
WidgetSelectionEvent localEvent(aEvent);
|
||||
localEvent.mWidget = mPuppetWidget;
|
||||
APZCCallbackHelper::DispatchWidgetEvent(localEvent);
|
||||
Unused << SendOnEventNeedingAckHandled(event.mMessage);
|
||||
Unused << SendOnEventNeedingAckHandled(aEvent.mMessage);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -1935,7 +1942,8 @@ TabChild::RecvPasteTransferable(const IPCDataTransfer& aDataTransfer,
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICommandParams> params = do_CreateInstance("@mozilla.org/embedcomp/command-params;1", &rv);
|
||||
nsCOMPtr<nsICommandParams> params =
|
||||
do_CreateInstance("@mozilla.org/embedcomp/command-params;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, IPC_OK());
|
||||
|
||||
rv = params->SetISupportsValue("transferable", trans);
|
||||
|
|
|
@ -1058,7 +1058,8 @@ TabParent::SendMouseEvent(const nsAString& aType, float aX, float aY,
|
|||
if (!mIsDestroyed) {
|
||||
Unused << PBrowserParent::SendMouseEvent(nsString(aType), aX, aY,
|
||||
aButton, aClickCount,
|
||||
aModifiers, aIgnoreRootScrollFrame);
|
||||
aModifiers,
|
||||
aIgnoreRootScrollFrame);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1069,31 +1070,34 @@ TabParent::SendKeyEvent(const nsAString& aType,
|
|||
int32_t aModifiers,
|
||||
bool aPreventDefault)
|
||||
{
|
||||
if (!mIsDestroyed) {
|
||||
Unused << PBrowserParent::SendKeyEvent(nsString(aType), aKeyCode, aCharCode,
|
||||
aModifiers, aPreventDefault);
|
||||
if (mIsDestroyed) {
|
||||
return;
|
||||
}
|
||||
Unused << PBrowserParent::SendKeyEvent(nsString(aType), aKeyCode, aCharCode,
|
||||
aModifiers, aPreventDefault);
|
||||
}
|
||||
|
||||
bool TabParent::SendRealMouseEvent(WidgetMouseEvent& event)
|
||||
bool
|
||||
TabParent::SendRealMouseEvent(WidgetMouseEvent& aEvent)
|
||||
{
|
||||
if (mIsDestroyed) {
|
||||
return false;
|
||||
}
|
||||
event.mRefPoint += GetChildProcessOffset();
|
||||
aEvent.mRefPoint += GetChildProcessOffset();
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget) {
|
||||
// When we mouseenter the tab, the tab's cursor should
|
||||
// become the current cursor. When we mouseexit, we stop.
|
||||
if (eMouseEnterIntoWidget == event.mMessage) {
|
||||
if (eMouseEnterIntoWidget == aEvent.mMessage) {
|
||||
mTabSetsCursor = true;
|
||||
if (mCustomCursor) {
|
||||
widget->SetCursor(mCustomCursor, mCustomCursorHotspotX, mCustomCursorHotspotY);
|
||||
widget->SetCursor(mCustomCursor,
|
||||
mCustomCursorHotspotX, mCustomCursorHotspotY);
|
||||
} else if (mCursor != nsCursor(-1)) {
|
||||
widget->SetCursor(mCursor);
|
||||
}
|
||||
} else if (eMouseExitFromWidget == event.mMessage) {
|
||||
} else if (eMouseExitFromWidget == aEvent.mMessage) {
|
||||
mTabSetsCursor = false;
|
||||
}
|
||||
}
|
||||
|
@ -1102,15 +1106,15 @@ bool TabParent::SendRealMouseEvent(WidgetMouseEvent& event)
|
|||
uint64_t blockId;
|
||||
ApzAwareEventRoutingToChild(&guid, &blockId, nullptr);
|
||||
|
||||
if (eMouseMove == event.mMessage) {
|
||||
if (event.mReason == WidgetMouseEvent::eSynthesized) {
|
||||
return SendSynthMouseMoveEvent(event, guid, blockId);
|
||||
if (eMouseMove == aEvent.mMessage) {
|
||||
if (aEvent.mReason == WidgetMouseEvent::eSynthesized) {
|
||||
return SendSynthMouseMoveEvent(aEvent, guid, blockId);
|
||||
} else {
|
||||
return SendRealMouseMoveEvent(event, guid, blockId);
|
||||
return SendRealMouseMoveEvent(aEvent, guid, blockId);
|
||||
}
|
||||
}
|
||||
|
||||
return SendRealMouseButtonEvent(event, guid, blockId);
|
||||
return SendRealMouseButtonEvent(aEvent, guid, blockId);
|
||||
}
|
||||
|
||||
LayoutDeviceToCSSScale
|
||||
|
@ -1126,22 +1130,24 @@ TabParent::GetLayoutDeviceToCSSScale()
|
|||
}
|
||||
|
||||
bool
|
||||
TabParent::SendRealDragEvent(WidgetDragEvent& event, uint32_t aDragAction,
|
||||
TabParent::SendRealDragEvent(WidgetDragEvent& aEvent, uint32_t aDragAction,
|
||||
uint32_t aDropEffect)
|
||||
{
|
||||
if (mIsDestroyed) {
|
||||
return false;
|
||||
}
|
||||
event.mRefPoint += GetChildProcessOffset();
|
||||
return PBrowserParent::SendRealDragEvent(event, aDragAction, aDropEffect);
|
||||
aEvent.mRefPoint += GetChildProcessOffset();
|
||||
return PBrowserParent::SendRealDragEvent(aEvent, aDragAction, aDropEffect);
|
||||
}
|
||||
|
||||
LayoutDevicePoint TabParent::AdjustTapToChildWidget(const LayoutDevicePoint& aPoint)
|
||||
LayoutDevicePoint
|
||||
TabParent::AdjustTapToChildWidget(const LayoutDevicePoint& aPoint)
|
||||
{
|
||||
return aPoint + LayoutDevicePoint(GetChildProcessOffset());
|
||||
}
|
||||
|
||||
bool TabParent::SendMouseWheelEvent(WidgetWheelEvent& event)
|
||||
bool
|
||||
TabParent::SendMouseWheelEvent(WidgetWheelEvent& aEvent)
|
||||
{
|
||||
if (mIsDestroyed) {
|
||||
return false;
|
||||
|
@ -1150,8 +1156,8 @@ bool TabParent::SendMouseWheelEvent(WidgetWheelEvent& event)
|
|||
ScrollableLayerGuid guid;
|
||||
uint64_t blockId;
|
||||
ApzAwareEventRoutingToChild(&guid, &blockId, nullptr);
|
||||
event.mRefPoint += GetChildProcessOffset();
|
||||
return PBrowserParent::SendMouseWheelEvent(event, guid, blockId);
|
||||
aEvent.mRefPoint += GetChildProcessOffset();
|
||||
return PBrowserParent::SendMouseWheelEvent(aEvent, guid, blockId);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
|
@ -1205,7 +1211,8 @@ TabParent::RecvDispatchKeyboardEvent(const mozilla::WidgetKeyboardEvent& aEvent)
|
|||
static void
|
||||
DoCommandCallback(mozilla::Command aCommand, void* aData)
|
||||
{
|
||||
static_cast<InfallibleTArray<mozilla::CommandInt>*>(aData)->AppendElement(aCommand);
|
||||
static_cast<InfallibleTArray<mozilla::CommandInt>*>(aData)->
|
||||
AppendElement(aCommand);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
|
@ -1229,12 +1236,15 @@ TabParent::RecvRequestNativeKeyBindings(const WidgetKeyboardEvent& aEvent,
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForSingleLineEditor,
|
||||
localEvent, DoCommandCallback, &singleLine);
|
||||
widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForMultiLineEditor,
|
||||
localEvent, DoCommandCallback, &multiLine);
|
||||
widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForRichTextEditor,
|
||||
localEvent, DoCommandCallback, &richText);
|
||||
widget->ExecuteNativeKeyBinding(
|
||||
nsIWidget::NativeKeyBindingsForSingleLineEditor,
|
||||
localEvent, DoCommandCallback, &singleLine);
|
||||
widget->ExecuteNativeKeyBinding(
|
||||
nsIWidget::NativeKeyBindingsForMultiLineEditor,
|
||||
localEvent, DoCommandCallback, &multiLine);
|
||||
widget->ExecuteNativeKeyBinding(
|
||||
nsIWidget::NativeKeyBindingsForRichTextEditor,
|
||||
localEvent, DoCommandCallback, &richText);
|
||||
|
||||
if (!singleLine.IsEmpty() || !multiLine.IsEmpty() || !richText.IsEmpty()) {
|
||||
*aBindings = NativeKeyBinding(singleLine, multiLine, richText);
|
||||
|
@ -1265,7 +1275,8 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!mTabParent->SendNativeSynthesisResponse(mObserverId, nsCString(aTopic))) {
|
||||
if (!mTabParent->SendNativeSynthesisResponse(mObserverId,
|
||||
nsCString(aTopic))) {
|
||||
NS_WARNING("Unable to send native event synthesization response!");
|
||||
}
|
||||
// Null out tabparent to indicate we already sent the response
|
||||
|
@ -1320,8 +1331,9 @@ TabParent::RecvSynthesizeNativeKeyEvent(const int32_t& aNativeKeyboardLayout,
|
|||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget) {
|
||||
widget->SynthesizeNativeKeyEvent(aNativeKeyboardLayout, aNativeKeyCode,
|
||||
aModifierFlags, aCharacters, aUnmodifiedCharacters,
|
||||
responder.GetObserver());
|
||||
aModifierFlags, aCharacters,
|
||||
aUnmodifiedCharacters,
|
||||
responder.GetObserver());
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -1336,7 +1348,7 @@ TabParent::RecvSynthesizeNativeMouseEvent(const LayoutDeviceIntPoint& aPoint,
|
|||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget) {
|
||||
widget->SynthesizeNativeMouseEvent(aPoint, aNativeMessage, aModifierFlags,
|
||||
responder.GetObserver());
|
||||
responder.GetObserver());
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -1354,38 +1366,42 @@ TabParent::RecvSynthesizeNativeMouseMove(const LayoutDeviceIntPoint& aPoint,
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabParent::RecvSynthesizeNativeMouseScrollEvent(const LayoutDeviceIntPoint& aPoint,
|
||||
const uint32_t& aNativeMessage,
|
||||
const double& aDeltaX,
|
||||
const double& aDeltaY,
|
||||
const double& aDeltaZ,
|
||||
const uint32_t& aModifierFlags,
|
||||
const uint32_t& aAdditionalFlags,
|
||||
const uint64_t& aObserverId)
|
||||
TabParent::RecvSynthesizeNativeMouseScrollEvent(
|
||||
const LayoutDeviceIntPoint& aPoint,
|
||||
const uint32_t& aNativeMessage,
|
||||
const double& aDeltaX,
|
||||
const double& aDeltaY,
|
||||
const double& aDeltaZ,
|
||||
const uint32_t& aModifierFlags,
|
||||
const uint32_t& aAdditionalFlags,
|
||||
const uint64_t& aObserverId)
|
||||
{
|
||||
AutoSynthesizedEventResponder responder(this, aObserverId, "mousescrollevent");
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget) {
|
||||
widget->SynthesizeNativeMouseScrollEvent(aPoint, aNativeMessage,
|
||||
aDeltaX, aDeltaY, aDeltaZ, aModifierFlags, aAdditionalFlags,
|
||||
responder.GetObserver());
|
||||
aDeltaX, aDeltaY, aDeltaZ,
|
||||
aModifierFlags, aAdditionalFlags,
|
||||
responder.GetObserver());
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabParent::RecvSynthesizeNativeTouchPoint(const uint32_t& aPointerId,
|
||||
const TouchPointerState& aPointerState,
|
||||
const LayoutDeviceIntPoint& aPoint,
|
||||
const double& aPointerPressure,
|
||||
const uint32_t& aPointerOrientation,
|
||||
const uint64_t& aObserverId)
|
||||
TabParent::RecvSynthesizeNativeTouchPoint(
|
||||
const uint32_t& aPointerId,
|
||||
const TouchPointerState& aPointerState,
|
||||
const LayoutDeviceIntPoint& aPoint,
|
||||
const double& aPointerPressure,
|
||||
const uint32_t& aPointerOrientation,
|
||||
const uint64_t& aObserverId)
|
||||
{
|
||||
AutoSynthesizedEventResponder responder(this, aObserverId, "touchpoint");
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget) {
|
||||
widget->SynthesizeNativeTouchPoint(aPointerId, aPointerState, aPoint,
|
||||
aPointerPressure, aPointerOrientation, responder.GetObserver());
|
||||
aPointerPressure, aPointerOrientation,
|
||||
responder.GetObserver());
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -1414,38 +1430,43 @@ TabParent::RecvClearNativeTouchSequence(const uint64_t& aObserverId)
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
bool TabParent::SendRealKeyEvent(WidgetKeyboardEvent& event)
|
||||
bool
|
||||
TabParent::SendRealKeyEvent(WidgetKeyboardEvent& aEvent)
|
||||
{
|
||||
if (mIsDestroyed) {
|
||||
return false;
|
||||
}
|
||||
event.mRefPoint += GetChildProcessOffset();
|
||||
aEvent.mRefPoint += GetChildProcessOffset();
|
||||
|
||||
MaybeNativeKeyBinding bindings;
|
||||
bindings = void_t();
|
||||
if (event.mMessage == eKeyPress) {
|
||||
if (aEvent.mMessage == eKeyPress) {
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
|
||||
AutoTArray<mozilla::CommandInt, 4> singleLine;
|
||||
AutoTArray<mozilla::CommandInt, 4> multiLine;
|
||||
AutoTArray<mozilla::CommandInt, 4> richText;
|
||||
|
||||
widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForSingleLineEditor,
|
||||
event, DoCommandCallback, &singleLine);
|
||||
widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForMultiLineEditor,
|
||||
event, DoCommandCallback, &multiLine);
|
||||
widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForRichTextEditor,
|
||||
event, DoCommandCallback, &richText);
|
||||
widget->ExecuteNativeKeyBinding(
|
||||
nsIWidget::NativeKeyBindingsForSingleLineEditor,
|
||||
aEvent, DoCommandCallback, &singleLine);
|
||||
widget->ExecuteNativeKeyBinding(
|
||||
nsIWidget::NativeKeyBindingsForMultiLineEditor,
|
||||
aEvent, DoCommandCallback, &multiLine);
|
||||
widget->ExecuteNativeKeyBinding(
|
||||
nsIWidget::NativeKeyBindingsForRichTextEditor,
|
||||
aEvent, DoCommandCallback, &richText);
|
||||
|
||||
if (!singleLine.IsEmpty() || !multiLine.IsEmpty() || !richText.IsEmpty()) {
|
||||
bindings = NativeKeyBinding(singleLine, multiLine, richText);
|
||||
}
|
||||
}
|
||||
|
||||
return PBrowserParent::SendRealKeyEvent(event, bindings);
|
||||
return PBrowserParent::SendRealKeyEvent(aEvent, bindings);
|
||||
}
|
||||
|
||||
bool TabParent::SendRealTouchEvent(WidgetTouchEvent& event)
|
||||
bool
|
||||
TabParent::SendRealTouchEvent(WidgetTouchEvent& aEvent)
|
||||
{
|
||||
if (mIsDestroyed) {
|
||||
return false;
|
||||
|
@ -1455,10 +1476,10 @@ bool TabParent::SendRealTouchEvent(WidgetTouchEvent& event)
|
|||
// confuses remote content and the panning and zooming logic into thinking
|
||||
// that the added touches are part of the touchend/cancel, when actually
|
||||
// they're not.
|
||||
if (event.mMessage == eTouchEnd || event.mMessage == eTouchCancel) {
|
||||
for (int i = event.mTouches.Length() - 1; i >= 0; i--) {
|
||||
if (!event.mTouches[i]->mChanged) {
|
||||
event.mTouches.RemoveElementAt(i);
|
||||
if (aEvent.mMessage == eTouchEnd || aEvent.mMessage == eTouchCancel) {
|
||||
for (int i = aEvent.mTouches.Length() - 1; i >= 0; i--) {
|
||||
if (!aEvent.mTouches[i]->mChanged) {
|
||||
aEvent.mTouches.RemoveElementAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1473,13 +1494,13 @@ bool TabParent::SendRealTouchEvent(WidgetTouchEvent& event)
|
|||
}
|
||||
|
||||
LayoutDeviceIntPoint offset = GetChildProcessOffset();
|
||||
for (uint32_t i = 0; i < event.mTouches.Length(); i++) {
|
||||
event.mTouches[i]->mRefPoint += offset;
|
||||
for (uint32_t i = 0; i < aEvent.mTouches.Length(); i++) {
|
||||
aEvent.mTouches[i]->mRefPoint += offset;
|
||||
}
|
||||
|
||||
return (event.mMessage == eTouchMove) ?
|
||||
PBrowserParent::SendRealTouchMoveEvent(event, guid, blockId, apzResponse) :
|
||||
PBrowserParent::SendRealTouchEvent(event, guid, blockId, apzResponse);
|
||||
return (aEvent.mMessage == eTouchMove) ?
|
||||
PBrowserParent::SendRealTouchMoveEvent(aEvent, guid, blockId, apzResponse) :
|
||||
PBrowserParent::SendRealTouchEvent(aEvent, guid, blockId, apzResponse);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1497,8 +1518,8 @@ TabParent::SendHandleTap(TapType aType,
|
|||
GetRenderFrame()->TakeFocusForClickFromTap();
|
||||
}
|
||||
LayoutDeviceIntPoint offset = GetChildProcessOffset();
|
||||
return PBrowserParent::SendHandleTap(aType, aPoint + offset, aModifiers, aGuid,
|
||||
aInputBlockId);
|
||||
return PBrowserParent::SendHandleTap(aType, aPoint + offset, aModifiers,
|
||||
aGuid, aInputBlockId);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
|
@ -1705,13 +1726,14 @@ TabParent::RecvNotifyIMETextChange(const ContentCache& aContentCache,
|
|||
const IMENotification& aIMENotification)
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget)
|
||||
if (!widget) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
nsIMEUpdatePreference updatePreference = widget->GetIMEUpdatePreference();
|
||||
NS_ASSERTION(updatePreference.WantTextChange(),
|
||||
"Don't call Send/RecvNotifyIMETextChange without NOTIFY_TEXT_CHANGE");
|
||||
"Don't call Send/RecvNotifyIMETextChange without NOTIFY_TEXT_CHANGE");
|
||||
#endif
|
||||
|
||||
mContentCache.AssignContent(aContentCache, widget, &aIMENotification);
|
||||
|
@ -1728,7 +1750,6 @@ TabParent::RecvNotifyIMECompositionUpdate(
|
|||
if (!widget) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mContentCache.AssignContent(aContentCache, widget, &aIMENotification);
|
||||
mContentCache.MaybeNotifyIME(widget, aIMENotification);
|
||||
return IPC_OK();
|
||||
|
@ -1739,9 +1760,9 @@ TabParent::RecvNotifyIMESelection(const ContentCache& aContentCache,
|
|||
const IMENotification& aIMENotification)
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget)
|
||||
if (!widget) {
|
||||
return IPC_OK();
|
||||
|
||||
}
|
||||
mContentCache.AssignContent(aContentCache, widget, &aIMENotification);
|
||||
mContentCache.MaybeNotifyIME(widget, aIMENotification);
|
||||
return IPC_OK();
|
||||
|
@ -1783,7 +1804,6 @@ TabParent::RecvNotifyIMEPositionChange(const ContentCache& aContentCache,
|
|||
if (!widget) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mContentCache.AssignContent(aContentCache, widget, &aIMENotification);
|
||||
mContentCache.MaybeNotifyIME(widget, aIMENotification);
|
||||
return IPC_OK();
|
||||
|
@ -1940,11 +1960,11 @@ TabParent::GetChildProcessOffset()
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
TabParent::RecvReplyKeyEvent(const WidgetKeyboardEvent& event)
|
||||
TabParent::RecvReplyKeyEvent(const WidgetKeyboardEvent& aEvent)
|
||||
{
|
||||
NS_ENSURE_TRUE(mFrameElement, IPC_OK());
|
||||
|
||||
WidgetKeyboardEvent localEvent(event);
|
||||
WidgetKeyboardEvent localEvent(aEvent);
|
||||
// Mark the event as not to be dispatched to remote process again.
|
||||
localEvent.StopCrossProcessForwarding();
|
||||
|
||||
|
@ -2012,20 +2032,20 @@ TabParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent)
|
|||
}
|
||||
|
||||
bool
|
||||
TabParent::SendCompositionEvent(WidgetCompositionEvent& event)
|
||||
TabParent::SendCompositionEvent(WidgetCompositionEvent& aEvent)
|
||||
{
|
||||
if (mIsDestroyed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mContentCache.OnCompositionEvent(event)) {
|
||||
if (!mContentCache.OnCompositionEvent(aEvent)) {
|
||||
return true;
|
||||
}
|
||||
return PBrowserParent::SendCompositionEvent(event);
|
||||
return PBrowserParent::SendCompositionEvent(aEvent);
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::SendSelectionEvent(WidgetSelectionEvent& event)
|
||||
TabParent::SendSelectionEvent(WidgetSelectionEvent& aEvent)
|
||||
{
|
||||
if (mIsDestroyed) {
|
||||
return false;
|
||||
|
@ -2034,11 +2054,11 @@ TabParent::SendSelectionEvent(WidgetSelectionEvent& event)
|
|||
if (!widget) {
|
||||
return true;
|
||||
}
|
||||
mContentCache.OnSelectionEvent(event);
|
||||
if (NS_WARN_IF(!PBrowserParent::SendSelectionEvent(event))) {
|
||||
mContentCache.OnSelectionEvent(aEvent);
|
||||
if (NS_WARN_IF(!PBrowserParent::SendSelectionEvent(aEvent))) {
|
||||
return false;
|
||||
}
|
||||
event.mSucceeded = true;
|
||||
aEvent.mSucceeded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -454,17 +454,17 @@ public:
|
|||
int32_t aCharCode, int32_t aModifiers,
|
||||
bool aPreventDefault);
|
||||
|
||||
bool SendRealMouseEvent(mozilla::WidgetMouseEvent& event);
|
||||
bool SendRealMouseEvent(mozilla::WidgetMouseEvent& aEvent);
|
||||
|
||||
bool SendRealDragEvent(mozilla::WidgetDragEvent& aEvent,
|
||||
uint32_t aDragAction,
|
||||
uint32_t aDropEffect);
|
||||
|
||||
bool SendMouseWheelEvent(mozilla::WidgetWheelEvent& event);
|
||||
bool SendMouseWheelEvent(mozilla::WidgetWheelEvent& aEvent);
|
||||
|
||||
bool SendRealKeyEvent(mozilla::WidgetKeyboardEvent& event);
|
||||
bool SendRealKeyEvent(mozilla::WidgetKeyboardEvent& aEvent);
|
||||
|
||||
bool SendRealTouchEvent(WidgetTouchEvent& event);
|
||||
bool SendRealTouchEvent(WidgetTouchEvent& aEvent);
|
||||
|
||||
bool SendHandleTap(TapType aType,
|
||||
const LayoutDevicePoint& aPoint,
|
||||
|
@ -512,9 +512,9 @@ public:
|
|||
|
||||
bool HandleQueryContentEvent(mozilla::WidgetQueryContentEvent& aEvent);
|
||||
|
||||
bool SendCompositionEvent(mozilla::WidgetCompositionEvent& event);
|
||||
bool SendCompositionEvent(mozilla::WidgetCompositionEvent& aEvent);
|
||||
|
||||
bool SendSelectionEvent(mozilla::WidgetSelectionEvent& event);
|
||||
bool SendSelectionEvent(mozilla::WidgetSelectionEvent& aEvent);
|
||||
|
||||
bool SendPasteTransferable(const IPCDataTransfer& aDataTransfer,
|
||||
const bool& aIsPrivateData,
|
||||
|
|
|
@ -27,9 +27,6 @@ skip-if = !e10s
|
|||
[browser_bug1238427.js]
|
||||
[browser_bug1316330.js]
|
||||
skip-if = !e10s
|
||||
[browser_cancel_keydown_keypress_event.js]
|
||||
support-files =
|
||||
prevent_return_key.html
|
||||
[browser_ConsoleAPI_originAttributes.js]
|
||||
[browser_ConsoleAPITests.js]
|
||||
skip-if = e10s
|
||||
|
|
|
@ -8061,9 +8061,6 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent,
|
|||
}
|
||||
}
|
||||
}
|
||||
if (aEvent->mMessage == eKeyDown) {
|
||||
mIsLastKeyDownCanceled = aEvent->mFlags.mDefaultPrevented;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case eMouseUp:
|
||||
|
@ -8853,9 +8850,6 @@ PresShell::FireOrClearDelayedEvents(bool aFireEvents)
|
|||
!doc->EventHandlingSuppressed()) {
|
||||
nsAutoPtr<DelayedEvent> ev(mDelayedEvents[0].forget());
|
||||
mDelayedEvents.RemoveElementAt(0);
|
||||
if (ev->IsKeyPressEvent() && mIsLastKeyDownCanceled) {
|
||||
continue;
|
||||
}
|
||||
ev->Dispatch();
|
||||
}
|
||||
if (!doc->EventHandlingSuppressed()) {
|
||||
|
@ -9663,12 +9657,6 @@ PresShell::DelayedKeyEvent::DelayedKeyEvent(WidgetKeyboardEvent* aEvent) :
|
|||
mEvent = keyEvent;
|
||||
}
|
||||
|
||||
bool
|
||||
PresShell::DelayedKeyEvent::IsKeyPressEvent()
|
||||
{
|
||||
return mEvent->mMessage == eKeyPress;
|
||||
}
|
||||
|
||||
// Start of DEBUG only code
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -600,7 +600,6 @@ protected:
|
|||
public:
|
||||
virtual ~DelayedEvent() { }
|
||||
virtual void Dispatch() { }
|
||||
virtual bool IsKeyPressEvent() { return false; }
|
||||
};
|
||||
|
||||
class DelayedInputEvent : public DelayedEvent
|
||||
|
@ -625,7 +624,6 @@ protected:
|
|||
{
|
||||
public:
|
||||
explicit DelayedKeyEvent(mozilla::WidgetKeyboardEvent* aEvent);
|
||||
virtual bool IsKeyPressEvent() override;
|
||||
};
|
||||
|
||||
// Check if aEvent is a mouse event and record the mouse location for later
|
||||
|
@ -905,8 +903,6 @@ protected:
|
|||
// Whether the widget has received a paint message yet.
|
||||
bool mHasReceivedPaintMessage : 1;
|
||||
|
||||
bool mIsLastKeyDownCanceled : 1;
|
||||
|
||||
static bool sDisableNonTestMouseEvents;
|
||||
};
|
||||
|
||||
|
|
|
@ -3959,8 +3959,13 @@ var gCSSProperties = {
|
|||
domProp: "width",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
/* computed value tests for width test more with display:block */
|
||||
prerequisites: { "display": "block" },
|
||||
prerequisites: {
|
||||
// computed value tests for width test more with display:block
|
||||
"display": "block",
|
||||
// add some margin to avoid the initial "auto" value getting
|
||||
// resolved to the same length as the parent element.
|
||||
"margin-left": "5px",
|
||||
},
|
||||
initial_values: [ " auto" ],
|
||||
/* XXX these have prerequisites */
|
||||
other_values: [ "15px", "3em", "15%",
|
||||
|
@ -5106,7 +5111,12 @@ var gCSSProperties = {
|
|||
get_computed: logical_axis_prop_get_computed,
|
||||
/* XXX testing auto has prerequisites */
|
||||
initial_values: [ "auto" ],
|
||||
prerequisites: { "display": "block" },
|
||||
prerequisites: {
|
||||
"display": "block",
|
||||
// add some margin to avoid the initial "auto" value getting
|
||||
// resolved to the same length as the parent element.
|
||||
"margin-left": "5px",
|
||||
},
|
||||
other_values: [ "15px", "3em", "15%",
|
||||
// these three keywords compute to the initial value only when the
|
||||
// writing mode is vertical, and we're testing with a horizontal
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
/** Test for computation of CSS 'inherit' on all properties and 'unset' on
|
||||
inherited properties **/
|
||||
|
||||
var gDisplayTree = document.getElementById("display");
|
||||
// elements without a frame
|
||||
var gNParent = document.getElementById("nparent");
|
||||
var gNChild = document.getElementById("nchild");
|
||||
|
@ -127,9 +128,15 @@ function test_property(property)
|
|||
is(inherit_initial_computed_n, initial_computed_n,
|
||||
keyword + " should cause inheritance of initial value for '" +
|
||||
property + "'");
|
||||
is(inherit_initial_computed_f, initial_computed_f,
|
||||
keyword + " should cause inheritance of initial value for '" +
|
||||
property + "'");
|
||||
// For width and inline-size, getComputedStyle returns used value
|
||||
// when the element is displayed. Their initial value "auto" makes
|
||||
// the element fill available space of the parent, so it doesn't
|
||||
// make sense to compare it with the value we get before.
|
||||
if (property != "width" && property != "inline-size") {
|
||||
is(inherit_initial_computed_f, initial_computed_f,
|
||||
keyword + " should cause inheritance of initial value for '" +
|
||||
property + "'");
|
||||
}
|
||||
gParentRuleTop.style.removeProperty(property);
|
||||
gChildRule1.style.removeProperty(property);
|
||||
gChildRule2.style.removeProperty(property);
|
||||
|
@ -142,10 +149,22 @@ function test_property(property)
|
|||
gChildRuleTop.style.removeProperty(prereq);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME -moz-binding value makes gElementF and its parent loses
|
||||
// their frame. Force it to get recreated after each property.
|
||||
// See bug 1331903.
|
||||
gDisplayTree.style.display = "none";
|
||||
get_computed_value(getComputedStyle(gFChild, ""), "width");
|
||||
gDisplayTree.style.display = "";
|
||||
get_computed_value(getComputedStyle(gFChild, ""), "width");
|
||||
});
|
||||
}
|
||||
|
||||
for (var prop in gCSSProperties) {
|
||||
// Skip -moz-binding because it effectively drops the frame.
|
||||
if (prop == "-moz-binding") {
|
||||
continue;
|
||||
}
|
||||
var info = gCSSProperties[prop];
|
||||
gChildRule3.style.setProperty(prop, info.other_values[0], "");
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ function xfail_initial(property) {
|
|||
return property in gBrokenInitial;
|
||||
}
|
||||
|
||||
var gDisplayTree = document.getElementById("display");
|
||||
var gElementN = document.getElementById("elementn");
|
||||
var gElementF = document.getElementById("elementf");
|
||||
var gStyleSheet = document.getElementById("stylesheet").sheet;
|
||||
|
@ -136,13 +137,12 @@ function test_property(property)
|
|||
gElementF.parentNode.style.removeProperty(property);
|
||||
}
|
||||
|
||||
// FIXME: Something (maybe with the -moz-binding values in
|
||||
// test_value_computation.html, but may as well do it here to match)
|
||||
// causes gElementF's frame to get lost. Force it to get recreated
|
||||
// after each property.
|
||||
gElementF.parentNode.style.display = "none";
|
||||
// FIXME -moz-binding value makes gElementF and its parent loses
|
||||
// their frame. Force it to get recreated after each property.
|
||||
// See bug 1331903.
|
||||
gDisplayTree.style.display = "none";
|
||||
get_computed_value(getComputedStyle(gElementF, ""), "width");
|
||||
gElementF.parentNode.style.display = "";
|
||||
gDisplayTree.style.display = "";
|
||||
get_computed_value(getComputedStyle(gElementF, ""), "width");
|
||||
});
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ function swap_when_frame(property, value) {
|
|||
gSwapInitialWhenHaveFrame[property].indexOf(value) != -1;
|
||||
}
|
||||
|
||||
var gDisplayTree = document.getElementById("display");
|
||||
var gElementN = document.getElementById("elementn");
|
||||
var gElementF = document.getElementById("elementf");
|
||||
var gStyleSheet = document.getElementById("stylesheet").sheet;
|
||||
|
@ -206,12 +207,12 @@ function test_value(property, val, is_initial)
|
|||
gElementF.parentNode.style.removeProperty(property);
|
||||
}
|
||||
|
||||
// FIXME: Something (maybe with the -moz-binding values) causes
|
||||
// gElementF's frame to get lost. Force it to get recreated after
|
||||
// each property.
|
||||
gElementF.parentNode.style.display = "none";
|
||||
// FIXME -moz-binding value makes gElementF and its parent loses
|
||||
// their frame. Force it to get recreated after each property.
|
||||
// See bug 1331903.
|
||||
gDisplayTree.style.display = "none";
|
||||
get_computed_value(getComputedStyle(gElementF, ""), "width");
|
||||
gElementF.parentNode.style.display = "";
|
||||
gDisplayTree.style.display = "";
|
||||
get_computed_value(getComputedStyle(gElementF, ""), "width");
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@ using namespace stagefright;
|
|||
namespace mp4_demuxer
|
||||
{
|
||||
|
||||
static LazyLogModule sLog("MP4Metadata");
|
||||
|
||||
class DataSourceAdapter : public DataSource
|
||||
{
|
||||
public:
|
||||
|
@ -197,8 +199,6 @@ TrackTypeToString(mozilla::TrackInfo::TrackType aType)
|
|||
uint32_t
|
||||
MP4Metadata::GetNumberTracks(mozilla::TrackInfo::TrackType aType) const
|
||||
{
|
||||
static LazyLogModule sLog("MP4Metadata");
|
||||
|
||||
uint32_t numTracks = mStagefright->GetNumberTracks(aType);
|
||||
|
||||
#ifdef MOZ_RUST_MP4PARSE
|
||||
|
@ -616,7 +616,6 @@ bool
|
|||
RustStreamAdaptor::Read(uint8_t* buffer, uintptr_t size, size_t* bytes_read)
|
||||
{
|
||||
if (!mOffset.isValid()) {
|
||||
static LazyLogModule sLog("MP4Metadata");
|
||||
MOZ_LOG(sLog, LogLevel::Error, ("Overflow in source stream offset"));
|
||||
return false;
|
||||
}
|
||||
|
@ -638,7 +637,6 @@ read_source(uint8_t* buffer, uintptr_t size, void* userdata)
|
|||
size_t bytes_read = 0;
|
||||
bool rv = source->Read(buffer, size, &bytes_read);
|
||||
if (!rv) {
|
||||
static LazyLogModule sLog("MP4Metadata");
|
||||
MOZ_LOG(sLog, LogLevel::Warning, ("Error reading source data"));
|
||||
return -1;
|
||||
}
|
||||
|
@ -653,7 +651,10 @@ MP4MetadataRust::MP4MetadataRust(Stream* aSource)
|
|||
mRustParser.reset(mp4parse_new(&io));
|
||||
MOZ_ASSERT(mRustParser);
|
||||
|
||||
static LazyLogModule sLog("MP4Metadata");
|
||||
if (MOZ_LOG_TEST(sLog, LogLevel::Debug)) {
|
||||
mp4parse_log(true);
|
||||
}
|
||||
|
||||
mp4parse_error rv = mp4parse_read(mRustParser.get());
|
||||
MOZ_LOG(sLog, LogLevel::Debug, ("rust parser returned %d\n", rv));
|
||||
Telemetry::Accumulate(Telemetry::MEDIA_RUST_MP4PARSE_SUCCESS,
|
||||
|
@ -701,8 +702,6 @@ TrackTypeEqual(TrackInfo::TrackType aLHS, mp4parse_track_type aRHS)
|
|||
uint32_t
|
||||
MP4MetadataRust::GetNumberTracks(mozilla::TrackInfo::TrackType aType) const
|
||||
{
|
||||
static LazyLogModule sLog("MP4Metadata");
|
||||
|
||||
uint32_t tracks;
|
||||
auto rv = mp4parse_get_track_count(mRustParser.get(), &tracks);
|
||||
if (rv != MP4PARSE_OK) {
|
||||
|
@ -762,8 +761,6 @@ mozilla::UniquePtr<mozilla::TrackInfo>
|
|||
MP4MetadataRust::GetTrackInfo(mozilla::TrackInfo::TrackType aType,
|
||||
size_t aTrackNumber) const
|
||||
{
|
||||
static LazyLogModule sLog("MP4Metadata");
|
||||
|
||||
Maybe<uint32_t> trackIndex = TrackTypeToGlobalTrackIndex(aType, aTrackNumber);
|
||||
if (trackIndex.isNothing()) {
|
||||
return nullptr;
|
||||
|
|
|
@ -39,6 +39,12 @@ if CONFIG['MOZ_REPLACE_MALLOC']:
|
|||
'replace_malloc.c',
|
||||
]
|
||||
|
||||
if CONFIG['OS_TARGET'] == 'Darwin' and (CONFIG['MOZ_REPLACE_MALLOC'] or
|
||||
CONFIG['MOZ_MEMORY'] and not CONFIG['MOZ_JEMALLOC4']):
|
||||
SOURCES += [
|
||||
'zone.c',
|
||||
]
|
||||
|
||||
Library('memory')
|
||||
|
||||
if CONFIG['MOZ_GLUE_IN_PROGRAM']:
|
||||
|
|
|
@ -300,247 +300,3 @@ MOZ_MEMORY_API __realloc_hook_type __realloc_hook = realloc_impl;
|
|||
MOZ_MEMORY_API __memalign_hook_type __memalign_hook = memalign_impl;
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following is a OSX zone allocator implementation.
|
||||
* /!\ WARNING. It assumes the underlying malloc implementation's
|
||||
* malloc_usable_size returns 0 when the given pointer is not owned by
|
||||
* the allocator. Sadly, OSX does call zone_size with pointers not
|
||||
* owned by the allocator.
|
||||
*/
|
||||
|
||||
#ifdef XP_DARWIN
|
||||
#include <stdlib.h>
|
||||
#include <malloc/malloc.h>
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
static size_t
|
||||
zone_size(malloc_zone_t *zone, void *ptr)
|
||||
{
|
||||
return malloc_usable_size_impl(ptr);
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_malloc(malloc_zone_t *zone, size_t size)
|
||||
{
|
||||
return malloc_impl(size);
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_calloc(malloc_zone_t *zone, size_t num, size_t size)
|
||||
{
|
||||
return calloc_impl(num, size);
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_realloc(malloc_zone_t *zone, void *ptr, size_t size)
|
||||
{
|
||||
if (malloc_usable_size_impl(ptr))
|
||||
return realloc_impl(ptr, size);
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
static void
|
||||
zone_free(malloc_zone_t *zone, void *ptr)
|
||||
{
|
||||
if (malloc_usable_size_impl(ptr)) {
|
||||
free_impl(ptr);
|
||||
return;
|
||||
}
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
zone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size)
|
||||
{
|
||||
size_t current_size = malloc_usable_size_impl(ptr);
|
||||
if (current_size) {
|
||||
MOZ_ASSERT(current_size == size);
|
||||
free_impl(ptr);
|
||||
return;
|
||||
}
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
if (posix_memalign_impl(&ptr, alignment, size) == 0)
|
||||
return ptr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_valloc(malloc_zone_t *zone, size_t size)
|
||||
{
|
||||
return valloc_impl(size);
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_destroy(malloc_zone_t *zone)
|
||||
{
|
||||
/* This function should never be called. */
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
static size_t
|
||||
zone_good_size(malloc_zone_t *zone, size_t size)
|
||||
{
|
||||
return malloc_good_size_impl(size);
|
||||
}
|
||||
|
||||
#ifdef MOZ_JEMALLOC
|
||||
|
||||
#include "jemalloc/internal/jemalloc_internal.h"
|
||||
|
||||
static void
|
||||
zone_force_lock(malloc_zone_t *zone)
|
||||
{
|
||||
/* /!\ This calls into jemalloc. It works because we're linked in the
|
||||
* same library. Stolen from jemalloc's zone.c. */
|
||||
if (isthreaded)
|
||||
jemalloc_prefork();
|
||||
}
|
||||
|
||||
static void
|
||||
zone_force_unlock(malloc_zone_t *zone)
|
||||
{
|
||||
/* /!\ This calls into jemalloc. It works because we're linked in the
|
||||
* same library. Stolen from jemalloc's zone.c. */
|
||||
if (isthreaded)
|
||||
jemalloc_postfork_parent();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define JEMALLOC_ZONE_VERSION 6
|
||||
|
||||
/* Empty implementations are needed, because fork() calls zone->force_(un)lock
|
||||
* unconditionally. */
|
||||
static void
|
||||
zone_force_lock(malloc_zone_t *zone)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
zone_force_unlock(malloc_zone_t *zone)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static malloc_zone_t zone;
|
||||
static struct malloc_introspection_t zone_introspect;
|
||||
|
||||
static malloc_zone_t *get_default_zone()
|
||||
{
|
||||
malloc_zone_t **zones = NULL;
|
||||
unsigned int num_zones = 0;
|
||||
|
||||
/*
|
||||
* On OSX 10.12, malloc_default_zone returns a special zone that is not
|
||||
* present in the list of registered zones. That zone uses a "lite zone"
|
||||
* if one is present (apparently enabled when malloc stack logging is
|
||||
* enabled), or the first registered zone otherwise. In practice this
|
||||
* means unless malloc stack logging is enabled, the first registered
|
||||
* zone is the default.
|
||||
* So get the list of zones to get the first one, instead of relying on
|
||||
* malloc_default_zone.
|
||||
*/
|
||||
if (KERN_SUCCESS != malloc_get_all_zones(0, NULL, (vm_address_t**) &zones,
|
||||
&num_zones)) {
|
||||
/* Reset the value in case the failure happened after it was set. */
|
||||
num_zones = 0;
|
||||
}
|
||||
if (num_zones) {
|
||||
return zones[0];
|
||||
}
|
||||
return malloc_default_zone();
|
||||
}
|
||||
|
||||
|
||||
__attribute__((constructor)) void
|
||||
register_zone(void)
|
||||
{
|
||||
malloc_zone_t *default_zone = get_default_zone();
|
||||
|
||||
zone.size = (void *)zone_size;
|
||||
zone.malloc = (void *)zone_malloc;
|
||||
zone.calloc = (void *)zone_calloc;
|
||||
zone.valloc = (void *)zone_valloc;
|
||||
zone.free = (void *)zone_free;
|
||||
zone.realloc = (void *)zone_realloc;
|
||||
zone.destroy = (void *)zone_destroy;
|
||||
zone.zone_name = "replace_malloc_zone";
|
||||
zone.batch_malloc = NULL;
|
||||
zone.batch_free = NULL;
|
||||
zone.introspect = &zone_introspect;
|
||||
zone.version = JEMALLOC_ZONE_VERSION;
|
||||
zone.memalign = zone_memalign;
|
||||
zone.free_definite_size = zone_free_definite_size;
|
||||
#if (JEMALLOC_ZONE_VERSION >= 8)
|
||||
zone.pressure_relief = NULL;
|
||||
#endif
|
||||
zone_introspect.enumerator = NULL;
|
||||
zone_introspect.good_size = (void *)zone_good_size;
|
||||
zone_introspect.check = NULL;
|
||||
zone_introspect.print = NULL;
|
||||
zone_introspect.log = NULL;
|
||||
zone_introspect.force_lock = (void *)zone_force_lock;
|
||||
zone_introspect.force_unlock = (void *)zone_force_unlock;
|
||||
zone_introspect.statistics = NULL;
|
||||
zone_introspect.zone_locked = NULL;
|
||||
#if (JEMALLOC_ZONE_VERSION >= 7)
|
||||
zone_introspect.enable_discharge_checking = NULL;
|
||||
zone_introspect.disable_discharge_checking = NULL;
|
||||
zone_introspect.discharge = NULL;
|
||||
#ifdef __BLOCKS__
|
||||
zone_introspect.enumerate_discharged_pointers = NULL;
|
||||
#else
|
||||
zone_introspect.enumerate_unavailable_without_blocks = NULL;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The default purgeable zone is created lazily by OSX's libc. It uses
|
||||
* the default zone when it is created for "small" allocations
|
||||
* (< 15 KiB), but assumes the default zone is a scalable_zone. This
|
||||
* obviously fails when the default zone is the jemalloc zone, so
|
||||
* malloc_default_purgeable_zone is called beforehand so that the
|
||||
* default purgeable zone is created when the default zone is still
|
||||
* a scalable_zone.
|
||||
*/
|
||||
malloc_zone_t *purgeable_zone = malloc_default_purgeable_zone();
|
||||
|
||||
/* Register the custom zone. At this point it won't be the default. */
|
||||
malloc_zone_register(&zone);
|
||||
|
||||
do {
|
||||
/*
|
||||
* Unregister and reregister the default zone. On OSX >= 10.6,
|
||||
* unregistering takes the last registered zone and places it at the
|
||||
* location of the specified zone. Unregistering the default zone thus
|
||||
* makes the last registered one the default. On OSX < 10.6,
|
||||
* unregistering shifts all registered zones. The first registered zone
|
||||
* then becomes the default.
|
||||
*/
|
||||
malloc_zone_unregister(default_zone);
|
||||
malloc_zone_register(default_zone);
|
||||
/*
|
||||
* On OSX 10.6, having the default purgeable zone appear before the default
|
||||
* zone makes some things crash because it thinks it owns the default
|
||||
* zone allocated pointers. We thus unregister/re-register it in order to
|
||||
* ensure it's always after the default zone. On OSX < 10.6, as
|
||||
* unregistering shifts registered zones, this simply removes the purgeable
|
||||
* zone from the list and adds it back at the end, after the default zone.
|
||||
* On OSX >= 10.6, unregistering replaces the purgeable zone with the last
|
||||
* registered zone above, i.e the default zone. Registering it again then
|
||||
* puts it at the end, obviously after the default zone.
|
||||
*/
|
||||
malloc_zone_unregister(purgeable_zone);
|
||||
malloc_zone_register(purgeable_zone);
|
||||
default_zone = get_default_zone();
|
||||
} while (default_zone != &zone);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,425 @@
|
|||
/* 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/. */
|
||||
|
||||
#include "mozmemory_wrap.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <mach/mach_types.h>
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
/*
|
||||
* Malloc implementation functions are MOZ_MEMORY_API, and jemalloc
|
||||
* specific functions MOZ_JEMALLOC_API; see mozmemory_wrap.h
|
||||
*/
|
||||
#define MALLOC_DECL(name, return_type, ...) \
|
||||
MOZ_MEMORY_API return_type name ## _impl(__VA_ARGS__);
|
||||
#define MALLOC_FUNCS MALLOC_FUNCS_MALLOC
|
||||
#include "malloc_decls.h"
|
||||
|
||||
#define MALLOC_DECL(name, return_type, ...) \
|
||||
MOZ_JEMALLOC_API return_type name ## _impl(__VA_ARGS__);
|
||||
#define MALLOC_FUNCS MALLOC_FUNCS_JEMALLOC
|
||||
#include "malloc_decls.h"
|
||||
|
||||
/*
|
||||
* Definitions of the following structs in malloc/malloc.h might be too old
|
||||
* for the built binary to run on newer versions of OSX. So use the newest
|
||||
* possible version of those structs.
|
||||
*/
|
||||
typedef struct _malloc_zone_t {
|
||||
void *reserved1;
|
||||
void *reserved2;
|
||||
size_t (*size)(struct _malloc_zone_t *, const void *);
|
||||
void *(*malloc)(struct _malloc_zone_t *, size_t);
|
||||
void *(*calloc)(struct _malloc_zone_t *, size_t, size_t);
|
||||
void *(*valloc)(struct _malloc_zone_t *, size_t);
|
||||
void (*free)(struct _malloc_zone_t *, void *);
|
||||
void *(*realloc)(struct _malloc_zone_t *, void *, size_t);
|
||||
void (*destroy)(struct _malloc_zone_t *);
|
||||
const char *zone_name;
|
||||
unsigned (*batch_malloc)(struct _malloc_zone_t *, size_t, void **, unsigned);
|
||||
void (*batch_free)(struct _malloc_zone_t *, void **, unsigned);
|
||||
struct malloc_introspection_t *introspect;
|
||||
unsigned version;
|
||||
void *(*memalign)(struct _malloc_zone_t *, size_t, size_t);
|
||||
void (*free_definite_size)(struct _malloc_zone_t *, void *, size_t);
|
||||
size_t (*pressure_relief)(struct _malloc_zone_t *, size_t);
|
||||
} malloc_zone_t;
|
||||
|
||||
typedef struct {
|
||||
vm_address_t address;
|
||||
vm_size_t size;
|
||||
} vm_range_t;
|
||||
|
||||
typedef struct malloc_statistics_t {
|
||||
unsigned blocks_in_use;
|
||||
size_t size_in_use;
|
||||
size_t max_size_in_use;
|
||||
size_t size_allocated;
|
||||
} malloc_statistics_t;
|
||||
|
||||
typedef kern_return_t memory_reader_t(task_t, vm_address_t, vm_size_t, void **);
|
||||
|
||||
typedef void vm_range_recorder_t(task_t, void *, unsigned type, vm_range_t *, unsigned);
|
||||
|
||||
typedef struct malloc_introspection_t {
|
||||
kern_return_t (*enumerator)(task_t, void *, unsigned, vm_address_t, memory_reader_t, vm_range_recorder_t);
|
||||
size_t (*good_size)(malloc_zone_t *, size_t);
|
||||
boolean_t (*check)(malloc_zone_t *);
|
||||
void (*print)(malloc_zone_t *, boolean_t);
|
||||
void (*log)(malloc_zone_t *, void *);
|
||||
void (*force_lock)(malloc_zone_t *);
|
||||
void (*force_unlock)(malloc_zone_t *);
|
||||
void (*statistics)(malloc_zone_t *, malloc_statistics_t *);
|
||||
boolean_t (*zone_locked)(malloc_zone_t *);
|
||||
boolean_t (*enable_discharge_checking)(malloc_zone_t *);
|
||||
boolean_t (*disable_discharge_checking)(malloc_zone_t *);
|
||||
void (*discharge)(malloc_zone_t *, void *);
|
||||
#ifdef __BLOCKS__
|
||||
void (*enumerate_discharged_pointers)(malloc_zone_t *, void (^)(void *, void *));
|
||||
#else
|
||||
void *enumerate_unavailable_without_blocks;
|
||||
#endif
|
||||
void (*reinit_lock)(malloc_zone_t *);
|
||||
} malloc_introspection_t;
|
||||
|
||||
extern kern_return_t malloc_get_all_zones(task_t, memory_reader_t, vm_address_t **, unsigned *);
|
||||
|
||||
extern malloc_zone_t *malloc_default_zone(void);
|
||||
|
||||
extern void malloc_zone_register(malloc_zone_t *zone);
|
||||
|
||||
extern void malloc_zone_unregister(malloc_zone_t *zone);
|
||||
|
||||
extern malloc_zone_t *malloc_default_purgeable_zone(void);
|
||||
|
||||
|
||||
/*
|
||||
* The following is a OSX zone allocator implementation.
|
||||
* /!\ WARNING. It assumes the underlying malloc implementation's
|
||||
* malloc_usable_size returns 0 when the given pointer is not owned by
|
||||
* the allocator. Sadly, OSX does call zone_size with pointers not
|
||||
* owned by the allocator.
|
||||
*/
|
||||
|
||||
static size_t
|
||||
zone_size(malloc_zone_t *zone, const void *ptr)
|
||||
{
|
||||
return malloc_usable_size_impl(ptr);
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_malloc(malloc_zone_t *zone, size_t size)
|
||||
{
|
||||
return malloc_impl(size);
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_calloc(malloc_zone_t *zone, size_t num, size_t size)
|
||||
{
|
||||
return calloc_impl(num, size);
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_realloc(malloc_zone_t *zone, void *ptr, size_t size)
|
||||
{
|
||||
if (malloc_usable_size_impl(ptr))
|
||||
return realloc_impl(ptr, size);
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
static void
|
||||
zone_free(malloc_zone_t *zone, void *ptr)
|
||||
{
|
||||
if (malloc_usable_size_impl(ptr)) {
|
||||
free_impl(ptr);
|
||||
return;
|
||||
}
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
zone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size)
|
||||
{
|
||||
size_t current_size = malloc_usable_size_impl(ptr);
|
||||
if (current_size) {
|
||||
MOZ_ASSERT(current_size == size);
|
||||
free_impl(ptr);
|
||||
return;
|
||||
}
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
if (posix_memalign_impl(&ptr, alignment, size) == 0)
|
||||
return ptr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_valloc(malloc_zone_t *zone, size_t size)
|
||||
{
|
||||
return valloc_impl(size);
|
||||
}
|
||||
|
||||
static void
|
||||
zone_destroy(malloc_zone_t *zone)
|
||||
{
|
||||
/* This function should never be called. */
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
static unsigned
|
||||
zone_batch_malloc(malloc_zone_t *zone, size_t size, void **results,
|
||||
unsigned num_requested)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < num_requested; i++) {
|
||||
results[i] = malloc_impl(size);
|
||||
if (!results[i])
|
||||
break;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
zone_batch_free(malloc_zone_t *zone, void **to_be_freed,
|
||||
unsigned num_to_be_freed)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < num_to_be_freed; i++) {
|
||||
zone_free(zone, to_be_freed[i]);
|
||||
to_be_freed[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t
|
||||
zone_pressure_relief(malloc_zone_t *zone, size_t goal)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
zone_good_size(malloc_zone_t *zone, size_t size)
|
||||
{
|
||||
return malloc_good_size_impl(size);
|
||||
}
|
||||
|
||||
static kern_return_t
|
||||
zone_enumerator(task_t task, void *data, unsigned type_mask,
|
||||
vm_address_t zone_address, memory_reader_t reader,
|
||||
vm_range_recorder_t recorder)
|
||||
{
|
||||
return KERN_SUCCESS;
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
zone_check(malloc_zone_t *zone)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
zone_print(malloc_zone_t *zone, boolean_t verbose)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
zone_log(malloc_zone_t *zone, void *address)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef MOZ_JEMALLOC
|
||||
|
||||
#include "jemalloc/internal/jemalloc_internal.h"
|
||||
|
||||
static void
|
||||
zone_force_lock(malloc_zone_t *zone)
|
||||
{
|
||||
/* /!\ This calls into jemalloc. It works because we're linked in the
|
||||
* same library. Stolen from jemalloc's zone.c. */
|
||||
if (isthreaded)
|
||||
jemalloc_prefork();
|
||||
}
|
||||
|
||||
static void
|
||||
zone_force_unlock(malloc_zone_t *zone)
|
||||
{
|
||||
/* /!\ This calls into jemalloc. It works because we're linked in the
|
||||
* same library. Stolen from jemalloc's zone.c. See the comment there. */
|
||||
if (isthreaded)
|
||||
jemalloc_postfork_child();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
extern void _malloc_prefork(void);
|
||||
extern void _malloc_postfork_child(void);
|
||||
|
||||
static void
|
||||
zone_force_lock(malloc_zone_t *zone)
|
||||
{
|
||||
/* /!\ This calls into mozjemalloc. It works because we're linked in the
|
||||
* same library. */
|
||||
_malloc_prefork();
|
||||
}
|
||||
|
||||
static void
|
||||
zone_force_unlock(malloc_zone_t *zone)
|
||||
{
|
||||
/* /!\ This calls into mozjemalloc. It works because we're linked in the
|
||||
* same library. */
|
||||
_malloc_postfork_child();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats)
|
||||
{
|
||||
/* We make no effort to actually fill the values */
|
||||
stats->blocks_in_use = 0;
|
||||
stats->size_in_use = 0;
|
||||
stats->max_size_in_use = 0;
|
||||
stats->size_allocated = 0;
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
zone_locked(malloc_zone_t *zone)
|
||||
{
|
||||
/* Pretend no lock is being held */
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
zone_reinit_lock(malloc_zone_t *zone)
|
||||
{
|
||||
/* As of OSX 10.12, this function is only used when force_unlock would
|
||||
* be used if the zone version were < 9. So just use force_unlock. */
|
||||
zone_force_unlock(zone);
|
||||
}
|
||||
|
||||
static malloc_zone_t zone;
|
||||
static struct malloc_introspection_t zone_introspect;
|
||||
|
||||
static malloc_zone_t *get_default_zone()
|
||||
{
|
||||
malloc_zone_t **zones = NULL;
|
||||
unsigned int num_zones = 0;
|
||||
|
||||
/*
|
||||
* On OSX 10.12, malloc_default_zone returns a special zone that is not
|
||||
* present in the list of registered zones. That zone uses a "lite zone"
|
||||
* if one is present (apparently enabled when malloc stack logging is
|
||||
* enabled), or the first registered zone otherwise. In practice this
|
||||
* means unless malloc stack logging is enabled, the first registered
|
||||
* zone is the default.
|
||||
* So get the list of zones to get the first one, instead of relying on
|
||||
* malloc_default_zone.
|
||||
*/
|
||||
if (KERN_SUCCESS != malloc_get_all_zones(0, NULL, (vm_address_t**) &zones,
|
||||
&num_zones)) {
|
||||
/* Reset the value in case the failure happened after it was set. */
|
||||
num_zones = 0;
|
||||
}
|
||||
if (num_zones) {
|
||||
return zones[0];
|
||||
}
|
||||
return malloc_default_zone();
|
||||
}
|
||||
|
||||
|
||||
#ifdef MOZ_REPLACE_MALLOC
|
||||
__attribute__((constructor))
|
||||
#endif
|
||||
void
|
||||
register_zone(void)
|
||||
{
|
||||
malloc_zone_t *default_zone = get_default_zone();
|
||||
|
||||
zone.size = zone_size;
|
||||
zone.malloc = zone_malloc;
|
||||
zone.calloc = zone_calloc;
|
||||
zone.valloc = zone_valloc;
|
||||
zone.free = zone_free;
|
||||
zone.realloc = zone_realloc;
|
||||
zone.destroy = zone_destroy;
|
||||
#ifdef MOZ_REPLACE_MALLOC
|
||||
zone.zone_name = "replace_malloc_zone";
|
||||
#else
|
||||
zone.zone_name = "jemalloc_zone";
|
||||
#endif
|
||||
zone.batch_malloc = zone_batch_malloc;
|
||||
zone.batch_free = zone_batch_free;
|
||||
zone.introspect = &zone_introspect;
|
||||
zone.version = 9;
|
||||
zone.memalign = zone_memalign;
|
||||
zone.free_definite_size = zone_free_definite_size;
|
||||
zone.pressure_relief = zone_pressure_relief;
|
||||
zone_introspect.enumerator = zone_enumerator;
|
||||
zone_introspect.good_size = zone_good_size;
|
||||
zone_introspect.check = zone_check;
|
||||
zone_introspect.print = zone_print;
|
||||
zone_introspect.log = zone_log;
|
||||
zone_introspect.force_lock = zone_force_lock;
|
||||
zone_introspect.force_unlock = zone_force_unlock;
|
||||
zone_introspect.statistics = zone_statistics;
|
||||
zone_introspect.zone_locked = zone_locked;
|
||||
zone_introspect.enable_discharge_checking = NULL;
|
||||
zone_introspect.disable_discharge_checking = NULL;
|
||||
zone_introspect.discharge = NULL;
|
||||
#ifdef __BLOCKS__
|
||||
zone_introspect.enumerate_discharged_pointers = NULL;
|
||||
#else
|
||||
zone_introspect.enumerate_unavailable_without_blocks = NULL;
|
||||
#endif
|
||||
zone_introspect.reinit_lock = zone_reinit_lock;
|
||||
|
||||
/*
|
||||
* The default purgeable zone is created lazily by OSX's libc. It uses
|
||||
* the default zone when it is created for "small" allocations
|
||||
* (< 15 KiB), but assumes the default zone is a scalable_zone. This
|
||||
* obviously fails when the default zone is the jemalloc zone, so
|
||||
* malloc_default_purgeable_zone is called beforehand so that the
|
||||
* default purgeable zone is created when the default zone is still
|
||||
* a scalable_zone.
|
||||
*/
|
||||
malloc_zone_t *purgeable_zone = malloc_default_purgeable_zone();
|
||||
|
||||
/* Register the custom zone. At this point it won't be the default. */
|
||||
malloc_zone_register(&zone);
|
||||
|
||||
do {
|
||||
/*
|
||||
* Unregister and reregister the default zone. On OSX >= 10.6,
|
||||
* unregistering takes the last registered zone and places it at the
|
||||
* location of the specified zone. Unregistering the default zone thus
|
||||
* makes the last registered one the default. On OSX < 10.6,
|
||||
* unregistering shifts all registered zones. The first registered zone
|
||||
* then becomes the default.
|
||||
*/
|
||||
malloc_zone_unregister(default_zone);
|
||||
malloc_zone_register(default_zone);
|
||||
/*
|
||||
* On OSX 10.6, having the default purgeable zone appear before the default
|
||||
* zone makes some things crash because it thinks it owns the default
|
||||
* zone allocated pointers. We thus unregister/re-register it in order to
|
||||
* ensure it's always after the default zone. On OSX < 10.6, as
|
||||
* unregistering shifts registered zones, this simply removes the purgeable
|
||||
* zone from the list and adds it back at the end, after the default zone.
|
||||
* On OSX >= 10.6, unregistering replaces the purgeable zone with the last
|
||||
* registered zone above, i.e the default zone. Registering it again then
|
||||
* puts it at the end, obviously after the default zone.
|
||||
*/
|
||||
malloc_zone_unregister(purgeable_zone);
|
||||
malloc_zone_register(purgeable_zone);
|
||||
default_zone = get_default_zone();
|
||||
} while (default_zone != &zone);
|
||||
}
|
|
@ -1 +1 @@
|
|||
4.4.0-0-gf1f76357313e7dcad7262f17a48ff0a2e005fcdc
|
||||
4.4.0-3-gc6943acb3c56d1b3d1e82dd43b3fcfeae7771990
|
||||
|
|
|
@ -9007,156 +9007,6 @@ if test "x${enable_zone_allocator}" = "x1" ; then
|
|||
fi
|
||||
$as_echo "#define JEMALLOC_ZONE " >>confdefs.h
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking malloc zone version" >&5
|
||||
$as_echo_n "checking malloc zone version... " >&6; }
|
||||
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <malloc/malloc.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static int foo[sizeof(malloc_zone_t) == sizeof(void *) * 14 ? 1 : -1]
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
JEMALLOC_ZONE_VERSION=3
|
||||
else
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <malloc/malloc.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static int foo[sizeof(malloc_zone_t) == sizeof(void *) * 15 ? 1 : -1]
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
JEMALLOC_ZONE_VERSION=5
|
||||
else
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <malloc/malloc.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static int foo[sizeof(malloc_zone_t) == sizeof(void *) * 16 ? 1 : -1]
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <malloc/malloc.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static int foo[sizeof(malloc_introspection_t) == sizeof(void *) * 9 ? 1 : -1]
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
JEMALLOC_ZONE_VERSION=6
|
||||
else
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <malloc/malloc.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static int foo[sizeof(malloc_introspection_t) == sizeof(void *) * 13 ? 1 : -1]
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
JEMALLOC_ZONE_VERSION=7
|
||||
else
|
||||
JEMALLOC_ZONE_VERSION=
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
else
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <malloc/malloc.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static int foo[sizeof(malloc_zone_t) == sizeof(void *) * 17 ? 1 : -1]
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
JEMALLOC_ZONE_VERSION=8
|
||||
else
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <malloc/malloc.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
static int foo[sizeof(malloc_zone_t) > sizeof(void *) * 17 ? 1 : -1]
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
JEMALLOC_ZONE_VERSION=9
|
||||
else
|
||||
JEMALLOC_ZONE_VERSION=
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
if test "x${JEMALLOC_ZONE_VERSION}" = "x"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
|
||||
$as_echo "unsupported" >&6; }
|
||||
as_fn_error $? "Unsupported malloc zone version" "$LINENO" 5
|
||||
fi
|
||||
if test "${JEMALLOC_ZONE_VERSION}" = 9; then
|
||||
JEMALLOC_ZONE_VERSION=8
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: > 8" >&5
|
||||
$as_echo "> 8" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $JEMALLOC_ZONE_VERSION" >&5
|
||||
$as_echo "$JEMALLOC_ZONE_VERSION" >&6; }
|
||||
fi
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define JEMALLOC_ZONE_VERSION $JEMALLOC_ZONE_VERSION
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
@ -1774,37 +1774,6 @@ if test "x${enable_zone_allocator}" = "x1" ; then
|
|||
AC_MSG_ERROR([--enable-zone-allocator is only supported on Darwin])
|
||||
fi
|
||||
AC_DEFINE([JEMALLOC_ZONE], [ ])
|
||||
|
||||
dnl The szone version jumped from 3 to 6 between the OS X 10.5.x and 10.6
|
||||
dnl releases. malloc_zone_t and malloc_introspection_t have new fields in
|
||||
dnl 10.6, which is the only source-level indication of the change.
|
||||
AC_MSG_CHECKING([malloc zone version])
|
||||
AC_DEFUN([JE_ZONE_PROGRAM],
|
||||
[AC_LANG_PROGRAM(
|
||||
[#include <malloc/malloc.h>],
|
||||
[static int foo[[sizeof($1) $2 sizeof(void *) * $3 ? 1 : -1]]]
|
||||
)])
|
||||
|
||||
AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,14)],[JEMALLOC_ZONE_VERSION=3],[
|
||||
AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,15)],[JEMALLOC_ZONE_VERSION=5],[
|
||||
AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,16)],[
|
||||
AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_introspection_t,==,9)],[JEMALLOC_ZONE_VERSION=6],[
|
||||
AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_introspection_t,==,13)],[JEMALLOC_ZONE_VERSION=7],[JEMALLOC_ZONE_VERSION=]
|
||||
)])],[
|
||||
AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,17)],[JEMALLOC_ZONE_VERSION=8],[
|
||||
AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,>,17)],[JEMALLOC_ZONE_VERSION=9],[JEMALLOC_ZONE_VERSION=]
|
||||
)])])])])
|
||||
if test "x${JEMALLOC_ZONE_VERSION}" = "x"; then
|
||||
AC_MSG_RESULT([unsupported])
|
||||
AC_MSG_ERROR([Unsupported malloc zone version])
|
||||
fi
|
||||
if test "${JEMALLOC_ZONE_VERSION}" = 9; then
|
||||
JEMALLOC_ZONE_VERSION=8
|
||||
AC_MSG_RESULT([> 8])
|
||||
else
|
||||
AC_MSG_RESULT([$JEMALLOC_ZONE_VERSION])
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(JEMALLOC_ZONE_VERSION, [$JEMALLOC_ZONE_VERSION])
|
||||
fi
|
||||
|
||||
dnl ============================================================================
|
||||
|
|
|
@ -158,7 +158,6 @@ static const bool config_cache_oblivious =
|
|||
#include <mach/mach_error.h>
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/vm_map.h>
|
||||
#include <malloc/malloc.h>
|
||||
#endif
|
||||
|
||||
#include "jemalloc/internal/ph.h"
|
||||
|
|
|
@ -239,7 +239,6 @@
|
|||
* Darwin (OS X) uses zones to work around Mach-O symbol override shortcomings.
|
||||
*/
|
||||
#undef JEMALLOC_ZONE
|
||||
#undef JEMALLOC_ZONE_VERSION
|
||||
|
||||
/*
|
||||
* Methods for determining whether the OS overcommits.
|
||||
|
|
|
@ -76,7 +76,7 @@ mb_write(void)
|
|||
: "memory" /* Clobbers. */
|
||||
);
|
||||
}
|
||||
#elif defined(__sparc64__)
|
||||
#elif defined(__sparc__) && defined(__arch64__)
|
||||
JEMALLOC_INLINE void
|
||||
mb_write(void)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,75 @@
|
|||
# error "This source file is for zones on Darwin (OS X)."
|
||||
#endif
|
||||
|
||||
/* Definitions of the following structs in malloc/malloc.h might be too old
|
||||
* for the built binary to run on newer versions of OSX. So use the newest
|
||||
* possible version of those structs.
|
||||
*/
|
||||
typedef struct _malloc_zone_t {
|
||||
void *reserved1;
|
||||
void *reserved2;
|
||||
size_t (*size)(struct _malloc_zone_t *, const void *);
|
||||
void *(*malloc)(struct _malloc_zone_t *, size_t);
|
||||
void *(*calloc)(struct _malloc_zone_t *, size_t, size_t);
|
||||
void *(*valloc)(struct _malloc_zone_t *, size_t);
|
||||
void (*free)(struct _malloc_zone_t *, void *);
|
||||
void *(*realloc)(struct _malloc_zone_t *, void *, size_t);
|
||||
void (*destroy)(struct _malloc_zone_t *);
|
||||
const char *zone_name;
|
||||
unsigned (*batch_malloc)(struct _malloc_zone_t *, size_t, void **, unsigned);
|
||||
void (*batch_free)(struct _malloc_zone_t *, void **, unsigned);
|
||||
struct malloc_introspection_t *introspect;
|
||||
unsigned version;
|
||||
void *(*memalign)(struct _malloc_zone_t *, size_t, size_t);
|
||||
void (*free_definite_size)(struct _malloc_zone_t *, void *, size_t);
|
||||
size_t (*pressure_relief)(struct _malloc_zone_t *, size_t);
|
||||
} malloc_zone_t;
|
||||
|
||||
typedef struct {
|
||||
vm_address_t address;
|
||||
vm_size_t size;
|
||||
} vm_range_t;
|
||||
|
||||
typedef struct malloc_statistics_t {
|
||||
unsigned blocks_in_use;
|
||||
size_t size_in_use;
|
||||
size_t max_size_in_use;
|
||||
size_t size_allocated;
|
||||
} malloc_statistics_t;
|
||||
|
||||
typedef kern_return_t memory_reader_t(task_t, vm_address_t, vm_size_t, void **);
|
||||
|
||||
typedef void vm_range_recorder_t(task_t, void *, unsigned type, vm_range_t *, unsigned);
|
||||
|
||||
typedef struct malloc_introspection_t {
|
||||
kern_return_t (*enumerator)(task_t, void *, unsigned, vm_address_t, memory_reader_t, vm_range_recorder_t);
|
||||
size_t (*good_size)(malloc_zone_t *, size_t);
|
||||
boolean_t (*check)(malloc_zone_t *);
|
||||
void (*print)(malloc_zone_t *, boolean_t);
|
||||
void (*log)(malloc_zone_t *, void *);
|
||||
void (*force_lock)(malloc_zone_t *);
|
||||
void (*force_unlock)(malloc_zone_t *);
|
||||
void (*statistics)(malloc_zone_t *, malloc_statistics_t *);
|
||||
boolean_t (*zone_locked)(malloc_zone_t *);
|
||||
boolean_t (*enable_discharge_checking)(malloc_zone_t *);
|
||||
boolean_t (*disable_discharge_checking)(malloc_zone_t *);
|
||||
void (*discharge)(malloc_zone_t *, void *);
|
||||
#ifdef __BLOCKS__
|
||||
void (*enumerate_discharged_pointers)(malloc_zone_t *, void (^)(void *, void *));
|
||||
#else
|
||||
void *enumerate_unavailable_without_blocks;
|
||||
#endif
|
||||
void (*reinit_lock)(malloc_zone_t *);
|
||||
} malloc_introspection_t;
|
||||
|
||||
extern kern_return_t malloc_get_all_zones(task_t, memory_reader_t, vm_address_t **, unsigned *);
|
||||
|
||||
extern malloc_zone_t *malloc_default_zone(void);
|
||||
|
||||
extern void malloc_zone_register(malloc_zone_t *zone);
|
||||
|
||||
extern void malloc_zone_unregister(malloc_zone_t *zone);
|
||||
|
||||
/*
|
||||
* The malloc_default_purgeable_zone() function is only available on >= 10.6.
|
||||
* We need to check whether it is present at runtime, thus the weak_import.
|
||||
|
@ -20,24 +89,35 @@ static struct malloc_introspection_t jemalloc_zone_introspect;
|
|||
/******************************************************************************/
|
||||
/* Function prototypes for non-inline static functions. */
|
||||
|
||||
static size_t zone_size(malloc_zone_t *zone, void *ptr);
|
||||
static size_t zone_size(malloc_zone_t *zone, const void *ptr);
|
||||
static void *zone_malloc(malloc_zone_t *zone, size_t size);
|
||||
static void *zone_calloc(malloc_zone_t *zone, size_t num, size_t size);
|
||||
static void *zone_valloc(malloc_zone_t *zone, size_t size);
|
||||
static void zone_free(malloc_zone_t *zone, void *ptr);
|
||||
static void *zone_realloc(malloc_zone_t *zone, void *ptr, size_t size);
|
||||
#if (JEMALLOC_ZONE_VERSION >= 5)
|
||||
static void *zone_memalign(malloc_zone_t *zone, size_t alignment,
|
||||
#endif
|
||||
#if (JEMALLOC_ZONE_VERSION >= 6)
|
||||
size_t size);
|
||||
static void zone_free_definite_size(malloc_zone_t *zone, void *ptr,
|
||||
size_t size);
|
||||
#endif
|
||||
static void *zone_destroy(malloc_zone_t *zone);
|
||||
static void zone_destroy(malloc_zone_t *zone);
|
||||
static unsigned zone_batch_malloc(struct _malloc_zone_t *zone, size_t size,
|
||||
void **results, unsigned num_requested);
|
||||
static void zone_batch_free(struct _malloc_zone_t *zone,
|
||||
void **to_be_freed, unsigned num_to_be_freed);
|
||||
static size_t zone_pressure_relief(struct _malloc_zone_t *zone, size_t goal);
|
||||
static size_t zone_good_size(malloc_zone_t *zone, size_t size);
|
||||
static kern_return_t zone_enumerator(task_t task, void *data, unsigned type_mask,
|
||||
vm_address_t zone_address, memory_reader_t reader,
|
||||
vm_range_recorder_t recorder);
|
||||
static boolean_t zone_check(malloc_zone_t *zone);
|
||||
static void zone_print(malloc_zone_t *zone, boolean_t verbose);
|
||||
static void zone_log(malloc_zone_t *zone, void *address);
|
||||
static void zone_force_lock(malloc_zone_t *zone);
|
||||
static void zone_force_unlock(malloc_zone_t *zone);
|
||||
static void zone_statistics(malloc_zone_t *zone,
|
||||
malloc_statistics_t *stats);
|
||||
static boolean_t zone_locked(malloc_zone_t *zone);
|
||||
static void zone_reinit_lock(malloc_zone_t *zone);
|
||||
|
||||
/******************************************************************************/
|
||||
/*
|
||||
|
@ -45,7 +125,7 @@ static void zone_force_unlock(malloc_zone_t *zone);
|
|||
*/
|
||||
|
||||
static size_t
|
||||
zone_size(malloc_zone_t *zone, void *ptr)
|
||||
zone_size(malloc_zone_t *zone, const void *ptr)
|
||||
{
|
||||
|
||||
/*
|
||||
|
@ -106,7 +186,6 @@ zone_realloc(malloc_zone_t *zone, void *ptr, size_t size)
|
|||
return (realloc(ptr, size));
|
||||
}
|
||||
|
||||
#if (JEMALLOC_ZONE_VERSION >= 5)
|
||||
static void *
|
||||
zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size)
|
||||
{
|
||||
|
@ -116,9 +195,7 @@ zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size)
|
|||
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (JEMALLOC_ZONE_VERSION >= 6)
|
||||
static void
|
||||
zone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size)
|
||||
{
|
||||
|
@ -133,15 +210,46 @@ zone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size)
|
|||
|
||||
free(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *
|
||||
static void
|
||||
zone_destroy(malloc_zone_t *zone)
|
||||
{
|
||||
|
||||
/* This function should never be called. */
|
||||
not_reached();
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
zone_batch_malloc(struct _malloc_zone_t *zone, size_t size, void **results,
|
||||
unsigned num_requested)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < num_requested; i++) {
|
||||
results[i] = je_malloc(size);
|
||||
if (!results[i])
|
||||
break;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
zone_batch_free(struct _malloc_zone_t *zone, void **to_be_freed,
|
||||
unsigned num_to_be_freed)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < num_to_be_freed; i++) {
|
||||
zone_free(zone, to_be_freed[i]);
|
||||
to_be_freed[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t
|
||||
zone_pressure_relief(struct _malloc_zone_t *zone, size_t goal)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
|
@ -153,6 +261,30 @@ zone_good_size(malloc_zone_t *zone, size_t size)
|
|||
return (s2u(size));
|
||||
}
|
||||
|
||||
static kern_return_t
|
||||
zone_enumerator(task_t task, void *data, unsigned type_mask,
|
||||
vm_address_t zone_address, memory_reader_t reader,
|
||||
vm_range_recorder_t recorder)
|
||||
{
|
||||
return KERN_SUCCESS;
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
zone_check(malloc_zone_t *zone)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
zone_print(malloc_zone_t *zone, boolean_t verbose)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
zone_log(malloc_zone_t *zone, void *address)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
zone_force_lock(malloc_zone_t *zone)
|
||||
{
|
||||
|
@ -176,53 +308,69 @@ zone_force_unlock(malloc_zone_t *zone)
|
|||
jemalloc_postfork_child();
|
||||
}
|
||||
|
||||
static void
|
||||
zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats)
|
||||
{
|
||||
/* We make no effort to actually fill the values */
|
||||
stats->blocks_in_use = 0;
|
||||
stats->size_in_use = 0;
|
||||
stats->max_size_in_use = 0;
|
||||
stats->size_allocated = 0;
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
zone_locked(malloc_zone_t *zone)
|
||||
{
|
||||
/* Pretend no lock is being held */
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
zone_reinit_lock(malloc_zone_t *zone)
|
||||
{
|
||||
/* As of OSX 10.12, this function is only used when force_unlock would
|
||||
* be used if the zone version were < 9. So just use force_unlock. */
|
||||
zone_force_unlock(zone);
|
||||
}
|
||||
|
||||
static void
|
||||
zone_init(void)
|
||||
{
|
||||
|
||||
jemalloc_zone.size = (void *)zone_size;
|
||||
jemalloc_zone.malloc = (void *)zone_malloc;
|
||||
jemalloc_zone.calloc = (void *)zone_calloc;
|
||||
jemalloc_zone.valloc = (void *)zone_valloc;
|
||||
jemalloc_zone.free = (void *)zone_free;
|
||||
jemalloc_zone.realloc = (void *)zone_realloc;
|
||||
jemalloc_zone.destroy = (void *)zone_destroy;
|
||||
jemalloc_zone.size = zone_size;
|
||||
jemalloc_zone.malloc = zone_malloc;
|
||||
jemalloc_zone.calloc = zone_calloc;
|
||||
jemalloc_zone.valloc = zone_valloc;
|
||||
jemalloc_zone.free = zone_free;
|
||||
jemalloc_zone.realloc = zone_realloc;
|
||||
jemalloc_zone.destroy = zone_destroy;
|
||||
jemalloc_zone.zone_name = "jemalloc_zone";
|
||||
jemalloc_zone.batch_malloc = NULL;
|
||||
jemalloc_zone.batch_free = NULL;
|
||||
jemalloc_zone.batch_malloc = zone_batch_malloc;
|
||||
jemalloc_zone.batch_free = zone_batch_free;
|
||||
jemalloc_zone.introspect = &jemalloc_zone_introspect;
|
||||
jemalloc_zone.version = JEMALLOC_ZONE_VERSION;
|
||||
#if (JEMALLOC_ZONE_VERSION >= 5)
|
||||
jemalloc_zone.version = 9;
|
||||
jemalloc_zone.memalign = zone_memalign;
|
||||
#endif
|
||||
#if (JEMALLOC_ZONE_VERSION >= 6)
|
||||
jemalloc_zone.free_definite_size = zone_free_definite_size;
|
||||
#endif
|
||||
#if (JEMALLOC_ZONE_VERSION >= 8)
|
||||
jemalloc_zone.pressure_relief = NULL;
|
||||
#endif
|
||||
jemalloc_zone.pressure_relief = zone_pressure_relief;
|
||||
|
||||
jemalloc_zone_introspect.enumerator = NULL;
|
||||
jemalloc_zone_introspect.good_size = (void *)zone_good_size;
|
||||
jemalloc_zone_introspect.check = NULL;
|
||||
jemalloc_zone_introspect.print = NULL;
|
||||
jemalloc_zone_introspect.log = NULL;
|
||||
jemalloc_zone_introspect.force_lock = (void *)zone_force_lock;
|
||||
jemalloc_zone_introspect.force_unlock = (void *)zone_force_unlock;
|
||||
jemalloc_zone_introspect.statistics = NULL;
|
||||
#if (JEMALLOC_ZONE_VERSION >= 6)
|
||||
jemalloc_zone_introspect.zone_locked = NULL;
|
||||
#endif
|
||||
#if (JEMALLOC_ZONE_VERSION >= 7)
|
||||
jemalloc_zone_introspect.enumerator = zone_enumerator;
|
||||
jemalloc_zone_introspect.good_size = zone_good_size;
|
||||
jemalloc_zone_introspect.check = zone_check;
|
||||
jemalloc_zone_introspect.print = zone_print;
|
||||
jemalloc_zone_introspect.log = zone_log;
|
||||
jemalloc_zone_introspect.force_lock = zone_force_lock;
|
||||
jemalloc_zone_introspect.force_unlock = zone_force_unlock;
|
||||
jemalloc_zone_introspect.statistics = zone_statistics;
|
||||
jemalloc_zone_introspect.zone_locked = zone_locked;
|
||||
jemalloc_zone_introspect.enable_discharge_checking = NULL;
|
||||
jemalloc_zone_introspect.disable_discharge_checking = NULL;
|
||||
jemalloc_zone_introspect.discharge = NULL;
|
||||
# ifdef __BLOCKS__
|
||||
#ifdef __BLOCKS__
|
||||
jemalloc_zone_introspect.enumerate_discharged_pointers = NULL;
|
||||
# else
|
||||
#else
|
||||
jemalloc_zone_introspect.enumerate_unavailable_without_blocks = NULL;
|
||||
# endif
|
||||
#endif
|
||||
jemalloc_zone_introspect.reinit_lock = zone_reinit_lock;
|
||||
}
|
||||
|
||||
static malloc_zone_t *
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
UPSTREAM_REPO=https://github.com/jemalloc/jemalloc
|
||||
UPSTREAM_COMMIT=4.4.0
|
||||
UPSTREAM_COMMIT=c6943acb3c56d1b3d1e82dd43b3fcfeae7771990
|
||||
|
|
|
@ -1451,67 +1451,18 @@ static
|
|||
#endif
|
||||
bool malloc_init_hard(void);
|
||||
|
||||
static void _malloc_prefork(void);
|
||||
static void _malloc_postfork(void);
|
||||
|
||||
#ifdef MOZ_MEMORY_DARWIN
|
||||
/*
|
||||
* MALLOC_ZONE_T_NOTE
|
||||
*
|
||||
* On Darwin, we hook into the memory allocator using a malloc_zone_t struct.
|
||||
* We must be very careful around this struct because of different behaviour on
|
||||
* different versions of OSX.
|
||||
*
|
||||
* Each of OSX 10.5, 10.6 and 10.7 use different versions of the struct
|
||||
* (with version numbers 3, 6 and 8 respectively). The binary we use on each of
|
||||
* these platforms will not necessarily be built using the correct SDK [1].
|
||||
* This means we need to statically know the correct struct size to use on all
|
||||
* OSX releases, and have a fallback for unknown future versions. The struct
|
||||
* sizes defined in osx_zone_types.h.
|
||||
*
|
||||
* For OSX 10.8 and later, we may expect the malloc_zone_t struct to change
|
||||
* again, and need to dynamically account for this. By simply leaving
|
||||
* malloc_zone_t alone, we don't quite deal with the problem, because there
|
||||
* remain calls to jemalloc through the mozalloc interface. We check this
|
||||
* dynamically on each allocation, using the CHECK_DARWIN macro and
|
||||
* osx_use_jemalloc.
|
||||
*
|
||||
*
|
||||
* [1] Mozilla is built as a universal binary on Mac, supporting i386 and
|
||||
* x86_64. The i386 target is built using the 10.5 SDK, even if it runs on
|
||||
* 10.6. The x86_64 target is built using the 10.6 SDK, even if it runs on
|
||||
* 10.7 or later, or 10.5.
|
||||
*
|
||||
* FIXME:
|
||||
* When later versions of OSX come out (10.8 and up), we need to check their
|
||||
* malloc_zone_t versions. If they're greater than 8, we need a new version
|
||||
* of malloc_zone_t adapted into osx_zone_types.h.
|
||||
*/
|
||||
|
||||
#ifndef MOZ_REPLACE_MALLOC
|
||||
#include "osx_zone_types.h"
|
||||
|
||||
#define LEOPARD_MALLOC_ZONE_T_VERSION 3
|
||||
#define SNOW_LEOPARD_MALLOC_ZONE_T_VERSION 6
|
||||
#define LION_MALLOC_ZONE_T_VERSION 8
|
||||
|
||||
static bool osx_use_jemalloc = false;
|
||||
|
||||
|
||||
static lion_malloc_zone l_szone;
|
||||
static malloc_zone_t * szone = (malloc_zone_t*)(&l_szone);
|
||||
|
||||
static lion_malloc_introspection l_ozone_introspect;
|
||||
static malloc_introspection_t * const ozone_introspect =
|
||||
(malloc_introspection_t*)(&l_ozone_introspect);
|
||||
static malloc_zone_t *get_default_zone();
|
||||
static void szone2ozone(malloc_zone_t *zone, size_t size);
|
||||
static size_t zone_version_size(int version);
|
||||
#else
|
||||
static const bool osx_use_jemalloc = true;
|
||||
#ifndef MOZ_MEMORY_DARWIN
|
||||
static
|
||||
#endif
|
||||
|
||||
void _malloc_prefork(void);
|
||||
#ifndef MOZ_MEMORY_DARWIN
|
||||
static
|
||||
#endif
|
||||
void _malloc_postfork_parent(void);
|
||||
#ifndef MOZ_MEMORY_DARWIN
|
||||
static
|
||||
#endif
|
||||
void _malloc_postfork_child(void);
|
||||
|
||||
/*
|
||||
* End function prototypes.
|
||||
|
@ -5580,6 +5531,10 @@ malloc_init(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_MEMORY_DARWIN) && !defined(MOZ_REPLACE_MALLOC)
|
||||
extern void register_zone(void);
|
||||
#endif
|
||||
|
||||
#if !defined(MOZ_MEMORY_WINDOWS)
|
||||
static
|
||||
#endif
|
||||
|
@ -5593,9 +5548,6 @@ malloc_init_hard(void)
|
|||
#ifndef MOZ_MEMORY_WINDOWS
|
||||
int linklen;
|
||||
#endif
|
||||
#ifdef MOZ_MEMORY_DARWIN
|
||||
malloc_zone_t* default_zone;
|
||||
#endif
|
||||
|
||||
#ifndef MOZ_MEMORY_WINDOWS
|
||||
malloc_mutex_lock(&init_lock);
|
||||
|
@ -6091,7 +6043,7 @@ MALLOC_OUT:
|
|||
|
||||
#if !defined(MOZ_MEMORY_WINDOWS) && !defined(MOZ_MEMORY_DARWIN)
|
||||
/* Prevent potential deadlock on malloc locks after fork. */
|
||||
pthread_atfork(_malloc_prefork, _malloc_postfork, _malloc_postfork);
|
||||
pthread_atfork(_malloc_prefork, _malloc_postfork_parent, _malloc_postfork_child);
|
||||
#endif
|
||||
|
||||
#if defined(NEEDS_PTHREAD_MMAP_UNALIGNED_TSD)
|
||||
|
@ -6101,45 +6053,7 @@ MALLOC_OUT:
|
|||
#endif
|
||||
|
||||
#if defined(MOZ_MEMORY_DARWIN) && !defined(MOZ_REPLACE_MALLOC)
|
||||
/*
|
||||
* Overwrite the default memory allocator to use jemalloc everywhere.
|
||||
*/
|
||||
default_zone = get_default_zone();
|
||||
|
||||
/*
|
||||
* We only use jemalloc with MacOS 10.6 and 10.7. jemalloc is disabled
|
||||
* on 32-bit builds (10.5 and 32-bit 10.6) due to bug 702250, an
|
||||
* apparent MacOS bug. In fact, this code isn't even compiled on
|
||||
* 32-bit builds.
|
||||
*
|
||||
* We'll have to update our code to work with newer versions, because
|
||||
* the malloc zone layout is likely to change.
|
||||
*/
|
||||
|
||||
osx_use_jemalloc = (default_zone->version == SNOW_LEOPARD_MALLOC_ZONE_T_VERSION ||
|
||||
default_zone->version == LION_MALLOC_ZONE_T_VERSION);
|
||||
|
||||
/* Allow us dynamically turn off jemalloc for testing. */
|
||||
if (getenv("NO_MAC_JEMALLOC")) {
|
||||
osx_use_jemalloc = false;
|
||||
#ifdef __i386__
|
||||
malloc_printf("Warning: NO_MAC_JEMALLOC has no effect on "
|
||||
"i386 machines (such as this one).\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (osx_use_jemalloc) {
|
||||
/*
|
||||
* Convert the default szone to an "overlay zone" that is capable
|
||||
* of deallocating szone-allocated objects, but allocating new
|
||||
* objects from jemalloc.
|
||||
*/
|
||||
size_t size = zone_version_size(default_zone->version);
|
||||
szone2ozone(default_zone, size);
|
||||
}
|
||||
else {
|
||||
szone = default_zone;
|
||||
}
|
||||
register_zone();
|
||||
#endif
|
||||
|
||||
#ifndef MOZ_MEMORY_WINDOWS
|
||||
|
@ -6166,32 +6080,11 @@ malloc_shutdown()
|
|||
* Begin malloc(3)-compatible functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Even though we compile with MOZ_MEMORY, we may have to dynamically decide
|
||||
* not to use jemalloc, as discussed above. However, we call jemalloc
|
||||
* functions directly from mozalloc. Since it's pretty dangerous to mix the
|
||||
* allocators, we need to call the OSX allocators from the functions below,
|
||||
* when osx_use_jemalloc is not (dynamically) set.
|
||||
*
|
||||
* Note that we assume jemalloc is enabled on i386. This is safe because the
|
||||
* only i386 versions of MacOS are 10.5 and 10.6, which we support. We have to
|
||||
* do this because madvise isn't in the malloc zone struct for 10.5.
|
||||
*
|
||||
* This means that NO_MAC_JEMALLOC doesn't work on i386.
|
||||
*/
|
||||
#if defined(MOZ_MEMORY_DARWIN) && !defined(__i386__) && !defined(MOZ_REPLACE_MALLOC)
|
||||
#define DARWIN_ONLY(A) if (!osx_use_jemalloc) { A; }
|
||||
#else
|
||||
#define DARWIN_ONLY(A)
|
||||
#endif
|
||||
|
||||
MOZ_MEMORY_API void *
|
||||
malloc_impl(size_t size)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
DARWIN_ONLY(return (szone->malloc)(szone, size));
|
||||
|
||||
if (malloc_init()) {
|
||||
ret = NULL;
|
||||
goto RETURN;
|
||||
|
@ -6274,8 +6167,6 @@ MEMALIGN(size_t alignment, size_t size)
|
|||
{
|
||||
void *ret;
|
||||
|
||||
DARWIN_ONLY(return (szone->memalign)(szone, alignment, size));
|
||||
|
||||
assert(((alignment - 1) & alignment) == 0);
|
||||
|
||||
if (malloc_init()) {
|
||||
|
@ -6374,8 +6265,6 @@ calloc_impl(size_t num, size_t size)
|
|||
void *ret;
|
||||
size_t num_size;
|
||||
|
||||
DARWIN_ONLY(return (szone->calloc)(szone, num, size));
|
||||
|
||||
if (malloc_init()) {
|
||||
num_size = 0;
|
||||
ret = NULL;
|
||||
|
@ -6430,8 +6319,6 @@ realloc_impl(void *ptr, size_t size)
|
|||
{
|
||||
void *ret;
|
||||
|
||||
DARWIN_ONLY(return (szone->realloc)(szone, ptr, size));
|
||||
|
||||
if (size == 0) {
|
||||
#ifdef MALLOC_SYSV
|
||||
if (opt_sysv == false)
|
||||
|
@ -6494,8 +6381,6 @@ free_impl(void *ptr)
|
|||
{
|
||||
size_t offset;
|
||||
|
||||
DARWIN_ONLY((szone->free)(szone, ptr); return);
|
||||
|
||||
UTRACE(ptr, 0, 0);
|
||||
|
||||
/*
|
||||
|
@ -6519,12 +6404,7 @@ free_impl(void *ptr)
|
|||
*/
|
||||
|
||||
/* This was added by Mozilla for use by SQLite. */
|
||||
#if defined(MOZ_MEMORY_DARWIN) && !defined(MOZ_REPLACE_MALLOC)
|
||||
static
|
||||
#else
|
||||
MOZ_MEMORY_API
|
||||
#endif
|
||||
size_t
|
||||
MOZ_MEMORY_API size_t
|
||||
malloc_good_size_impl(size_t size)
|
||||
{
|
||||
/*
|
||||
|
@ -6566,8 +6446,6 @@ malloc_good_size_impl(size_t size)
|
|||
MOZ_MEMORY_API size_t
|
||||
malloc_usable_size_impl(MALLOC_USABLE_SIZE_CONST_PTR void *ptr)
|
||||
{
|
||||
DARWIN_ONLY(return (szone->size)(szone, ptr));
|
||||
|
||||
#ifdef MALLOC_VALIDATE
|
||||
return (isalloc_validate(ptr));
|
||||
#else
|
||||
|
@ -6885,7 +6763,10 @@ jemalloc_free_dirty_pages_impl(void)
|
|||
* is threaded here.
|
||||
*/
|
||||
|
||||
static void
|
||||
#ifndef MOZ_MEMORY_DARWIN
|
||||
static
|
||||
#endif
|
||||
void
|
||||
_malloc_prefork(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
@ -6903,8 +6784,11 @@ _malloc_prefork(void)
|
|||
malloc_mutex_lock(&huge_mtx);
|
||||
}
|
||||
|
||||
static void
|
||||
_malloc_postfork(void)
|
||||
#ifndef MOZ_MEMORY_DARWIN
|
||||
static
|
||||
#endif
|
||||
void
|
||||
_malloc_postfork_parent(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
|
@ -6921,6 +6805,27 @@ _malloc_postfork(void)
|
|||
malloc_spin_unlock(&arenas_lock);
|
||||
}
|
||||
|
||||
#ifndef MOZ_MEMORY_DARWIN
|
||||
static
|
||||
#endif
|
||||
void
|
||||
_malloc_postfork_child(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* Reinitialize all mutexes, now that fork() has completed. */
|
||||
|
||||
malloc_mutex_init(&huge_mtx);
|
||||
|
||||
malloc_mutex_init(&base_mtx);
|
||||
|
||||
for (i = 0; i < narenas; i++) {
|
||||
if (arenas[i] != NULL)
|
||||
malloc_spin_init(&arenas[i]->lock);
|
||||
}
|
||||
malloc_spin_init(&arenas_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* End library-private functions.
|
||||
*/
|
||||
|
@ -6932,254 +6837,6 @@ _malloc_postfork(void)
|
|||
|
||||
#if defined(MOZ_MEMORY_DARWIN)
|
||||
|
||||
#if !defined(MOZ_REPLACE_MALLOC)
|
||||
static void *
|
||||
zone_malloc(malloc_zone_t *zone, size_t size)
|
||||
{
|
||||
|
||||
return (malloc_impl(size));
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_calloc(malloc_zone_t *zone, size_t num, size_t size)
|
||||
{
|
||||
|
||||
return (calloc_impl(num, size));
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_valloc(malloc_zone_t *zone, size_t size)
|
||||
{
|
||||
void *ret = NULL; /* Assignment avoids useless compiler warning. */
|
||||
|
||||
posix_memalign_impl(&ret, pagesize, size);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size)
|
||||
{
|
||||
return (memalign_impl(alignment, size));
|
||||
}
|
||||
|
||||
static void *
|
||||
zone_destroy(malloc_zone_t *zone)
|
||||
{
|
||||
|
||||
/* This function should never be called. */
|
||||
assert(false);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static size_t
|
||||
zone_good_size(malloc_zone_t *zone, size_t size)
|
||||
{
|
||||
return malloc_good_size_impl(size);
|
||||
}
|
||||
|
||||
static size_t
|
||||
ozone_size(malloc_zone_t *zone, void *ptr)
|
||||
{
|
||||
size_t ret = isalloc_validate(ptr);
|
||||
if (ret == 0)
|
||||
ret = szone->size(zone, ptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
ozone_free(malloc_zone_t *zone, void *ptr)
|
||||
{
|
||||
if (isalloc_validate(ptr) != 0)
|
||||
free_impl(ptr);
|
||||
else {
|
||||
size_t size = szone->size(zone, ptr);
|
||||
if (size != 0)
|
||||
(szone->free)(zone, ptr);
|
||||
/* Otherwise we leak. */
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
ozone_realloc(malloc_zone_t *zone, void *ptr, size_t size)
|
||||
{
|
||||
size_t oldsize;
|
||||
if (ptr == NULL)
|
||||
return (malloc_impl(size));
|
||||
|
||||
oldsize = isalloc_validate(ptr);
|
||||
if (oldsize != 0)
|
||||
return (realloc_impl(ptr, size));
|
||||
else {
|
||||
oldsize = szone->size(zone, ptr);
|
||||
if (oldsize == 0)
|
||||
return (malloc_impl(size));
|
||||
else {
|
||||
void *ret = malloc_impl(size);
|
||||
if (ret != NULL) {
|
||||
memcpy(ret, ptr, (oldsize < size) ? oldsize :
|
||||
size);
|
||||
(szone->free)(zone, ptr);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned
|
||||
ozone_batch_malloc(malloc_zone_t *zone, size_t size, void **results,
|
||||
unsigned num_requested)
|
||||
{
|
||||
/* Don't bother implementing this interface, since it isn't required. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ozone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsigned num)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
ozone_free(zone, to_be_freed[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
ozone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size)
|
||||
{
|
||||
if (isalloc_validate(ptr) != 0) {
|
||||
assert(isalloc_validate(ptr) == size);
|
||||
free_impl(ptr);
|
||||
} else {
|
||||
assert(size == szone->size(zone, ptr));
|
||||
l_szone.m16(zone, ptr, size);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ozone_force_lock(malloc_zone_t *zone)
|
||||
{
|
||||
_malloc_prefork();
|
||||
szone->introspect->force_lock(zone);
|
||||
}
|
||||
|
||||
static void
|
||||
ozone_force_unlock(malloc_zone_t *zone)
|
||||
{
|
||||
szone->introspect->force_unlock(zone);
|
||||
_malloc_postfork();
|
||||
}
|
||||
|
||||
static size_t
|
||||
zone_version_size(int version)
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case SNOW_LEOPARD_MALLOC_ZONE_T_VERSION:
|
||||
return sizeof(snow_leopard_malloc_zone);
|
||||
case LEOPARD_MALLOC_ZONE_T_VERSION:
|
||||
return sizeof(leopard_malloc_zone);
|
||||
default:
|
||||
case LION_MALLOC_ZONE_T_VERSION:
|
||||
return sizeof(lion_malloc_zone);
|
||||
}
|
||||
}
|
||||
|
||||
static malloc_zone_t *get_default_zone()
|
||||
{
|
||||
malloc_zone_t **zones = NULL;
|
||||
unsigned int num_zones = 0;
|
||||
|
||||
/*
|
||||
* On OSX 10.12, malloc_default_zone returns a special zone that is not
|
||||
* present in the list of registered zones. That zone uses a "lite zone"
|
||||
* if one is present (apparently enabled when malloc stack logging is
|
||||
* enabled), or the first registered zone otherwise. In practice this
|
||||
* means unless malloc stack logging is enabled, the first registered
|
||||
* zone is the default.
|
||||
* So get the list of zones to get the first one, instead of relying on
|
||||
* malloc_default_zone.
|
||||
*/
|
||||
if (KERN_SUCCESS != malloc_get_all_zones(0, NULL, (vm_address_t**) &zones,
|
||||
&num_zones)) {
|
||||
/* Reset the value in case the failure happened after it was set. */
|
||||
num_zones = 0;
|
||||
}
|
||||
if (num_zones) {
|
||||
return zones[0];
|
||||
}
|
||||
return malloc_default_zone();
|
||||
}
|
||||
|
||||
/*
|
||||
* Overlay the default scalable zone (szone) such that existing allocations are
|
||||
* drained, and further allocations come from jemalloc. This is necessary
|
||||
* because Core Foundation directly accesses and uses the szone before the
|
||||
* jemalloc library is even loaded.
|
||||
*/
|
||||
static void
|
||||
szone2ozone(malloc_zone_t *default_zone, size_t size)
|
||||
{
|
||||
lion_malloc_zone *l_zone;
|
||||
assert(malloc_initialized);
|
||||
|
||||
/*
|
||||
* Stash a copy of the original szone so that we can call its
|
||||
* functions as needed. Note that internally, the szone stores its
|
||||
* bookkeeping data structures immediately following the malloc_zone_t
|
||||
* header, so when calling szone functions, we need to pass a pointer to
|
||||
* the original zone structure.
|
||||
*/
|
||||
memcpy(szone, default_zone, size);
|
||||
|
||||
/* OSX 10.7 allocates the default zone in protected memory. */
|
||||
if (default_zone->version >= LION_MALLOC_ZONE_T_VERSION) {
|
||||
void* start_of_page = (void*)((size_t)(default_zone) & ~pagesize_mask);
|
||||
mprotect (start_of_page, size, PROT_READ | PROT_WRITE);
|
||||
}
|
||||
|
||||
default_zone->size = (void *)ozone_size;
|
||||
default_zone->malloc = (void *)zone_malloc;
|
||||
default_zone->calloc = (void *)zone_calloc;
|
||||
default_zone->valloc = (void *)zone_valloc;
|
||||
default_zone->free = (void *)ozone_free;
|
||||
default_zone->realloc = (void *)ozone_realloc;
|
||||
default_zone->destroy = (void *)zone_destroy;
|
||||
default_zone->batch_malloc = NULL;
|
||||
default_zone->batch_free = ozone_batch_free;
|
||||
default_zone->introspect = ozone_introspect;
|
||||
|
||||
/* Don't modify default_zone->zone_name; Mac libc may rely on the name
|
||||
* being unchanged. See Mozilla bug 694896. */
|
||||
|
||||
ozone_introspect->enumerator = NULL;
|
||||
ozone_introspect->good_size = (void *)zone_good_size;
|
||||
ozone_introspect->check = NULL;
|
||||
ozone_introspect->print = NULL;
|
||||
ozone_introspect->log = NULL;
|
||||
ozone_introspect->force_lock = (void *)ozone_force_lock;
|
||||
ozone_introspect->force_unlock = (void *)ozone_force_unlock;
|
||||
ozone_introspect->statistics = NULL;
|
||||
|
||||
/* Platform-dependent structs */
|
||||
l_zone = (lion_malloc_zone*)(default_zone);
|
||||
|
||||
if (default_zone->version >= SNOW_LEOPARD_MALLOC_ZONE_T_VERSION) {
|
||||
l_zone->m15 = (void (*)())zone_memalign;
|
||||
l_zone->m16 = (void (*)())ozone_free_definite_size;
|
||||
l_ozone_introspect.m9 = NULL;
|
||||
}
|
||||
|
||||
if (default_zone->version >= LION_MALLOC_ZONE_T_VERSION) {
|
||||
l_zone->m17 = NULL;
|
||||
l_ozone_introspect.m10 = NULL;
|
||||
l_ozone_introspect.m11 = NULL;
|
||||
l_ozone_introspect.m12 = NULL;
|
||||
l_ozone_introspect.m13 = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
__attribute__((constructor))
|
||||
void
|
||||
jemalloc_darwin_init(void)
|
||||
|
|
|
@ -1,147 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 8; c-basic-offset: 8 -*- */
|
||||
/* vim:set softtabstop=8 shiftwidth=8: */
|
||||
/*-
|
||||
* Copyright (C) 2006-2008 Jason Evans <jasone@FreeBSD.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice(s), this list of conditions and the following disclaimer as
|
||||
* the first lines of this file unmodified other than the possible
|
||||
* addition of one or more copyright notices.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice(s), this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The purpose of these structs is described in jemalloc.c, in the comment
|
||||
* marked MALLOC_ZONE_T_NOTE.
|
||||
*
|
||||
* We need access to some structs that come with a specific version of OSX
|
||||
* but can't copy them here because of licensing restrictions (see bug
|
||||
* 603655). The structs below are equivalent in that they'll always be
|
||||
* compiled to the same representation on all platforms.
|
||||
*
|
||||
* `void*` and `void (*)()` may not be the same size on weird platforms, but
|
||||
* the size of a function pointer shouldn't vary according to its parameters
|
||||
* or return type.
|
||||
*
|
||||
* Apple's version of these structures, complete with member names and
|
||||
* comments, is available online at
|
||||
*
|
||||
* http://www.opensource.apple.com/source/Libc/Libc-763.12/include/malloc/malloc.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* OSX 10.5 - Leopard
|
||||
*/
|
||||
typedef struct _leopard_malloc_zone {
|
||||
void *m1;
|
||||
void *m2;
|
||||
void (*m3)();
|
||||
void (*m4)();
|
||||
void (*m5)();
|
||||
void (*m6)();
|
||||
void (*m7)();
|
||||
void (*m8)();
|
||||
void (*m9)();
|
||||
void *m10;
|
||||
void (*m11)();
|
||||
void (*m12)();
|
||||
void *m13;
|
||||
unsigned m14;
|
||||
} leopard_malloc_zone;
|
||||
|
||||
/*
|
||||
* OSX 10.6 - Snow Leopard
|
||||
*/
|
||||
typedef struct _snow_leopard_malloc_zone {
|
||||
void *m1;
|
||||
void *m2;
|
||||
void (*m3)();
|
||||
void (*m4)();
|
||||
void (*m5)();
|
||||
void (*m6)();
|
||||
void (*m7)();
|
||||
void (*m8)();
|
||||
void (*m9)();
|
||||
void *m10;
|
||||
void (*m11)();
|
||||
void (*m12)();
|
||||
void *m13;
|
||||
unsigned m14;
|
||||
void (*m15)(); // this member added in 10.6
|
||||
void (*m16)(); // this member added in 10.6
|
||||
} snow_leopard_malloc_zone;
|
||||
|
||||
typedef struct _snow_leopard_malloc_introspection {
|
||||
void (*m1)();
|
||||
void (*m2)();
|
||||
void (*m3)();
|
||||
void (*m4)();
|
||||
void (*m5)();
|
||||
void (*m6)();
|
||||
void (*m7)();
|
||||
void (*m8)();
|
||||
void (*m9)(); // this member added in 10.6
|
||||
} snow_leopard_malloc_introspection;
|
||||
|
||||
/*
|
||||
* OSX 10.7 - Lion
|
||||
*/
|
||||
typedef struct _lion_malloc_zone {
|
||||
void *m1;
|
||||
void *m2;
|
||||
void (*m3)();
|
||||
void (*m4)();
|
||||
void (*m5)();
|
||||
void (*m6)();
|
||||
void (*m7)();
|
||||
void (*m8)();
|
||||
void (*m9)();
|
||||
void *m10;
|
||||
void (*m11)();
|
||||
void (*m12)();
|
||||
void *m13;
|
||||
unsigned m14;
|
||||
void (*m15)();
|
||||
void (*m16)();
|
||||
void (*m17)(); // this member added in 10.7
|
||||
} lion_malloc_zone;
|
||||
|
||||
typedef struct _lion_malloc_introspection {
|
||||
void (*m1)();
|
||||
void (*m2)();
|
||||
void (*m3)();
|
||||
void (*m4)();
|
||||
void (*m5)();
|
||||
void (*m6)();
|
||||
void (*m7)();
|
||||
void (*m8)();
|
||||
void (*m9)();
|
||||
void (*m10)(); // this member added in 10.7
|
||||
void (*m11)(); // this member added in 10.7
|
||||
void (*m12)(); // this member added in 10.7
|
||||
#ifdef __BLOCKS__
|
||||
void (*m13)(); // this member added in 10.7
|
||||
#else
|
||||
void *m13; // this member added in 10.7
|
||||
#endif
|
||||
} lion_malloc_introspection;
|
|
@ -741,6 +741,7 @@ public class BrowserApp extends GeckoApp
|
|||
"CharEncoding:State",
|
||||
"Settings:Show",
|
||||
"Updater:Launch",
|
||||
"Sanitize:OpenTabs",
|
||||
null);
|
||||
|
||||
EventDispatcher.getInstance().registerBackgroundThreadListener(this,
|
||||
|
@ -1454,6 +1455,7 @@ public class BrowserApp extends GeckoApp
|
|||
"CharEncoding:State",
|
||||
"Settings:Show",
|
||||
"Updater:Launch",
|
||||
"Sanitize:OpenTabs",
|
||||
null);
|
||||
|
||||
EventDispatcher.getInstance().unregisterBackgroundThreadListener(this,
|
||||
|
@ -1914,6 +1916,11 @@ public class BrowserApp extends GeckoApp
|
|||
settings.edit().putInt(getPackageName() + ".feedback_launch_count", 0).apply();
|
||||
break;
|
||||
|
||||
case "Sanitize:OpenTabs":
|
||||
Tabs.getInstance().closeAll();
|
||||
callback.sendSuccess(null);
|
||||
break;
|
||||
|
||||
case "Sanitize:ClearHistory":
|
||||
BrowserDB.from(getProfile()).clearHistory(
|
||||
getContentResolver(), message.getBoolean("clearSearchHistory", false));
|
||||
|
|
|
@ -585,17 +585,20 @@ public abstract class GeckoApp
|
|||
Log.e(LOGTAG, "Error adding sanitize object", ex);
|
||||
}
|
||||
|
||||
// If the user has opted out of session restore, and does want to clear history
|
||||
// If the user wants to clear open tabs, or else has opted out of session restore and does want to clear history,
|
||||
// we also want to prevent the current session info from being saved.
|
||||
if (clearObj.has("private.data.history")) {
|
||||
final String sessionRestore = getSessionRestorePreference(getSharedPreferences());
|
||||
try {
|
||||
res.put("dontSaveSession", "quit".equals(sessionRestore));
|
||||
} catch (JSONException ex) {
|
||||
Log.e(LOGTAG, "Error adding session restore data", ex);
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (clearObj.has("private.data.openTabs")) {
|
||||
res.put("dontSaveSession", true);
|
||||
} else if (clearObj.has("private.data.history")) {
|
||||
|
||||
final String sessionRestore = getSessionRestorePreference(getSharedPreferences());
|
||||
res.put("dontSaveSession", "quit".equals(sessionRestore));
|
||||
|
||||
}
|
||||
} catch (JSONException ex) {
|
||||
Log.e(LOGTAG, "Error adding session restore data", ex);
|
||||
}
|
||||
GeckoAppShell.notifyObservers("Browser:Quit", res.toString());
|
||||
// We don't call doShutdown() here because this creates a race condition which can
|
||||
// cause the clearing of private data to fail. Instead, we shut down the UI only after
|
||||
|
|
|
@ -85,6 +85,12 @@ public class Tabs implements BundleEventListener {
|
|||
private PersistTabsRunnable mPersistTabsRunnable;
|
||||
private int mPrivateClearColor;
|
||||
|
||||
public void closeAll() {
|
||||
for (final Tab tab : mOrder) {
|
||||
Tabs.getInstance().closeTab(tab, false);
|
||||
}
|
||||
}
|
||||
|
||||
private static class PersistTabsRunnable implements Runnable {
|
||||
private final BrowserDB db;
|
||||
private final Context context;
|
||||
|
|
|
@ -225,8 +225,13 @@ public class HomePager extends ViewPager implements HomeScreen {
|
|||
// list of panels in place.
|
||||
mTabStrip.setVisibility(View.INVISIBLE);
|
||||
|
||||
// Load list of panels from configuration
|
||||
lm.initLoader(LOADER_ID_CONFIG, null, mConfigLoaderCallbacks);
|
||||
// If HomeConfigLoader already exist, force load to select the current item
|
||||
if (lm.getLoader(LOADER_ID_CONFIG) != null) {
|
||||
lm.getLoader(LOADER_ID_CONFIG).forceLoad();
|
||||
} else {
|
||||
// Load list of panels from configuration
|
||||
lm.initLoader(LOADER_ID_CONFIG, null, mConfigLoaderCallbacks);
|
||||
}
|
||||
|
||||
if (shouldAnimate) {
|
||||
animator.addPropertyAnimationListener(new PropertyAnimator.PropertyAnimationListener() {
|
||||
|
|
|
@ -7,8 +7,6 @@ package org.mozilla.gecko.home.activitystream.menu;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.NavigationView;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
@ -82,6 +80,7 @@ public abstract class ActivityStreamContextMenu
|
|||
final MenuItem bookmarkItem = getItemByID(R.id.bookmark);
|
||||
if (Boolean.TRUE.equals(item.isBookmarked())) {
|
||||
bookmarkItem.setTitle(R.string.bookmark_remove);
|
||||
bookmarkItem.setIcon(R.drawable.as_bookmark_filled);
|
||||
}
|
||||
|
||||
final MenuItem pinItem = getItemByID(R.id.pin);
|
||||
|
@ -111,6 +110,7 @@ public abstract class ActivityStreamContextMenu
|
|||
protected void onPostExecute(Boolean hasBookmark) {
|
||||
if (hasBookmark) {
|
||||
bookmarkItem.setTitle(R.string.bookmark_remove);
|
||||
bookmarkItem.setIcon(R.drawable.as_bookmark_filled);
|
||||
}
|
||||
|
||||
item.updateBookmarked(hasBookmark);
|
||||
|
|
|
@ -54,12 +54,13 @@ public class FadedMultiColorTextView extends FadedTextView {
|
|||
|
||||
updateGradientShader(needsEllipsis, right);
|
||||
|
||||
final float center = getHeight() / 2;
|
||||
|
||||
// Shrink height of gradient to prevent it overlaying parent view border.
|
||||
// The shrunk size just nee to cover the text itself.
|
||||
final float top = center - getTextSize() / 2;
|
||||
final float bottom = center + getTextSize() / 2;
|
||||
final float density = getResources().getDisplayMetrics().density;
|
||||
final float h = Math.abs(fadePaint.getFontMetrics().top) + 1;
|
||||
final float l = fadePaint.getFontMetrics().bottom + 1;
|
||||
final float top = getBaseline() - h * density;
|
||||
final float bottom = getBaseline() + l * density;
|
||||
|
||||
canvas.drawRect(left, top, right, bottom, fadePaint);
|
||||
}
|
||||
|
|
|
@ -387,6 +387,7 @@ size. -->
|
|||
<!ENTITY pref_history_search_suggestions "Show search history">
|
||||
<!ENTITY pref_import_options "Import options">
|
||||
<!ENTITY pref_import_android_summary "Import bookmarks and history from the native browser">
|
||||
<!ENTITY pref_private_data_openTabs "Open tabs">
|
||||
<!ENTITY pref_private_data_history2 "Browsing history">
|
||||
<!ENTITY pref_private_data_searchHistory "Search history">
|
||||
<!ENTITY pref_private_data_formdata2 "Form history">
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12.01,1C11.508,1.068 11.087,1.415 10.925,1.895L8.178,7.562L2.301,8.552C0.956,8.771 0.622,9.738 1.557,10.7L5.717,15.186L4.748,21.497C4.601,22.445 4.99,22.997 5.673,22.997C5.985,22.985 6.291,22.899 6.564,22.748L12.021,19.817L17.542,22.748C17.816,22.9 18.121,22.985 18.434,22.997C19.117,22.997 19.504,22.442 19.36,21.497L18.394,15.186L22.505,10.705C23.441,9.739 23.105,8.771 21.761,8.552L15.972,7.562L13.1,1.9C12.939,1.416 12.516,1.067 12.01,1L12.01,1Z"/>
|
||||
</vector>
|
|
@ -78,6 +78,7 @@
|
|||
<item>android_import.data.history</item>
|
||||
</string-array>
|
||||
<string-array name="pref_private_data_entries">
|
||||
<item>@string/pref_private_data_openTabs</item>
|
||||
<item>@string/pref_private_data_history2</item>
|
||||
<item>@string/pref_private_data_searchHistory</item>
|
||||
<item>@string/pref_private_data_downloadFiles2</item>
|
||||
|
@ -99,9 +100,11 @@
|
|||
<item>true</item>
|
||||
<item>true</item>
|
||||
<item>true</item>
|
||||
<item>true</item>
|
||||
<item>false</item>
|
||||
</string-array>
|
||||
<string-array name="pref_private_data_values">
|
||||
<item>private.data.openTabs</item>
|
||||
<item>private.data.history</item>
|
||||
<item>private.data.searchHistory</item>
|
||||
<item>private.data.downloadFiles</item>
|
||||
|
@ -114,6 +117,7 @@
|
|||
<item>private.data.passwords</item>
|
||||
</string-array>
|
||||
<string-array name="pref_private_data_keys">
|
||||
<item>private.data.openTabs</item>
|
||||
<item>private.data.history</item>
|
||||
<item>private.data.searchHistory</item>
|
||||
<item>private.data.downloadFiles</item>
|
||||
|
@ -136,6 +140,7 @@
|
|||
<item>false</item>
|
||||
<item>false</item>
|
||||
<item>false</item>
|
||||
<item>false</item>
|
||||
</string-array>
|
||||
<string-array name="pref_restore_entries">
|
||||
<item>@string/pref_restore_always</item>
|
||||
|
|
|
@ -279,6 +279,7 @@
|
|||
<string name="pref_sync_summary">&pref_sync_summary2;</string>
|
||||
<string name="pref_search_suggestions">&pref_search_suggestions;</string>
|
||||
<string name="pref_history_search_suggestions">&pref_history_search_suggestions;</string>
|
||||
<string name="pref_private_data_openTabs">&pref_private_data_openTabs;</string>
|
||||
<string name="pref_private_data_history2">&pref_private_data_history2;</string>
|
||||
<string name="pref_private_data_searchHistory">&pref_private_data_searchHistory;</string>
|
||||
<string name="pref_private_data_formdata2">&pref_private_data_formdata2;</string>
|
||||
|
|
|
@ -1470,6 +1470,12 @@ var BrowserApp = {
|
|||
promises.push(Sanitizer.clearItem("cookies"));
|
||||
promises.push(Sanitizer.clearItem("sessions"));
|
||||
break;
|
||||
case "openTabs":
|
||||
if (aShutdown === true) {
|
||||
Services.obs.notifyObservers(null, "browser:purge-session-tabs", "");
|
||||
break;
|
||||
}
|
||||
// fall-through if aShutdown is false
|
||||
default:
|
||||
promises.push(Sanitizer.clearItem(key));
|
||||
}
|
||||
|
|
|
@ -180,6 +180,7 @@ SessionStore.prototype = {
|
|||
observerService.addObserver(this, "domwindowopened", true);
|
||||
observerService.addObserver(this, "domwindowclosed", true);
|
||||
observerService.addObserver(this, "browser:purge-session-history", true);
|
||||
observerService.addObserver(this, "browser:purge-session-tabs", true);
|
||||
observerService.addObserver(this, "quit-application-requested", true);
|
||||
observerService.addObserver(this, "quit-application-proceeding", true);
|
||||
observerService.addObserver(this, "quit-application", true);
|
||||
|
@ -236,8 +237,9 @@ SessionStore.prototype = {
|
|||
this._loadState = STATE_QUITTING_FLUSHED;
|
||||
|
||||
break;
|
||||
case "browser:purge-session-tabs":
|
||||
case "browser:purge-session-history": // catch sanitization
|
||||
log("browser:purge-session-history");
|
||||
log(aTopic);
|
||||
this._clearDisk();
|
||||
|
||||
// Clear all data about closed tabs
|
||||
|
@ -1780,6 +1782,12 @@ SessionStore.prototype = {
|
|||
},
|
||||
|
||||
_sendClosedTabsToJava: function ss_sendClosedTabsToJava(aWindow) {
|
||||
|
||||
// If the app is shutting down, we don't need to do anything.
|
||||
if (this._loadState <= STATE_QUITTING) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aWindow.__SSID) {
|
||||
throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
|
|
|
@ -9,3 +9,10 @@
|
|||
-keep public class * extends android.support.v4.view.ActionProvider {
|
||||
public <init>(android.content.Context);
|
||||
}
|
||||
|
||||
-keepclassmembers class android.support.graphics.drawable.VectorDrawableCompat$* {
|
||||
void set*(***);
|
||||
*** get*();
|
||||
}
|
||||
|
||||
-keepattributes LocalVariableTable
|
||||
|
|
|
@ -168,6 +168,26 @@ Sanitizer.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
openTabs: {
|
||||
clear: function ()
|
||||
{
|
||||
return EventDispatcher.instance.sendRequestForResult({ type: "Sanitize:OpenTabs" })
|
||||
.catch(e => Cu.reportError("Java-side tab clearing failed: " + e))
|
||||
.then(function() {
|
||||
try {
|
||||
// clear "Recently Closed" tabs in Android App
|
||||
Services.obs.notifyObservers(null, "browser:purge-session-tabs", "");
|
||||
}
|
||||
catch (e) { }
|
||||
});
|
||||
},
|
||||
|
||||
get canClear()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
searchHistory: {
|
||||
clear: function ()
|
||||
{
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
This form triggers a MP and gets filled in.<br>
|
||||
<form>
|
||||
Username: <input type="text" id="userfield" name="u"><br>
|
||||
Password: <input type="password" id="passfield" name="p"
|
||||
oninput="parent.postMessage('filled', '*');"><br>
|
||||
Password: <input type="password" id="passfield" name="p"><br>
|
||||
<script>
|
||||
// Only notify when we fill in the password field.
|
||||
document.getElementById("passfield").addEventListener("input", function() {
|
||||
parent.postMessage("filled", "*");
|
||||
});
|
||||
</script>
|
||||
</form>
|
||||
|
|
|
@ -1376,6 +1376,35 @@ var AddonManagerInternal = {
|
|||
return uri.replace(/\+/g, "%2B");
|
||||
},
|
||||
|
||||
_updatePromptHandler(info) {
|
||||
let oldPerms = info.existingAddon.userPermissions || {hosts: [], permissions: []};
|
||||
let newPerms = info.addon.userPermissions;
|
||||
|
||||
// See bug 1331769: should we do something more complicated to
|
||||
// compare host permissions?
|
||||
// e.g., if we go from <all_urls> to a specific host or from
|
||||
// a *.domain.com to specific-host.domain.com that's actually a
|
||||
// drop in permissions but the simple test below will cause a prompt.
|
||||
let difference = {
|
||||
hosts: newPerms.hosts.filter(perm => !oldPerms.hosts.includes(perm)),
|
||||
permissions: newPerms.permissions.filter(perm => !oldPerms.permissions.includes(perm)),
|
||||
};
|
||||
|
||||
// If there are no new permissions, just go ahead with the update
|
||||
if (difference.hosts.length == 0 && difference.permissions.length == 0) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let subject = {wrappedJSObject: {
|
||||
addon: info.addon,
|
||||
permissions: difference,
|
||||
resolve, reject
|
||||
}};
|
||||
Services.obs.notifyObservers(subject, "webextension-update-permissions", null);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Performs a background update check by starting an update for all add-ons
|
||||
* that can be updated.
|
||||
|
@ -1430,6 +1459,9 @@ var AddonManagerInternal = {
|
|||
// XXX we really should resolve when this install is done,
|
||||
// not when update-available check completes, no?
|
||||
logger.debug(`Starting upgrade install of ${aAddon.id}`);
|
||||
if (WEBEXT_PERMISSION_PROMPTS) {
|
||||
aInstall.promptHandler = (...args) => AddonManagerInternal._updatePromptHandler(...args);
|
||||
}
|
||||
aInstall.install();
|
||||
}
|
||||
},
|
||||
|
|
|
@ -508,6 +508,10 @@ public:
|
|||
*/
|
||||
bool HasPluginActivationEventMessage() const;
|
||||
|
||||
/**
|
||||
* Returns true if the event can be sent to remote process.
|
||||
*/
|
||||
bool CanBeSentToRemoteProcess() const;
|
||||
/**
|
||||
* Returns true if the event is native event deliverer event for plugin and
|
||||
* it should be retarted to focused document.
|
||||
|
|
|
@ -306,40 +306,40 @@ PuppetWidget::Invalidate(const LayoutDeviceIntRect& aRect)
|
|||
}
|
||||
|
||||
void
|
||||
PuppetWidget::InitEvent(WidgetGUIEvent& event, LayoutDeviceIntPoint* aPoint)
|
||||
PuppetWidget::InitEvent(WidgetGUIEvent& aEvent, LayoutDeviceIntPoint* aPoint)
|
||||
{
|
||||
if (nullptr == aPoint) {
|
||||
event.mRefPoint = LayoutDeviceIntPoint(0, 0);
|
||||
aEvent.mRefPoint = LayoutDeviceIntPoint(0, 0);
|
||||
} else {
|
||||
// use the point override if provided
|
||||
event.mRefPoint = *aPoint;
|
||||
aEvent.mRefPoint = *aPoint;
|
||||
}
|
||||
event.mTime = PR_Now() / 1000;
|
||||
aEvent.mTime = PR_Now() / 1000;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PuppetWidget::DispatchEvent(WidgetGUIEvent* event, nsEventStatus& aStatus)
|
||||
PuppetWidget::DispatchEvent(WidgetGUIEvent* aEvent, nsEventStatus& aStatus)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
debug_DumpEvent(stdout, event->mWidget, event, "PuppetWidget", 0);
|
||||
debug_DumpEvent(stdout, aEvent->mWidget, aEvent, "PuppetWidget", 0);
|
||||
#endif
|
||||
|
||||
MOZ_ASSERT(!mChild || mChild->mWindowType == eWindowType_popup,
|
||||
"Unexpected event dispatch!");
|
||||
|
||||
AutoCacheNativeKeyCommands autoCache(this);
|
||||
if ((event->mFlags.mIsSynthesizedForTests ||
|
||||
event->mFlags.mIsSuppressedOrDelayed) && !mNativeKeyCommandsValid) {
|
||||
WidgetKeyboardEvent* keyEvent = event->AsKeyboardEvent();
|
||||
if ((aEvent->mFlags.mIsSynthesizedForTests ||
|
||||
aEvent->mFlags.mIsSuppressedOrDelayed) && !mNativeKeyCommandsValid) {
|
||||
WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
|
||||
if (keyEvent) {
|
||||
mTabChild->RequestNativeKeyBindings(&autoCache, keyEvent);
|
||||
}
|
||||
}
|
||||
|
||||
if (event->mClass == eCompositionEventClass) {
|
||||
if (aEvent->mClass == eCompositionEventClass) {
|
||||
// Store the latest native IME context of parent process's widget or
|
||||
// TextEventDispatcher if it's in this process.
|
||||
WidgetCompositionEvent* compositionEvent = event->AsCompositionEvent();
|
||||
WidgetCompositionEvent* compositionEvent = aEvent->AsCompositionEvent();
|
||||
#ifdef DEBUG
|
||||
if (mNativeIMEContext.IsValid() &&
|
||||
mNativeIMEContext != compositionEvent->mNativeIMEContext) {
|
||||
|
@ -357,7 +357,8 @@ PuppetWidget::DispatchEvent(WidgetGUIEvent* event, nsEventStatus& aStatus)
|
|||
aStatus = nsEventStatus_eIgnore;
|
||||
|
||||
if (GetCurrentWidgetListener()) {
|
||||
aStatus = GetCurrentWidgetListener()->HandleEvent(event, mUseAttachedEvents);
|
||||
aStatus =
|
||||
GetCurrentWidgetListener()->HandleEvent(aEvent, mUseAttachedEvents);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -409,8 +410,9 @@ PuppetWidget::SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mTabChild->SendSynthesizeNativeKeyEvent(aNativeKeyboardLayout, aNativeKeyCode,
|
||||
aModifierFlags, nsString(aCharacters), nsString(aUnmodifiedCharacters),
|
||||
notifier.SaveObserver());
|
||||
aModifierFlags, nsString(aCharacters),
|
||||
nsString(aUnmodifiedCharacters),
|
||||
notifier.SaveObserver());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -425,7 +427,8 @@ PuppetWidget::SynthesizeNativeMouseEvent(mozilla::LayoutDeviceIntPoint aPoint,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mTabChild->SendSynthesizeNativeMouseEvent(aPoint, aNativeMessage,
|
||||
aModifierFlags, notifier.SaveObserver());
|
||||
aModifierFlags,
|
||||
notifier.SaveObserver());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -442,22 +445,25 @@ PuppetWidget::SynthesizeNativeMouseMove(mozilla::LayoutDeviceIntPoint aPoint,
|
|||
}
|
||||
|
||||
nsresult
|
||||
PuppetWidget::SynthesizeNativeMouseScrollEvent(mozilla::LayoutDeviceIntPoint aPoint,
|
||||
uint32_t aNativeMessage,
|
||||
double aDeltaX,
|
||||
double aDeltaY,
|
||||
double aDeltaZ,
|
||||
uint32_t aModifierFlags,
|
||||
uint32_t aAdditionalFlags,
|
||||
nsIObserver* aObserver)
|
||||
PuppetWidget::SynthesizeNativeMouseScrollEvent(
|
||||
mozilla::LayoutDeviceIntPoint aPoint,
|
||||
uint32_t aNativeMessage,
|
||||
double aDeltaX,
|
||||
double aDeltaY,
|
||||
double aDeltaZ,
|
||||
uint32_t aModifierFlags,
|
||||
uint32_t aAdditionalFlags,
|
||||
nsIObserver* aObserver)
|
||||
{
|
||||
AutoObserverNotifier notifier(aObserver, "mousescrollevent");
|
||||
if (!mTabChild) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mTabChild->SendSynthesizeNativeMouseScrollEvent(aPoint, aNativeMessage,
|
||||
aDeltaX, aDeltaY, aDeltaZ, aModifierFlags, aAdditionalFlags,
|
||||
notifier.SaveObserver());
|
||||
aDeltaX, aDeltaY, aDeltaZ,
|
||||
aModifierFlags,
|
||||
aAdditionalFlags,
|
||||
notifier.SaveObserver());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -474,8 +480,9 @@ PuppetWidget::SynthesizeNativeTouchPoint(uint32_t aPointerId,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mTabChild->SendSynthesizeNativeTouchPoint(aPointerId, aPointerState,
|
||||
aPoint, aPointerPressure, aPointerOrientation,
|
||||
notifier.SaveObserver());
|
||||
aPoint, aPointerPressure,
|
||||
aPointerOrientation,
|
||||
notifier.SaveObserver());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -489,7 +496,7 @@ PuppetWidget::SynthesizeNativeTouchTap(LayoutDeviceIntPoint aPoint,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mTabChild->SendSynthesizeNativeTouchTap(aPoint, aLongTap,
|
||||
notifier.SaveObserver());
|
||||
notifier.SaveObserver());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -505,8 +512,9 @@ PuppetWidget::ClearNativeTouchSequence(nsIObserver* aObserver)
|
|||
}
|
||||
|
||||
void
|
||||
PuppetWidget::SetConfirmedTargetAPZC(uint64_t aInputBlockId,
|
||||
const nsTArray<ScrollableLayerGuid>& aTargets) const
|
||||
PuppetWidget::SetConfirmedTargetAPZC(
|
||||
uint64_t aInputBlockId,
|
||||
const nsTArray<ScrollableLayerGuid>& aTargets) const
|
||||
{
|
||||
if (mTabChild) {
|
||||
mTabChild->SetTargetAPZC(aInputBlockId, aTargets);
|
||||
|
@ -530,15 +538,12 @@ PuppetWidget::AsyncPanZoomEnabled() const
|
|||
}
|
||||
|
||||
bool
|
||||
PuppetWidget::ExecuteNativeKeyBinding(NativeKeyBindingsType aType,
|
||||
const mozilla::WidgetKeyboardEvent& aEvent,
|
||||
DoCommandCallback aCallback,
|
||||
void* aCallbackData)
|
||||
PuppetWidget::ExecuteNativeKeyBinding(
|
||||
NativeKeyBindingsType aType,
|
||||
const mozilla::WidgetKeyboardEvent& aEvent,
|
||||
DoCommandCallback aCallback,
|
||||
void* aCallbackData)
|
||||
{
|
||||
// B2G doesn't have native key bindings.
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
return false;
|
||||
#else // #ifdef MOZ_WIDGET_GONK
|
||||
AutoCacheNativeKeyCommands autoCache(this);
|
||||
if (!aEvent.mWidget && !mNativeKeyCommandsValid) {
|
||||
MOZ_ASSERT(!aEvent.mFlags.mIsSynthesizedForTests);
|
||||
|
@ -575,7 +580,6 @@ PuppetWidget::ExecuteNativeKeyBinding(NativeKeyBindingsType aType,
|
|||
aCallback(static_cast<mozilla::Command>((*commands)[i]), aCallbackData);
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
LayerManager*
|
||||
|
@ -606,7 +610,6 @@ PuppetWidget::RecreateLayerManager(PLayerTransactionChild* aShadowManager)
|
|||
nsresult
|
||||
PuppetWidget::RequestIMEToCommitComposition(bool aCancel)
|
||||
{
|
||||
#ifdef MOZ_CROSS_PROCESS_IME
|
||||
if (!mTabChild) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -646,9 +649,6 @@ PuppetWidget::RequestIMEToCommitComposition(bool aCancel)
|
|||
DispatchEvent(&compositionCommitEvent, status);
|
||||
|
||||
// NOTE: PuppetWidget might be destroyed already.
|
||||
|
||||
#endif // #ifdef MOZ_CROSS_PROCESS_IME
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -717,11 +717,6 @@ PuppetWidget::SetInputContext(const InputContext& aContext,
|
|||
// can be changed by user but native IME may not notify us of changing the
|
||||
// open state on some platforms.
|
||||
mInputContext.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED;
|
||||
|
||||
#ifndef MOZ_CROSS_PROCESS_IME
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (!mTabChild) {
|
||||
return;
|
||||
}
|
||||
|
@ -738,10 +733,6 @@ PuppetWidget::SetInputContext(const InputContext& aContext,
|
|||
InputContext
|
||||
PuppetWidget::GetInputContext()
|
||||
{
|
||||
#ifndef MOZ_CROSS_PROCESS_IME
|
||||
return InputContext();
|
||||
#endif
|
||||
|
||||
// XXX Currently, we don't support retrieving IME open state from child
|
||||
// process.
|
||||
|
||||
|
@ -777,12 +768,9 @@ PuppetWidget::GetNativeIMEContext()
|
|||
nsresult
|
||||
PuppetWidget::NotifyIMEOfFocusChange(const IMENotification& aIMENotification)
|
||||
{
|
||||
#ifndef MOZ_CROSS_PROCESS_IME
|
||||
return NS_OK;
|
||||
#endif
|
||||
|
||||
if (!mTabChild)
|
||||
if (!mTabChild) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
bool gotFocus = aIMENotification.mMessage == NOTIFY_IME_OF_FOCUS;
|
||||
if (gotFocus) {
|
||||
|
@ -816,11 +804,9 @@ nsresult
|
|||
PuppetWidget::NotifyIMEOfCompositionUpdate(
|
||||
const IMENotification& aIMENotification)
|
||||
{
|
||||
#ifndef MOZ_CROSS_PROCESS_IME
|
||||
return NS_OK;
|
||||
#endif
|
||||
|
||||
NS_ENSURE_TRUE(mTabChild, NS_ERROR_FAILURE);
|
||||
if (NS_WARN_IF(!mTabChild)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (mInputContext.mIMEState.mEnabled != IMEState::PLUGIN &&
|
||||
NS_WARN_IF(!mContentCache.CacheSelection(this, &aIMENotification))) {
|
||||
|
@ -833,7 +819,6 @@ PuppetWidget::NotifyIMEOfCompositionUpdate(
|
|||
nsIMEUpdatePreference
|
||||
PuppetWidget::GetIMEUpdatePreference()
|
||||
{
|
||||
#ifdef MOZ_CROSS_PROCESS_IME
|
||||
// e10s requires IME content cache in in the TabParent for handling query
|
||||
// content event only with the parent process. Therefore, this process
|
||||
// needs to receive a lot of information from the focused editor to sent
|
||||
|
@ -848,10 +833,6 @@ PuppetWidget::GetIMEUpdatePreference()
|
|||
return nsIMEUpdatePreference(mIMEPreferenceOfParent.mWantUpdates |
|
||||
nsIMEUpdatePreference::NOTIFY_TEXT_CHANGE |
|
||||
nsIMEUpdatePreference::NOTIFY_POSITION_CHANGE );
|
||||
#else
|
||||
// B2G doesn't handle IME as widget-level.
|
||||
return nsIMEUpdatePreference();
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -859,13 +840,9 @@ PuppetWidget::NotifyIMEOfTextChange(const IMENotification& aIMENotification)
|
|||
{
|
||||
MOZ_ASSERT(aIMENotification.mMessage == NOTIFY_IME_OF_TEXT_CHANGE,
|
||||
"Passed wrong notification");
|
||||
|
||||
#ifndef MOZ_CROSS_PROCESS_IME
|
||||
return NS_OK;
|
||||
#endif
|
||||
|
||||
if (!mTabChild)
|
||||
if (!mTabChild) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// While a plugin has focus, text change notification shouldn't be available.
|
||||
if (NS_WARN_IF(mInputContext.mIMEState.mEnabled == IMEState::PLUGIN)) {
|
||||
|
@ -896,13 +873,9 @@ PuppetWidget::NotifyIMEOfSelectionChange(
|
|||
{
|
||||
MOZ_ASSERT(aIMENotification.mMessage == NOTIFY_IME_OF_SELECTION_CHANGE,
|
||||
"Passed wrong notification");
|
||||
|
||||
#ifndef MOZ_CROSS_PROCESS_IME
|
||||
return NS_OK;
|
||||
#endif
|
||||
|
||||
if (!mTabChild)
|
||||
if (!mTabChild) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// While a plugin has focus, selection change notification shouldn't be
|
||||
// available.
|
||||
|
@ -951,9 +924,6 @@ PuppetWidget::NotifyIMEOfMouseButtonEvent(
|
|||
nsresult
|
||||
PuppetWidget::NotifyIMEOfPositionChange(const IMENotification& aIMENotification)
|
||||
{
|
||||
#ifndef MOZ_CROSS_PROCESS_IME
|
||||
return NS_OK;
|
||||
#endif
|
||||
if (NS_WARN_IF(!mTabChild)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -313,6 +313,41 @@ WidgetEvent::HasPluginActivationEventMessage() const
|
|||
* Specific event checking methods.
|
||||
******************************************************************************/
|
||||
|
||||
bool
|
||||
WidgetEvent::CanBeSentToRemoteProcess() const
|
||||
{
|
||||
// If this event is explicitly marked as shouldn't be sent to remote process,
|
||||
// just return false.
|
||||
if (mFlags.mNoCrossProcessBoundaryForwarding) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mClass == eKeyboardEventClass ||
|
||||
mClass == eWheelEventClass) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (mMessage) {
|
||||
case eMouseDown:
|
||||
case eMouseUp:
|
||||
case eMouseMove:
|
||||
case eContextMenu:
|
||||
case eMouseEnterIntoWidget:
|
||||
case eMouseExitFromWidget:
|
||||
case eMouseTouchDrag:
|
||||
case eTouchStart:
|
||||
case eTouchMove:
|
||||
case eTouchEnd:
|
||||
case eTouchCancel:
|
||||
case eDragOver:
|
||||
case eDragExit:
|
||||
case eDrop:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
WidgetEvent::IsRetargetedNativeEventDelivererForPlugin() const
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче