diff --git a/b2g/config/aries/sources.xml b/b2g/config/aries/sources.xml
index 14fcb8f20b0d..fc4fdd2f51fe 100644
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index 9da4a44f7f7c..1324f67553eb 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
-
+
@@ -128,7 +128,7 @@
-
+
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index f957517a30eb..49eca3d14f90 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 7effa8af8dd7..814b88f0dbe2 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index f8355ff80370..9169f6cf5d99 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml
index e5e2cb66f29b..a4063cf578b1 100644
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index f957517a30eb..49eca3d14f90 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index b8a3fabc3109..7ce1c07068c0 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 82378628feea..a59c4a92e292 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
{
"git": {
- "git_revision": "59ce66c60e71b434061aeaf11e945814b234c355",
+ "git_revision": "68d369c2a2b0cd16db028f0c2e660107c52ce113",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
- "revision": "8ab354e8ef85b6ee872eb7eb1710a8e094c93b18",
+ "revision": "041d99d0bd97e84219626c711c4c709e9558dfaa",
"repo_path": "integration/gaia-central"
}
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 454cc144eb7d..310930f1c7ed 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml
index 975dff4d4b77..86ccffaee836 100644
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index 80037169ebec..16f6451ec371 100644
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -6678,12 +6678,10 @@ var gIdentityHandler = {
IDENTITY_MODE_MIXED_ACTIVE_BLOCKED : "verifiedDomain mixedContent mixedActiveBlocked", // SSL with unauthenticated active content blocked; no unauthenticated display content
IDENTITY_MODE_MIXED_ACTIVE_BLOCKED_IDENTIFIED : "verifiedIdentity mixedContent mixedActiveBlocked", // SSL with unauthenticated active content blocked; no unauthenticated display content
IDENTITY_MODE_CHROMEUI : "chromeUI", // Part of the product's UI
- IDENTITY_MODE_FILE_URI : "fileURI", // File path
- // Cache the most recent SSLStatus and Location seen in checkIdentity
- _lastStatus : null,
- _lastUri : null,
- _mode : "unknownIdentity",
+ _isChromeUI: false,
+ _sslStatus: null,
+ _uri: null,
// smart getters
get _identityPopup () {
@@ -6714,20 +6712,10 @@ var gIdentityHandler = {
return this._identityPopupContentVerif =
document.getElementById("identity-popup-content-verifier");
},
- get _identityPopupSecurityContent () {
- delete this._identityPopupSecurityContent;
- return this._identityPopupSecurityContent =
- document.getElementById("identity-popup-security-content");
- },
- get _identityPopupSecurityView () {
- delete this._identityPopupSecurityView;
- return this._identityPopupSecurityView =
- document.getElementById("identity-popup-securityView");
- },
- get _identityPopupMainView () {
- delete this._identityPopupMainView;
- return this._identityPopupMainView =
- document.getElementById("identity-popup-mainView");
+ get _identityPopupMixedContentLearnMore () {
+ delete this._identityPopupMixedContentLearnMore;
+ return this._identityPopupMixedContentLearnMore =
+ document.getElementById("identity-popup-mcb-learn-more");
},
get _identityIconLabel () {
delete this._identityIconLabel;
@@ -6806,13 +6794,33 @@ var gIdentityHandler = {
}
},
+ disableMixedContentProtection() {
+ // Use telemetry to measure how often unblocking happens
+ const kMIXED_CONTENT_UNBLOCK_EVENT = 2;
+ let histogram =
+ Services.telemetry.getHistogramById(
+ "MIXED_CONTENT_UNBLOCK_COUNTER");
+ histogram.add(kMIXED_CONTENT_UNBLOCK_EVENT);
+ // Reload the page with the content unblocked
+ BrowserReloadWithFlags(
+ Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_MIXED_CONTENT);
+ this._identityPopup.hidePopup();
+ },
+
+ enableMixedContentProtection() {
+ gBrowser.selectedBrowser.messageManager.sendAsyncMessage(
+ "MixedContent:ReenableProtection", {});
+ BrowserReload();
+ this._identityPopup.hidePopup();
+ },
+
/**
- * Helper to parse out the important parts of _lastStatus (of the SSL cert in
+ * Helper to parse out the important parts of _sslStatus (of the SSL cert in
* particular) for use in constructing identity UI strings
*/
getIdentityData : function() {
var result = {};
- var status = this._lastStatus.QueryInterface(Components.interfaces.nsISSLStatus);
+ var status = this._sslStatus.QueryInterface(Ci.nsISSLStatus);
var cert = status.serverCert;
// Human readable name of Subject
@@ -6848,16 +6856,11 @@ var gIdentityHandler = {
* @param nsIURI uri The address for which the UI should be updated.
*/
checkIdentity : function(state, uri) {
- var currentStatus = gBrowser.securityUI
- .QueryInterface(Components.interfaces.nsISSLStatusProvider)
- .SSLStatus;
- this._lastStatus = currentStatus;
- this._lastUri = uri;
-
let nsIWebProgressListener = Ci.nsIWebProgressListener;
- // For some URIs like data: we can't get a host and so can't do
- // anything useful here.
+ // For some URIs like data: we can't get a host. URIs without a host will
+ // usually be treated as a non-secure connection if they're not on the
+ // whitelist below and don't resolve to file:// URIs internally.
let unknown = false;
try {
uri.host;
@@ -6867,49 +6870,54 @@ var gIdentityHandler = {
// whitelisted to provide a positive security signal to the user.
let whitelist = /^about:(accounts|addons|app-manager|config|crashes|customizing|downloads|healthreport|home|license|newaddon|permissions|preferences|privatebrowsing|rights|sessionrestore|support|welcomeback)/i;
let isChromeUI = uri.schemeIs("about") && whitelist.test(uri.spec);
+ let mode = this.IDENTITY_MODE_UNKNOWN;
+
if (isChromeUI) {
- this.setMode(this.IDENTITY_MODE_CHROMEUI);
+ mode = this.IDENTITY_MODE_CHROMEUI;
} else if (unknown) {
- this.setMode(this.IDENTITY_MODE_UNKNOWN);
+ // Use default mode.
} else if (state & nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL) {
if (state & nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT) {
- this.setMode(this.IDENTITY_MODE_MIXED_ACTIVE_BLOCKED_IDENTIFIED);
+ mode = this.IDENTITY_MODE_MIXED_ACTIVE_BLOCKED_IDENTIFIED;
} else {
- this.setMode(this.IDENTITY_MODE_IDENTIFIED);
+ mode = this.IDENTITY_MODE_IDENTIFIED;
}
} else if (state & nsIWebProgressListener.STATE_IS_SECURE) {
if (state & nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT) {
- this.setMode(this.IDENTITY_MODE_MIXED_ACTIVE_BLOCKED);
+ mode = this.IDENTITY_MODE_MIXED_ACTIVE_BLOCKED;
} else {
- this.setMode(this.IDENTITY_MODE_DOMAIN_VERIFIED);
+ mode = this.IDENTITY_MODE_DOMAIN_VERIFIED;
}
} else if (state & nsIWebProgressListener.STATE_IS_BROKEN) {
if (state & nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT) {
- this.setMode(this.IDENTITY_MODE_MIXED_ACTIVE_LOADED);
+ mode = this.IDENTITY_MODE_MIXED_ACTIVE_LOADED;
} else if (state & nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT) {
- this.setMode(this.IDENTITY_MODE_MIXED_DISPLAY_LOADED_ACTIVE_BLOCKED);
+ mode = this.IDENTITY_MODE_MIXED_DISPLAY_LOADED_ACTIVE_BLOCKED;
} else if (state & nsIWebProgressListener.STATE_LOADED_MIXED_DISPLAY_CONTENT) {
- this.setMode(this.IDENTITY_MODE_MIXED_DISPLAY_LOADED);
+ mode = this.IDENTITY_MODE_MIXED_DISPLAY_LOADED;
} else {
- this.setMode(this.IDENTITY_MODE_USES_WEAK_CIPHER);
- }
- } else {
- // Create a channel for the sole purpose of getting the resolved URI
- // of the request to determine if it's loaded from the file system.
- let resolvedURI = NetUtil.newChannel({uri,loadUsingSystemPrincipal:true}).URI;
- if (resolvedURI.schemeIs("jar")) {
- // Given a URI "jar:!/"
- // create a new URI using !/
- resolvedURI = NetUtil.newURI(resolvedURI.path);
- }
-
- if (resolvedURI.schemeIs("file")) {
- this.setMode(this.IDENTITY_MODE_FILE_URI);
- } else {
- this.setMode(this.IDENTITY_MODE_UNKNOWN);
+ mode = this.IDENTITY_MODE_USES_WEAK_CIPHER;
}
}
+ // We need those values later when populating the control center.
+ this._uri = uri;
+ this._state = state;
+ this._isChromeUI = isChromeUI;
+ this._sslStatus =
+ gBrowser.securityUI.QueryInterface(Ci.nsISSLStatusProvider).SSLStatus;
+
+ // Update the identity block.
+ if (this._identityBox) {
+ this._identityBox.className = mode;
+ this.refreshIdentityBlock(mode);
+ }
+
+ // NOTE: We do NOT update the identity popup (the control center) when
+ // we receive a new security state. If the user opened the popup and looks
+ // at the provided information we don't want to suddenly change the panel
+ // contents.
+
// Show the doorhanger when:
// - mixed active content is blocked
// - mixed active content is loaded (detected but not blocked)
@@ -6961,46 +6969,22 @@ var gIdentityHandler = {
.getService(Ci.nsIIDNService);
try {
let baseDomain =
- Services.eTLD.getBaseDomainFromHost(this._lastUri.host);
+ Services.eTLD.getBaseDomainFromHost(this._uri.host);
return this._IDNService.convertToDisplayIDN(baseDomain, {});
} catch (e) {
// If something goes wrong (e.g. host is an IP address) just fail back
// to the full domain.
- return this._lastUri.host;
+ return this._uri.host;
}
},
- /**
- * Update the UI to reflect the specified mode, which should be one of the
- * IDENTITY_MODE_* constants.
- */
- setMode : function(newMode) {
- if (!this._identityBox) {
- // No identity box means the identity box is not visible, in which
- // case there's nothing to do.
- return;
- }
-
- this._identityPopup.className = newMode;
- this._identityBox.className = newMode;
- this.setIdentityMessages(newMode);
-
- // Update the popup too, if it's open
- if (this._identityPopup.state == "open") {
- this.setPopupMessages(newMode);
- this.updateSitePermissions();
- }
-
- this._mode = newMode;
- },
-
/**
* Set up the messages for the primary identity UI based on the specified mode,
* and the details of the SSL cert, where applicable
*
* @param newMode The newly set identity mode. Should be one of the IDENTITY_MODE_* constants.
*/
- setIdentityMessages : function(newMode) {
+ refreshIdentityBlock(newMode) {
let icon_label = "";
let tooltip = "";
let icon_country_label = "";
@@ -7017,11 +7001,11 @@ var gIdentityHandler = {
[iData.caOrg]);
// This can't throw, because URI's with a host that throw don't end up in this case.
- let host = this._lastUri.host;
+ let host = this._uri.host;
let port = 443;
try {
- if (this._lastUri.port > 0)
- port = this._lastUri.port;
+ if (this._uri.port > 0)
+ port = this._uri.port;
} catch (e) {}
if (this._overrideService.hasMatchingOverride(host, port, iData.cert, {}, {}))
@@ -7070,15 +7054,78 @@ var gIdentityHandler = {
* Set up the title and content messages for the identity message popup,
* based on the specified mode, and the details of the SSL cert, where
* applicable
- *
- * @param newMode The newly set identity mode. Should be one of the IDENTITY_MODE_* constants.
*/
- setPopupMessages : function(newMode) {
+ refreshIdentityPopup() {
+ // Update the "Learn More" hrefs for Mixed Content Blocking.
+ let baseURL = Services.urlFormatter.formatURLPref("app.support.baseURL");
+ let learnMoreHref = `${baseURL}mixed-content`;
+ this._identityPopupMixedContentLearnMore.setAttribute("href", learnMoreHref);
- this._identityPopup.className = newMode;
- this._identityPopupMainView.className = newMode;
- this._identityPopupSecurityView.className = newMode;
- this._identityPopupSecurityContent.className = newMode;
+ // Basic connection properties.
+ let isBroken = this._state & Ci.nsIWebProgressListener.STATE_IS_BROKEN;
+ let isSecure = this._state & Ci.nsIWebProgressListener.STATE_IS_SECURE;
+ let isEV = this._state & Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL;
+
+ // Determine connection security information.
+ let connection = "not-secure";
+ if (this._isChromeUI) {
+ connection = "chrome";
+ } else if (this._isURILoadedFromFile(this._uri)) {
+ connection = "file";
+ } else if (isEV) {
+ connection = "secure-ev";
+ } else if (isSecure) {
+ connection = "secure";
+ }
+
+ // Mixed content flags.
+ let isMixedActiveContentLoaded =
+ this._state & Ci.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT;
+ let isMixedActiveContentBlocked =
+ this._state & Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT;
+ let isMixedPassiveContentLoaded =
+ this._state & Ci.nsIWebProgressListener.STATE_LOADED_MIXED_DISPLAY_CONTENT;
+
+ // Determine the mixed content state.
+ let mixedcontent = [];
+ if (isMixedPassiveContentLoaded) {
+ mixedcontent.push("passive-loaded");
+ }
+ if (isMixedActiveContentLoaded) {
+ mixedcontent.push("active-loaded");
+ } else if (isMixedActiveContentBlocked) {
+ mixedcontent.push("active-blocked");
+ }
+ mixedcontent = mixedcontent.join(" ");
+
+ // We have no specific flags for weak ciphers (yet). If a connection is
+ // broken and we can't detect any mixed active content loaded then it's
+ // a weak cipher.
+ let ciphers = "";
+ if (isBroken && !isMixedActiveContentLoaded) {
+ ciphers = "weak";
+ }
+
+ // Update all elements.
+ let elementIDs = [
+ "identity-popup",
+ "identity-popup-securityView-body",
+ ];
+
+ function updateAttribute(elem, attr, value) {
+ if (value) {
+ elem.setAttribute(attr, value);
+ } else {
+ elem.removeAttribute(attr);
+ }
+ }
+
+ for (let id of elementIDs) {
+ let element = document.getElementById(id);
+ updateAttribute(element, "connection", connection);
+ updateAttribute(element, "ciphers", ciphers);
+ updateAttribute(element, "mixedcontent", mixedcontent);
+ }
// Initialize the optional strings to empty values
let supplemental = "";
@@ -7092,19 +7139,18 @@ var gIdentityHandler = {
// Some URIs might have no hosts.
}
+ // Fallback for special protocols.
if (!host) {
- // Fallback for special protocols.
- host = this._lastUri.specIgnoringRef;
+ host = this._uri.specIgnoringRef;
}
- switch (newMode) {
- case this.IDENTITY_MODE_DOMAIN_VERIFIED:
- case this.IDENTITY_MODE_MIXED_ACTIVE_BLOCKED:
+ // Fill in the CA name if we have a valid TLS certificate.
+ if (isSecure) {
verifier = this._identityBox.tooltipText;
- break;
- case this.IDENTITY_MODE_IDENTIFIED:
- case this.IDENTITY_MODE_MIXED_ACTIVE_BLOCKED_IDENTIFIED: {
- // If it's identified, then we can populate the dialog with credentials
+ }
+
+ // Fill in organization information if we have a valid EV certificate.
+ if (isEV) {
let iData = this.getIdentityData();
host = owner = iData.subjectOrg;
verifier = this._identityBox.tooltipText;
@@ -7119,21 +7165,6 @@ var gIdentityHandler = {
supplemental += iData.state;
else if (iData.country) // Country only
supplemental += iData.country;
- break;
- }
- case this.IDENTITY_MODE_UNKNOWN:
- supplemental = gNavigatorBundle.getString("identity.not_secure");
- break;
- case this.IDENTITY_MODE_USES_WEAK_CIPHER:
- supplemental = gNavigatorBundle.getString("identity.uses_weak_cipher");
- break;
- case this.IDENTITY_MODE_MIXED_DISPLAY_LOADED:
- case this.IDENTITY_MODE_MIXED_DISPLAY_LOADED_ACTIVE_BLOCKED:
- supplemental = gNavigatorBundle.getString("identity.mixed_display_loaded");
- break;
- case this.IDENTITY_MODE_MIXED_ACTIVE_LOADED:
- supplemental = gNavigatorBundle.getString("identity.mixed_active_loaded2");
- break;
}
// Push the appropriate strings out to the UI. Need to use |value| for the
@@ -7144,8 +7175,23 @@ var gIdentityHandler = {
this._identityPopupContentSupp.textContent = supplemental;
this._identityPopupContentVerif.textContent = verifier;
- // Hide subviews when updating panel information.
- document.getElementById("identity-popup-multiView").showMainView();
+ // Update per-site permissions section.
+ this.updateSitePermissions();
+ },
+
+ _isURILoadedFromFile(uri) {
+ // Create a channel for the sole purpose of getting the resolved URI
+ // of the request to determine if it's loaded from the file system.
+ let chanOptions = {uri, loadUsingSystemPrincipal: true};
+ let resolvedURI = NetUtil.newChannel(chanOptions).URI;
+ if (resolvedURI.schemeIs("jar")) {
+ // Given a URI "jar:!/"
+ // create a new URI using !/
+ resolvedURI = NetUtil.newURI(resolvedURI.path);
+ }
+
+ // Check the URI again after resolving.
+ return resolvedURI.schemeIs("file");
},
/**
@@ -7170,9 +7216,7 @@ var gIdentityHandler = {
this._identityPopup.hidden = false;
// Update the popup strings
- this.setPopupMessages(this._identityBox.className);
-
- this.updateSitePermissions();
+ this.refreshIdentityPopup();
// Add the "open" attribute to the identity box for styling
this._identityBox.setAttribute("open", "true");
diff --git a/browser/base/content/test/general/browser_bug590206.js b/browser/base/content/test/general/browser_bug590206.js
index 30e1c3ccf5ca..43f5429f3997 100644
--- a/browser/base/content/test/general/browser_bug590206.js
+++ b/browser/base/content/test/general/browser_bug590206.js
@@ -2,6 +2,8 @@
* Test the identity mode UI for a variety of page types
*/
+"use strict";
+
const DUMMY = "browser/browser/base/content/test/general/dummy_page.html";
function loadNewTab(url) {
@@ -12,6 +14,11 @@ function getIdentityMode() {
return document.getElementById("identity-box").className;
}
+function getConnectionState() {
+ gIdentityHandler.refreshIdentityPopup();
+ return document.getElementById("identity-popup").getAttribute("connection");
+}
+
// This test is slow on Linux debug e10s
requestLongerTimeout(2);
@@ -49,13 +56,13 @@ add_task(function* test_chrome() {
let oldTab = gBrowser.selectedTab;
let newTab = yield loadNewTab("chrome://mozapps/content/extensions/extensions.xul");
- is(getIdentityMode(), "fileURI", "Identity should be file");
+ is(getConnectionState(), "file", "Connection should be file");
gBrowser.selectedTab = oldTab;
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
gBrowser.selectedTab = newTab;
- is(getIdentityMode(), "fileURI", "Identity should be file");
+ is(getConnectionState(), "file", "Connection should be file");
gBrowser.removeTab(newTab);
});
@@ -95,30 +102,30 @@ add_task(function* test_file() {
let fileURI = getTestFilePath("");
let newTab = yield loadNewTab(fileURI);
- is(getIdentityMode(), "fileURI", "Identity should be file");
+ is(getConnectionState(), "file", "Connection should be file");
gBrowser.selectedTab = oldTab;
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
gBrowser.selectedTab = newTab;
- is(getIdentityMode(), "fileURI", "Identity should be file");
+ is(getConnectionState(), "file", "Connection should be file");
gBrowser.removeTab(newTab);
});
add_task(function test_resource_uri() {
let oldTab = gBrowser.selectedTab;
- let dataURI = "resource://gre/modules/Services.jsm"
+ let dataURI = "resource://gre/modules/Services.jsm";
let newTab = yield loadNewTab(dataURI);
- is(getIdentityMode(), "fileURI", "Identity should be unknown");
+ is(getConnectionState(), "file", "Connection should be file");
gBrowser.selectedTab = oldTab;
is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
gBrowser.selectedTab = newTab;
- is(getIdentityMode(), "fileURI", "Identity should be unknown");
+ is(getConnectionState(), "file", "Connection should be file");
gBrowser.removeTab(newTab);
});
@@ -138,3 +145,19 @@ add_task(function test_data_uri() {
gBrowser.removeTab(newTab);
});
+
+add_task(function test_about_uri() {
+ let oldTab = gBrowser.selectedTab;
+ let aboutURI = "about:robots"
+
+ let newTab = yield loadNewTab(aboutURI);
+ is(getConnectionState(), "file", "Connection should be file");
+
+ gBrowser.selectedTab = oldTab;
+ is(getIdentityMode(), "unknownIdentity", "Identity should be unknown");
+
+ gBrowser.selectedTab = newTab;
+ is(getConnectionState(), "file", "Connection should be file");
+
+ gBrowser.removeTab(newTab);
+});
diff --git a/browser/base/content/test/general/browser_identity_UI.js b/browser/base/content/test/general/browser_identity_UI.js
index 7a7f34bdac3a..3305447019c4 100644
--- a/browser/base/content/test/general/browser_identity_UI.js
+++ b/browser/base/content/test/general/browser_identity_UI.js
@@ -43,7 +43,6 @@ var tests = [
{
name: "subdomain HTTPS",
location: "https://test1.example.com/",
-
effectiveHost: "example.com",
isHTTPS: true
},
@@ -104,12 +103,14 @@ function nextTest() {
function checkResult() {
// Sanity check other values, and the value of gIdentityHandler.getEffectiveHost()
- is(gIdentityHandler._lastUri.spec, gCurrentTest.location, "location matches for test " + gTestDesc);
+ is(gIdentityHandler._uri.spec, gCurrentTest.location, "location matches for test " + gTestDesc);
// getEffectiveHost can't be called for all modes
- if (gCurrentTest.effectiveHost === null)
- is(gIdentityHandler._mode == gIdentityHandler.IDENTITY_MODE_UNKNOWN || gIdentityHandler._mode == gIdentityHandler.IDENTITY_MODE_CHROMEUI, true, "mode matched");
- else
+ if (gCurrentTest.effectiveHost === null) {
+ let identityBox = document.getElementById("identity-box");
+ is(identityBox.className == gIdentityHandler.IDENTITY_MODE_UNKNOWN || identityBox.className == gIdentityHandler.IDENTITY_MODE_CHROMEUI, true, "mode matched");
+ } else {
is(gIdentityHandler.getEffectiveHost(), gCurrentTest.effectiveHost, "effectiveHost matches for test " + gTestDesc);
+ }
executeSoon(nextTest);
}
diff --git a/browser/components/controlcenter/content/panel.inc.xul b/browser/components/controlcenter/content/panel.inc.xul
index c3e6b05f2029..cf386cad98f8 100644
--- a/browser/components/controlcenter/content/panel.inc.xul
+++ b/browser/components/controlcenter/content/panel.inc.xul
@@ -10,7 +10,8 @@
orient="vertical">
-
+
+
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+ &identity.activeBlocked;
+ &identity.passiveLoaded;
+ &identity.activeLoaded;
+ &identity.weakEncryption;
+
-
-
+
-
diff --git a/browser/components/preferences/in-content/sync.xul b/browser/components/preferences/in-content/sync.xul
index 0fefce3ce8a9..827e36e77390 100644
--- a/browser/components/preferences/in-content/sync.xul
+++ b/browser/components/preferences/in-content/sync.xul
@@ -293,7 +293,7 @@
-
+
&mobilePromo.end;
-
+
diff --git a/browser/locales/en-US/chrome/browser/browser.dtd b/browser/locales/en-US/chrome/browser/browser.dtd
index 1e40986b3f9d..bba732609aa0 100644
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -691,6 +691,29 @@ you can use these alternative items. Otherwise, their values should be empty. -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties
index 0f14b29be9bd..670d244b5b17 100644
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -329,11 +329,6 @@ identity.identified.verifier=Verified by: %S
identity.identified.verified_by_you=You have added a security exception for this site.
identity.identified.state_and_country=%S, %S
-identity.not_secure=Your connection to this site is not private. Information you submit could be viewable to others (for example passwords, messages, credit cards, etc.).
-identity.uses_weak_cipher=Your connection to this website uses weak encryption and is not private. Other people can view your information or modify the website's behavior.
-identity.mixed_display_loaded=The connection to this website is not fully secure because it contains unencrypted elements (such as images).
-identity.mixed_active_loaded2=This website contains interactive content that isn't encrypted (such as scripts). Other people can view your information or modify the website's behavior.
-
identity.unknown.tooltip=This website does not supply identity information.
trackingProtection.intro.title=How Tracking Protection works
diff --git a/browser/locales/en-US/chrome/browser/preferences/sync.dtd b/browser/locales/en-US/chrome/browser/preferences/sync.dtd
index c1b2c10c53f2..74f7bdedea70 100644
--- a/browser/locales/en-US/chrome/browser/preferences/sync.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/sync.dtd
@@ -89,7 +89,7 @@ both, to better adapt this sentence to their language.
-
+
diff --git a/browser/themes/osx/controlcenter/panel.css b/browser/themes/osx/controlcenter/panel.css
index c4c5d509cbae..a0b7b00e33ba 100644
--- a/browser/themes/osx/controlcenter/panel.css
+++ b/browser/themes/osx/controlcenter/panel.css
@@ -21,20 +21,23 @@
#tracking-action-block,
#tracking-action-unblock,
-#tracking-action-unblock-private {
+#tracking-action-unblock-private,
+#identity-popup-securityView-body > button {
@hudButton@
min-height: 30px;
}
#tracking-action-block:hover:active,
#tracking-action-unblock:hover:active,
-#tracking-action-unblock-private:hover:active {
+#tracking-action-unblock-private:hover:active,
+#identity-popup-securityView-body > button:hover:active {
@hudButtonPressed@
}
#tracking-action-block:-moz-focusring,
#tracking-action-unblock:-moz-focusring,
-#tracking-action-unblock-private:-moz-focusring {
+#tracking-action-unblock-private:-moz-focusring,
+#identity-popup-securityView-body > button:-moz-focusring {
@hudButtonFocused@
}
diff --git a/browser/themes/osx/jar.mn b/browser/themes/osx/jar.mn
index e217e423b9e2..9957a3966671 100644
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -195,8 +195,10 @@ browser.jar:
skin/classic/browser/controlcenter/conn-degraded.svg (../shared/controlcenter/conn-degraded.svg)
skin/classic/browser/controlcenter/mcb-disabled.svg (../shared/controlcenter/mcb-disabled.svg)
skin/classic/browser/controlcenter/permissions.svg (../shared/controlcenter/permissions.svg)
- skin/classic/browser/controlcenter/tracking-protection.svg (../shared/controlcenter/tracking-protection.svg)
- skin/classic/browser/controlcenter/tracking-protection-disabled.svg (../shared/controlcenter/tracking-protection-disabled.svg)
+ skin/classic/browser/controlcenter/tracking-protection.svg (../shared/controlcenter/tracking-protection.svg)
+ skin/classic/browser/controlcenter/tracking-protection-disabled.svg (../shared/controlcenter/tracking-protection-disabled.svg)
+ skin/classic/browser/controlcenter/warning-gray.svg (../shared/controlcenter/warning-gray.svg)
+ skin/classic/browser/controlcenter/warning-yellow.svg (../shared/controlcenter/warning-yellow.svg)
skin/classic/browser/customizableui/background-noise-toolbar.png (customizableui/background-noise-toolbar.png)
skin/classic/browser/customizableui/customize-titleBar-toggle.png (customizableui/customize-titleBar-toggle.png)
skin/classic/browser/customizableui/customize-titleBar-toggle@2x.png (customizableui/customize-titleBar-toggle@2x.png)
diff --git a/browser/themes/shared/controlcenter/panel.inc.css b/browser/themes/shared/controlcenter/panel.inc.css
index 3a03754a56f6..ef9d574874f4 100644
--- a/browser/themes/shared/controlcenter/panel.inc.css
+++ b/browser/themes/shared/controlcenter/panel.inc.css
@@ -1,33 +1,39 @@
-/* Show the organization name only for EV certs. */
-#identity-popup-securityView:not(.verifiedIdentity) > #identity-popup-content-owner,
-#identity-popup-securityView:not(.verifiedIdentity) > #identity-popup-securityView-connection,
-/* Show the "Verified by" label only for DV and EV certs. */
-#identity-popup-securityView:not(.verifiedIdentity):not(.verifiedDomain) > #identity-popup-content-verifier,
-/* Show a longer explanation for non-secure sites, mixed content, and weak
- connection security. Show the organization address for EV certs. */
-#identity-popup-securityView:not(.unknownIdentity):not(.verifiedIdentity):not(.mixedContent):not(.weakCipher) > #identity-popup-content-supplemental,
-/* Show the "Connection is secure" labels only for EV and DV certs. */
-#identity-popup-security-content:not(.verifiedIdentity):not(.verifiedDomain) > .identity-popup-connection-secure,
-#identity-popup-securityView:not(.verifiedIdentity):not(.verifiedDomain) > #identity-popup-securityView-header > .identity-popup-connection-secure,
-/* Show the "Connection is not secure" labels only for non-secure sites. */
-#identity-popup-security-content:not(.unknownIdentity) > .identity-popup-connection-not-secure,
-#identity-popup-securityView:not(.unknownIdentity) > #identity-popup-securityView-header > .identity-popup-connection-not-secure,
-/* Show "This page is stored on your computer" only for file URLs. */
-#identity-popup-security-content:not(.fileURI) > .identity-popup-connection-file-uri,
-#identity-popup-securityView:not(.fileURI) > #identity-popup-securityView-header > .identity-popup-connection-file-uri,
-/* Show "This is a secure internal page" only for whitelisted pages. */
-#identity-popup-securityView:not(.chromeUI) > #identity-popup-securityView-header > .identity-popup-connection-internal,
-#identity-popup-security-content:not(.chromeUI) > .identity-popup-connection-internal,
-/* Hide the subsection arrow for whitelisted chromeUI pages. */
-#identity-popup-security-content.chromeUI + .identity-popup-expander,
-/* Hide the subsection arrow for whitelisted file URI pages. */
-#identity-popup-security-content.fileURI + .identity-popup-expander,
-/* Hide the tracking protection section for whitelisted chromeUI pages. */
-#identity-popup-mainView.chromeUI > #tracking-protection-container {
+%if 0
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+%endif
+
+/* Hide all conditional elements by default. */
+:-moz-any([when-connection],[when-mixedcontent],[when-ciphers]) {
display: none;
}
-/* PANEL */
+/* Show the right elements for the right connection states. */
+#identity-popup[connection=not-secure] [when-connection~=not-secure],
+#identity-popup[connection=secure-ev] [when-connection~=secure-ev],
+#identity-popup[connection=secure] [when-connection~=secure],
+#identity-popup[connection=chrome] [when-connection~=chrome],
+#identity-popup[connection=file] [when-connection~=file],
+/* Show weak cipher messages when needed. */
+#identity-popup[ciphers=weak]:not([mixedcontent]) [when-ciphers~=weak],
+/* Show mixed content warnings when needed */
+#identity-popup[mixedcontent~=active-loaded] [when-mixedcontent=active-loaded],
+#identity-popup[mixedcontent~=passive-loaded]:not([mixedcontent~=active-loaded]) [when-mixedcontent=passive-loaded],
+#identity-popup[mixedcontent~=active-blocked]:not([mixedcontent~=passive-loaded]) [when-mixedcontent=active-blocked],
+/* Show the right elements when there is mixed passive content loaded and active blocked. */
+#identity-popup[mixedcontent~=active-blocked][mixedcontent~=passive-loaded] [when-mixedcontent~=active-blocked][when-mixedcontent~=passive-loaded],
+/* Show 'disable MCB' button always when there is mixed active content blocked. */
+#identity-popup-securityView-body[mixedcontent~=active-blocked] > button[when-mixedcontent=active-blocked] {
+ display: inherit;
+}
+
+/* Hide 'not secure' message in subview when weak cipher or mixed content messages are shown. */
+#identity-popup-securityView-body:-moz-any([mixedcontent],[ciphers]) > description[when-connection=not-secure],
+/* Hide 'passive-loaded (only)' message when there is mixed passive content loaded and active blocked. */
+#identity-popup-securityView-body[mixedcontent~=passive-loaded][mixedcontent~=active-blocked] > description[when-mixedcontent=passive-loaded] {
+ display: none;
+}
#identity-popup,
#identity-popup:not([panelopen]) .panel-viewstack[viewtype="main"]:not([transitioning]) #identity-popup-mainView {
@@ -143,7 +149,11 @@
/* CONTENT */
-.identity-popup-text {
+#identity-popup-security-content > description,
+#identity-popup-security-descriptions > description,
+#identity-popup-securityView-header > description,
+#identity-popup-securityView-body > description,
+#tracking-protection-content > label {
white-space: pre-wrap;
font-size: 110%;
margin: 0;
@@ -154,12 +164,18 @@
font-size: 150%;
}
-/* SECURITY */
-
-#identity-popup-securityView > .identity-popup-text:not(#identity-popup-content-owner) {
- margin: 2px 0 4px;
+.identity-popup-warning-gray {
+ -moz-padding-start: 24px;
+ background: url(chrome://browser/skin/controlcenter/warning-gray.svg) no-repeat 0 50%;
}
+.identity-popup-warning-yellow {
+ -moz-padding-start: 24px;
+ background: url(chrome://browser/skin/controlcenter/warning-yellow.svg) no-repeat 0 50%;
+}
+
+/* SECURITY */
+
.identity-popup-connection-secure {
color: #418220;
}
@@ -168,12 +184,6 @@
color: #d74345;
}
-#identity-popup-security-content.chromeUI {
- background-image: url(chrome://branding/content/icon48.png);
-}
-
-/* SECURITY SUBVIEW */
-
#identity-popup-securityView {
padding-bottom: 2em;
overflow: hidden;
@@ -184,46 +194,59 @@
background-image: url(chrome://browser/skin/controlcenter/conn-not-secure.svg);
}
-#identity-popup-securityView.verifiedDomain,
-#identity-popup-securityView.verifiedIdentity,
-#identity-popup-security-content.verifiedDomain,
-#identity-popup-security-content.verifiedIdentity {
+#identity-popup[connection=chrome] #identity-popup-securityView,
+#identity-popup[connection=chrome] #identity-popup-security-content {
+ background-image: url(chrome://branding/content/icon48.png);
+}
+
+#identity-popup[connection^=secure] #identity-popup-securityView,
+#identity-popup[connection^=secure] #identity-popup-security-content {
background-image: url(chrome://browser/skin/controlcenter/conn-secure.svg);
}
-#identity-popup-securityView.weakCipher,
-#identity-popup-securityView.mixedDisplayContent,
-#identity-popup-securityView.mixedDisplayContentLoadedActiveBlocked,
-#identity-popup-security-content.weakCipher,
-#identity-popup-security-content.mixedDisplayContent,
-#identity-popup-security-content.mixedDisplayContentLoadedActiveBlocked {
+#identity-popup[ciphers=weak] #identity-popup-securityView,
+#identity-popup[ciphers=weak] #identity-popup-security-content,
+#identity-popup[mixedcontent~=passive-loaded] #identity-popup-securityView,
+#identity-popup[mixedcontent~=passive-loaded] #identity-popup-security-content {
background-image: url(chrome://browser/skin/controlcenter/conn-degraded.svg);
}
-#identity-popup-securityView.mixedActiveContent,
-#identity-popup-security-content.mixedActiveContent {
+#identity-popup[mixedcontent~=active-loaded] #identity-popup-securityView,
+#identity-popup[mixedcontent~=active-loaded] #identity-popup-security-content {
background-image: url(chrome://browser/skin/controlcenter/mcb-disabled.svg);
}
+#identity-popup-security-descriptions > description {
+ margin-top: 6px;
+ color: Graytext;
+}
+
#identity-popup-securityView-header {
border-bottom: 1px solid var(--panel-separator-color);
padding-bottom: 1em;
- margin-bottom: 1em;
}
-#identity-popup-content-owner {
- font-weight: 700;
+#identity-popup-securityView-body {
+ -moz-padding-end: 1em;
}
-#identity-popup-content-verifier {
+#identity-popup-content-verifier ~ description {
+ margin-top: 1em;
color: Graytext;
}
-#identity-popup-content-owner,
-#identity-popup-securityView > #identity-popup-securityView-connection.identity-popup-text {
+description#identity-popup-content-verified-by,
+description#identity-popup-content-owner,
+description#identity-popup-content-verifier,
+#identity-popup-securityView-body > button {
margin-top: 1em;
}
+#identity-popup-securityView-body > button {
+ margin-inline-start: 0;
+ margin-inline-end: 0;
+}
+
/* TRACKING PROTECTION */
#tracking-protection-content {
diff --git a/browser/themes/shared/controlcenter/warning-gray.svg b/browser/themes/shared/controlcenter/warning-gray.svg
new file mode 100644
index 000000000000..5f122c3ee433
--- /dev/null
+++ b/browser/themes/shared/controlcenter/warning-gray.svg
@@ -0,0 +1,9 @@
+
+
+
diff --git a/browser/themes/shared/controlcenter/warning-yellow.svg b/browser/themes/shared/controlcenter/warning-yellow.svg
new file mode 100644
index 000000000000..e2d3a3664a03
--- /dev/null
+++ b/browser/themes/shared/controlcenter/warning-yellow.svg
@@ -0,0 +1,9 @@
+
+
+
diff --git a/build/annotationProcessors/utils/GeneratableElementIterator.java b/build/annotationProcessors/utils/GeneratableElementIterator.java
index a9ce573c8676..6c4cc9891524 100644
--- a/build/annotationProcessors/utils/GeneratableElementIterator.java
+++ b/build/annotationProcessors/utils/GeneratableElementIterator.java
@@ -50,7 +50,7 @@ public class GeneratableElementIterator implements Iterator {
// Check for "Wrap ALL the things" flag.
for (Annotation annotation : aClass.getDeclaredAnnotations()) {
final String annotationTypeName = annotation.annotationType().getName();
- if (annotationTypeName.equals("org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI")) {
+ if (annotationTypeName.equals("org.mozilla.gecko.annotation.WrapForJNI")) {
mIterateEveryEntry = true;
break;
}
@@ -71,7 +71,7 @@ public class GeneratableElementIterator implements Iterator {
// WrappedJNIMethod has parameters. Use Reflection to obtain them.
Class extends Annotation> annotationType = annotation.annotationType();
final String annotationTypeName = annotationType.getName();
- if (annotationTypeName.equals("org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI")) {
+ if (annotationTypeName.equals("org.mozilla.gecko.annotation.WrapForJNI")) {
String stubName = null;
boolean isMultithreadedStub = false;
boolean noThrow = false;
@@ -104,15 +104,15 @@ public class GeneratableElementIterator implements Iterator {
catchException = (Boolean) catchExceptionMethod.invoke(annotation);
} catch (NoSuchMethodException e) {
- System.err.println("Unable to find expected field on WrapElementForJNI annotation. Did the signature change?");
+ System.err.println("Unable to find expected field on WrapForJNI annotation. Did the signature change?");
e.printStackTrace(System.err);
System.exit(3);
} catch (IllegalAccessException e) {
- System.err.println("IllegalAccessException reading fields on WrapElementForJNI annotation. Seems the semantics of Reflection have changed...");
+ System.err.println("IllegalAccessException reading fields on WrapForJNI annotation. Seems the semantics of Reflection have changed...");
e.printStackTrace(System.err);
System.exit(4);
} catch (InvocationTargetException e) {
- System.err.println("InvocationTargetException reading fields on WrapElementForJNI annotation. This really shouldn't happen.");
+ System.err.println("InvocationTargetException reading fields on WrapForJNI annotation. This really shouldn't happen.");
e.printStackTrace(System.err);
System.exit(5);
}
diff --git a/dom/apps/PermissionsTable.jsm b/dom/apps/PermissionsTable.jsm
index 614943f05a82..ca7b4a2694f0 100644
--- a/dom/apps/PermissionsTable.jsm
+++ b/dom/apps/PermissionsTable.jsm
@@ -573,6 +573,12 @@ this.PermissionsTable = { geolocation: {
privileged: ALLOW_ACTION,
certified: ALLOW_ACTION
},
+ "open-hidden-window": {
+ app: DENY_ACTION,
+ trusted: DENY_ACTION,
+ privileged: DENY_ACTION,
+ certified: ALLOW_ACTION
+ },
};
/**
diff --git a/dom/contacts/tests/shared.js b/dom/contacts/tests/shared.js
index 9d0424bd5f52..00a6110b00af 100644
--- a/dom/contacts/tests/shared.js
+++ b/dom/contacts/tests/shared.js
@@ -5,10 +5,6 @@ if (SpecialPowers.isMainProcess()) {
SpecialPowers.Cu.import("resource://gre/modules/ContactService.jsm");
}
-SpecialPowers.addPermission("contacts-write", true, document);
-SpecialPowers.addPermission("contacts-read", true, document);
-SpecialPowers.addPermission("contacts-create", true, document);
-
// Some helpful global vars
var isAndroid = (navigator.userAgent.indexOf("Android") !== -1);
@@ -16,7 +12,12 @@ var defaultOptions = {
sortBy: "givenName",
};
-var mozContacts = navigator.mozContacts;
+// Make sure we only touch |navigator.mozContacts| after we have the necessary
+// permissions, or we'll race when checking the listen permission needed for the
+// oncontactchange event. This is only needed for tests because at first we have
+// the permission set to UNKNOWN_ACTION. That should never happen for real apps,
+// see dom/apps/PermissionsTable.jsm.
+var mozContacts;
// To test sorting
var c1 = {
@@ -495,7 +496,14 @@ function start_tests() {
.getService(SpecialPowers.Ci.nsIPropertyBag2)
.getProperty('version');
if (!isAndroid || androidVersion >= 14) {
- next();
+ SpecialPowers.pushPermissions([
+ {type: "contacts-write", allow: 1, context: document},
+ {type: "contacts-read", allow: 1, context: document},
+ {type: "contacts-create", allow: 1, context: document},
+ ], function() {
+ mozContacts = navigator.mozContacts;
+ next();
+ });
} else {
ok(true, "Skip tests on Android < 4.0 (bugs 897924 & 888891");
SimpleTest.finish();
diff --git a/dom/presentation/provider/PresentationDeviceProviderModule.cpp b/dom/presentation/provider/PresentationDeviceProviderModule.cpp
index 9819937f415a..9463f7efed14 100644
--- a/dom/presentation/provider/PresentationDeviceProviderModule.cpp
+++ b/dom/presentation/provider/PresentationDeviceProviderModule.cpp
@@ -28,7 +28,8 @@ static const mozilla::Module::ContractIDEntry kPresentationDeviceProviderContrac
};
static const mozilla::Module::CategoryEntry kPresentationDeviceProviderCategories[] = {
-#if defined(MOZ_WIDGET_ANDROID) || (defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 16)
+#if (defined(MOZ_WIDGET_ANDROID) && ANDROID_VERSION >= 21) || \
+ (defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 16)
{ PRESENTATION_DEVICE_PROVIDER_CATEGORY, "MulticastDNSDeviceProvider", MULTICAST_DNS_PROVIDER_CONTRACT_ID },
#endif
{ nullptr }
diff --git a/dom/system/SystemUpdateService.jsm b/dom/system/SystemUpdateService.jsm
index 13b2ff18ec6b..07278a93a05f 100644
--- a/dom/system/SystemUpdateService.jsm
+++ b/dom/system/SystemUpdateService.jsm
@@ -27,7 +27,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
function ActiveProvider(aProvider) {
this.id = aProvider.id;
- this._instance = Cc[aProvider.contractId].getService(Ci.nsISystemUpdateProvider);
+ this._instance = Components.classesByID[aProvider.id].getService(Ci.nsISystemUpdateProvider);
this._instance.setListener(this);
}
diff --git a/dom/telephony/gonk/TelephonyService.js b/dom/telephony/gonk/TelephonyService.js
index f2a75e506b96..0cfbd0fd5b00 100644
--- a/dom/telephony/gonk/TelephonyService.js
+++ b/dom/telephony/gonk/TelephonyService.js
@@ -2362,6 +2362,10 @@ TelephonyService.prototype = {
_handleCallStateChanged: function(aClientId, aCalls) {
if (DEBUG) debug("handleCallStateChanged: " + JSON.stringify(aCalls));
+ if (aCalls.length === 0) {
+ return;
+ }
+
if (aCalls.some(call => call.state == nsITelephonyService.CALL_STATE_DIALING)) {
gTelephonyMessenger.notifyNewCall();
}
diff --git a/dom/telephony/test/marionette/test_TelephonyUtils.js b/dom/telephony/test/marionette/test_TelephonyUtils.js
index b3a155718ab7..7cecd11b0b00 100644
--- a/dom/telephony/test/marionette/test_TelephonyUtils.js
+++ b/dom/telephony/test/marionette/test_TelephonyUtils.js
@@ -33,15 +33,18 @@ function dial() {
});
}
-function waitForStateChanged() {
+function waitForStateChanged(aPredicate) {
return new Promise(resolve => {
let listener = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsITelephonyListener]),
callStateChanged: function(length, allInfo) {
- resolve(allInfo);
- TelephonyService.unregisterListener(listener);
+ if (aPredicate(allInfo)) {
+ resolve(allInfo);
+ TelephonyService.unregisterListener(listener);
+ }
},
+
conferenceCallStateChanged: function() {},
supplementaryServiceNotification: function() {},
notifyError: function() {},
@@ -68,13 +71,17 @@ function test_oneCall() {
is(TelephonyUtils.hasAnyCalls(), true, "hasAnyCalls");
is(TelephonyUtils.hasConnectedCalls(), false, "hasConnectedCalls");
})
+ .then(() => waitForStateChanged(aAllInfo => {
+ return aAllInfo[0].callState === Ci.nsITelephonyService.CALL_STATE_ALERTING;
+ }))
.then(() => {
- let p = waitForStateChanged();
+ let p = waitForStateChanged(aAllInfo => {
+ return aAllInfo[0].callState === Ci.nsITelephonyService.CALL_STATE_CONNECTED;
+ });
emulator.runCmd("gsm accept " + number);
return p;
})
- .then(allInfo => {
- is(allInfo[0].callState, Ci.nsITelephonyService.CALL_STATE_CONNECTED);
+ .then(() => {
is(TelephonyUtils.hasAnyCalls(), true, "hasAnyCalls");
is(TelephonyUtils.hasConnectedCalls(), true, "hasConnectedCalls");
})
@@ -85,7 +92,10 @@ function test_oneCall() {
});
}
-test_noCall()
- .then(test_oneCall)
- .catch(error => ok(false, "Promise reject: " + error))
- .then(finish);
+startTest(function() {
+ return Promise.resolve()
+ .then(test_noCall)
+ .then(test_oneCall)
+ .catch(error => ok(false, "Promise reject: " + error))
+ .then(finish);
+});
diff --git a/mobile/android/base/ANRReporter.java b/mobile/android/base/ANRReporter.java
index 91753602122c..f9bb0acea4ff 100644
--- a/mobile/android/base/ANRReporter.java
+++ b/mobile/android/base/ANRReporter.java
@@ -20,8 +20,8 @@ import java.util.UUID;
import java.util.regex.Pattern;
import org.json.JSONObject;
+import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.AppConstants.Versions;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
import org.mozilla.gecko.util.ThreadUtils;
import android.content.BroadcastReceiver;
@@ -54,11 +54,11 @@ public final class ANRReporter extends BroadcastReceiver
private Handler mHandler;
private volatile boolean mPendingANR;
- @WrapElementForJNI
+ @WrapForJNI
private static native boolean requestNativeStack(boolean unwind);
- @WrapElementForJNI
+ @WrapForJNI
private static native String getNativeStack();
- @WrapElementForJNI
+ @WrapForJNI
private static native void releaseNativeStack();
public static void register(Context context) {
diff --git a/mobile/android/base/DownloadsIntegration.java b/mobile/android/base/DownloadsIntegration.java
index 8c65835b17f0..f107daf19986 100644
--- a/mobile/android/base/DownloadsIntegration.java
+++ b/mobile/android/base/DownloadsIntegration.java
@@ -5,11 +5,11 @@
package org.mozilla.gecko;
+import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.util.NativeEventListener;
import org.mozilla.gecko.util.NativeJSObject;
import org.mozilla.gecko.util.EventCallback;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
import java.io.File;
import java.lang.IllegalArgumentException;
@@ -108,7 +108,7 @@ public class DownloadsIntegration implements NativeEventListener
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT == state);
}
- @WrapElementForJNI
+ @WrapForJNI
public static void scanMedia(final String aFile, String aMimeType) {
String mimeType = aMimeType;
if (UNKNOWN_MIME_TYPES.contains(mimeType)) {
diff --git a/mobile/android/base/GeckoAppShell.java b/mobile/android/base/GeckoAppShell.java
index ed1d11814a04..70ef3ef16fad 100644
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -30,6 +30,7 @@ import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
+import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.favicons.Favicons;
@@ -41,7 +42,6 @@ import org.mozilla.gecko.mozglue.ContextUtils;
import org.mozilla.gecko.mozglue.GeckoLoader;
import org.mozilla.gecko.mozglue.JNITarget;
import org.mozilla.gecko.mozglue.RobocopTarget;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
import org.mozilla.gecko.overlays.ui.ShareDialog;
import org.mozilla.gecko.prompts.PromptService;
import org.mozilla.gecko.util.EventCallback;
@@ -461,19 +461,19 @@ public class GeckoAppShell
* The Gecko-side API: API methods that Gecko calls
*/
- @WrapElementForJNI(allowMultithread = true, noThrow = true)
+ @WrapForJNI(allowMultithread = true, noThrow = true)
public static void handleUncaughtException(Thread thread, Throwable e) {
CRASH_HANDLER.uncaughtException(thread, e);
}
- @WrapElementForJNI
+ @WrapForJNI
public static void notifyIME(int type) {
if (editableListener != null) {
editableListener.notifyIME(type);
}
}
- @WrapElementForJNI
+ @WrapForJNI
public static void notifyIMEContext(int state, String typeHint,
String modeHint, String actionHint) {
if (editableListener != null) {
@@ -482,7 +482,7 @@ public class GeckoAppShell
}
}
- @WrapElementForJNI
+ @WrapForJNI
public static void notifyIMEChange(String text, int start, int end, int newEnd) {
if (newEnd < 0) { // Selection change
editableListener.onSelectionChange(start, end);
@@ -534,7 +534,7 @@ public class GeckoAppShell
}
// Signal the Java thread that it's time to wake up
- @WrapElementForJNI
+ @WrapForJNI
public static void acknowledgeEvent() {
synchronized (sEventAckLock) {
sWaitingForEventAck = false;
@@ -555,7 +555,7 @@ public class GeckoAppShell
private static native long runUiThreadCallback();
- @WrapElementForJNI(allowMultithread = true)
+ @WrapForJNI(allowMultithread = true)
private static void requestUiThreadCallback(long delay) {
ThreadUtils.getUiHandler().postDelayed(sCallbackRunnable, delay);
}
@@ -591,7 +591,7 @@ public class GeckoAppShell
return lastKnownLocation;
}
- @WrapElementForJNI
+ @WrapForJNI
public static void enableLocation(final boolean enable) {
ThreadUtils.postToUiThread(new Runnable() {
@Override
@@ -647,12 +647,12 @@ public class GeckoAppShell
}
}
- @WrapElementForJNI
+ @WrapForJNI
public static void enableLocationHighAccuracy(final boolean enable) {
locationHighAccuracyEnabled = enable;
}
- @WrapElementForJNI
+ @WrapForJNI
public static void enableSensor(int aSensortype) {
GeckoInterface gi = getGeckoInterface();
if (gi == null)
@@ -722,7 +722,7 @@ public class GeckoAppShell
}
}
- @WrapElementForJNI
+ @WrapForJNI
public static void disableSensor(int aSensortype) {
GeckoInterface gi = getGeckoInterface();
if (gi == null)
@@ -776,7 +776,7 @@ public class GeckoAppShell
}
}
- @WrapElementForJNI
+ @WrapForJNI
public static void startMonitoringGamepad() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
@@ -786,7 +786,7 @@ public class GeckoAppShell
});
}
- @WrapElementForJNI
+ @WrapForJNI
public static void stopMonitoringGamepad() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
@@ -796,7 +796,7 @@ public class GeckoAppShell
});
}
- @WrapElementForJNI
+ @WrapForJNI
public static void gamepadAdded(final int device_id, final int service_id) {
ThreadUtils.postToUiThread(new Runnable() {
@Override
@@ -806,20 +806,20 @@ public class GeckoAppShell
});
}
- @WrapElementForJNI
+ @WrapForJNI
public static void moveTaskToBack() {
if (getGeckoInterface() != null)
getGeckoInterface().getActivity().moveTaskToBack(true);
}
- @WrapElementForJNI
+ @WrapForJNI
static void scheduleRestart() {
getGeckoInterface().doRestart();
}
// Creates a homescreen shortcut for a web page.
// This is the entry point from nsIShellService.
- @WrapElementForJNI
+ @WrapForJNI
static void createShortcut(final String aTitle, final String aURI, final String aIconData) {
// We have the favicon data (base64) decoded on the background thread, callback here, then
// call the other createShortcut method with the decoded favicon.
@@ -943,7 +943,7 @@ public class GeckoAppShell
return bitmap;
}
- @WrapElementForJNI(stubName = "GetHandlersForMimeTypeWrapper")
+ @WrapForJNI(stubName = "GetHandlersForMimeTypeWrapper")
static String[] getHandlersForMimeType(String aMimeType, String aAction) {
Intent intent = getIntentForActionString(aAction);
if (aMimeType != null && aMimeType.length() > 0)
@@ -951,7 +951,7 @@ public class GeckoAppShell
return getHandlersForIntent(intent);
}
- @WrapElementForJNI(stubName = "GetHandlersForURLWrapper")
+ @WrapForJNI(stubName = "GetHandlersForURLWrapper")
static String[] getHandlersForURL(String aURL, String aAction) {
// aURL may contain the whole URL or just the protocol
Uri uri = aURL.indexOf(':') >= 0 ? Uri.parse(aURL) : new Uri.Builder().scheme(aURL).build();
@@ -962,12 +962,12 @@ public class GeckoAppShell
return getHandlersForIntent(intent);
}
- @WrapElementForJNI(stubName = "GetHWEncoderCapability")
+ @WrapForJNI(stubName = "GetHWEncoderCapability")
static boolean getHWEncoderCapability() {
return HardwareCodecCapabilityUtils.getHWEncoderCapability();
}
- @WrapElementForJNI(stubName = "GetHWDecoderCapability")
+ @WrapForJNI(stubName = "GetHWDecoderCapability")
static boolean getHWDecoderCapability() {
return HardwareCodecCapabilityUtils.getHWDecoderCapability();
}
@@ -1028,12 +1028,12 @@ public class GeckoAppShell
return new Intent(aAction);
}
- @WrapElementForJNI(stubName = "GetExtensionFromMimeTypeWrapper")
+ @WrapForJNI(stubName = "GetExtensionFromMimeTypeWrapper")
static String getExtensionFromMimeType(String aMimeType) {
return MimeTypeMap.getSingleton().getExtensionFromMimeType(aMimeType);
}
- @WrapElementForJNI(stubName = "GetMimeTypeFromExtensionsWrapper")
+ @WrapForJNI(stubName = "GetMimeTypeFromExtensionsWrapper")
static String getMimeTypeFromExtensions(String aFileExt) {
StringTokenizer st = new StringTokenizer(aFileExt, ".,; ");
String type = null;
@@ -1094,7 +1094,7 @@ public class GeckoAppShell
* @param title the title to use in ACTION_SEND intents.
* @return true if the activity started successfully; false otherwise.
*/
- @WrapElementForJNI
+ @WrapForJNI
public static boolean openUriExternal(String targetURI,
String mimeType,
String packageName,
@@ -1382,7 +1382,7 @@ public class GeckoAppShell
}
}
- @WrapElementForJNI(stubName = "ShowAlertNotificationWrapper")
+ @WrapForJNI(stubName = "ShowAlertNotificationWrapper")
public static void showAlertNotification(String aImageUrl, String aAlertTitle, String aAlertText,
String aAlertCookie, String aAlertName) {
// The intent to launch when the user clicks the expanded notification
@@ -1409,13 +1409,13 @@ public class GeckoAppShell
notificationClient.add(notificationID, aImageUrl, aAlertTitle, aAlertText, contentIntent);
}
- @WrapElementForJNI
+ @WrapForJNI
public static void alertsProgressListener_OnProgress(String aAlertName, long aProgress, long aProgressMax, String aAlertText) {
int notificationID = aAlertName.hashCode();
notificationClient.update(notificationID, aProgress, aProgressMax, aAlertText);
}
- @WrapElementForJNI
+ @WrapForJNI
public static void closeNotification(String aAlertName) {
String alertCookie = ALERT_COOKIES.get(aAlertName);
if (alertCookie != null) {
@@ -1443,7 +1443,7 @@ public class GeckoAppShell
closeNotification(aAlertName);
}
- @WrapElementForJNI(stubName = "GetDpiWrapper")
+ @WrapForJNI(stubName = "GetDpiWrapper")
public static int getDpi() {
if (sDensityDpi == 0) {
sDensityDpi = getContext().getResources().getDisplayMetrics().densityDpi;
@@ -1452,7 +1452,7 @@ public class GeckoAppShell
return sDensityDpi;
}
- @WrapElementForJNI
+ @WrapForJNI
public static float getDensity() {
return getContext().getResources().getDisplayMetrics().density;
}
@@ -1465,7 +1465,7 @@ public class GeckoAppShell
* Returns the colour depth of the default screen. This will either be
* 24 or 16.
*/
- @WrapElementForJNI(stubName = "GetScreenDepthWrapper")
+ @WrapForJNI(stubName = "GetScreenDepthWrapper")
public static synchronized int getScreenDepth() {
if (sScreenDepth == 0) {
sScreenDepth = 16;
@@ -1488,13 +1488,13 @@ public class GeckoAppShell
sScreenDepth = aScreenDepth;
}
- @WrapElementForJNI
+ @WrapForJNI
public static void setFullScreen(boolean fullscreen) {
if (getGeckoInterface() != null)
getGeckoInterface().setFullScreen(fullscreen);
}
- @WrapElementForJNI
+ @WrapForJNI
public static void performHapticFeedback(boolean aIsLongPress) {
// Don't perform haptic feedback if a vibration is currently playing,
// because the haptic feedback will nuke the vibration.
@@ -1527,14 +1527,14 @@ public class GeckoAppShell
}
}
- @WrapElementForJNI(stubName = "Vibrate1")
+ @WrapForJNI(stubName = "Vibrate1")
public static void vibrate(long milliseconds) {
sVibrationEndTime = System.nanoTime() + milliseconds * 1000000;
sVibrationMaybePlaying = true;
vibrator().vibrate(milliseconds);
}
- @WrapElementForJNI(stubName = "VibrateA")
+ @WrapForJNI(stubName = "VibrateA")
public static void vibrate(long[] pattern, int repeat) {
// If pattern.length is even, the last element in the pattern is a
// meaningless delay, so don't include it in vibrationDuration.
@@ -1549,21 +1549,21 @@ public class GeckoAppShell
vibrator().vibrate(pattern, repeat);
}
- @WrapElementForJNI
+ @WrapForJNI
public static void cancelVibrate() {
sVibrationMaybePlaying = false;
sVibrationEndTime = 0;
vibrator().cancel();
}
- @WrapElementForJNI
+ @WrapForJNI
public static void showInputMethodPicker() {
InputMethodManager imm = (InputMethodManager)
getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showInputMethodPicker();
}
- @WrapElementForJNI
+ @WrapForJNI
public static void setKeepScreenOn(final boolean on) {
ThreadUtils.postToUiThread(new Runnable() {
@Override
@@ -1573,7 +1573,7 @@ public class GeckoAppShell
});
}
- @WrapElementForJNI
+ @WrapForJNI
public static void notifyDefaultPrevented(final boolean defaultPrevented) {
ThreadUtils.postToUiThread(new Runnable() {
@Override
@@ -1587,7 +1587,7 @@ public class GeckoAppShell
});
}
- @WrapElementForJNI
+ @WrapForJNI
public static boolean isNetworkLinkUp() {
ConnectivityManager cm = (ConnectivityManager)
getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -1601,7 +1601,7 @@ public class GeckoAppShell
return true;
}
- @WrapElementForJNI
+ @WrapForJNI
public static boolean isNetworkLinkKnown() {
ConnectivityManager cm = (ConnectivityManager)
getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -1614,7 +1614,7 @@ public class GeckoAppShell
return true;
}
- @WrapElementForJNI
+ @WrapForJNI
public static int networkLinkType() {
ConnectivityManager cm = (ConnectivityManager)
getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -1673,7 +1673,7 @@ public class GeckoAppShell
}
}
- @WrapElementForJNI(stubName = "GetSystemColoursWrapper")
+ @WrapForJNI(stubName = "GetSystemColoursWrapper")
public static int[] getSystemColors() {
// attrsAppearance[] must correspond to AndroidSystemColors structure in android/AndroidBridge.h
final int[] attrsAppearance = {
@@ -1710,7 +1710,7 @@ public class GeckoAppShell
return result;
}
- @WrapElementForJNI
+ @WrapForJNI
public static void killAnyZombies() {
GeckoProcessesVisitor visitor = new GeckoProcessesVisitor() {
@Override
@@ -1840,7 +1840,7 @@ public class GeckoAppShell
} catch (Exception e) { }
}
- @WrapElementForJNI(stubName = "GetIconForExtensionWrapper")
+ @WrapForJNI(stubName = "GetIconForExtensionWrapper")
public static byte[] getIconForExtension(String aExt, int iconSize) {
try {
if (iconSize <= 0)
@@ -1898,7 +1898,7 @@ public class GeckoAppShell
return activityInfo.loadIcon(pm);
}
- @WrapElementForJNI
+ @WrapForJNI
public static boolean getShowPasswordSetting() {
try {
int showPassword =
@@ -1911,7 +1911,7 @@ public class GeckoAppShell
}
}
- @WrapElementForJNI(stubName = "AddPluginViewWrapper")
+ @WrapForJNI(stubName = "AddPluginViewWrapper")
public static void addPluginView(View view,
float x, float y,
float w, float h,
@@ -1920,7 +1920,7 @@ public class GeckoAppShell
getGeckoInterface().addPluginView(view, new RectF(x, y, x + w, y + h), isFullScreen);
}
- @WrapElementForJNI
+ @WrapForJNI
public static void removePluginView(View view, boolean isFullScreen) {
if (getGeckoInterface() != null)
getGeckoInterface().removePluginView(view, isFullScreen);
@@ -2126,7 +2126,7 @@ public class GeckoAppShell
return pluginCL.loadClass(className);
}
- @WrapElementForJNI(allowMultithread = true)
+ @WrapForJNI(allowMultithread = true)
public static Class> loadPluginClass(String className, String libName) {
if (getGeckoInterface() == null)
return null;
@@ -2146,7 +2146,7 @@ public class GeckoAppShell
private static ContextGetter sContextGetter;
- @WrapElementForJNI(allowMultithread = true)
+ @WrapForJNI(allowMultithread = true)
public static Context getContext() {
return sContextGetter.getContext();
}
@@ -2210,7 +2210,7 @@ public class GeckoAppShell
static byte[] sCameraBuffer;
- @WrapElementForJNI(stubName = "InitCameraWrapper")
+ @WrapForJNI(stubName = "InitCameraWrapper")
static int[] initCamera(String aContentType, int aCamera, int aWidth, int aHeight) {
ThreadUtils.postToUiThread(new Runnable() {
@Override
@@ -2304,7 +2304,7 @@ public class GeckoAppShell
return result;
}
- @WrapElementForJNI
+ @WrapForJNI
static synchronized void closeCamera() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
@@ -2326,33 +2326,33 @@ public class GeckoAppShell
/*
* Battery API related methods.
*/
- @WrapElementForJNI
+ @WrapForJNI
public static void enableBatteryNotifications() {
GeckoBatteryManager.enableNotifications();
}
- @WrapElementForJNI(stubName = "HandleGeckoMessageWrapper")
+ @WrapForJNI(stubName = "HandleGeckoMessageWrapper")
public static void handleGeckoMessage(final NativeJSContainer message) {
EventDispatcher.getInstance().dispatchEvent(message);
message.disposeNative();
}
- @WrapElementForJNI
+ @WrapForJNI
public static void disableBatteryNotifications() {
GeckoBatteryManager.disableNotifications();
}
- @WrapElementForJNI(stubName = "GetCurrentBatteryInformationWrapper")
+ @WrapForJNI(stubName = "GetCurrentBatteryInformationWrapper")
public static double[] getCurrentBatteryInformation() {
return GeckoBatteryManager.getCurrentInformation();
}
- @WrapElementForJNI(stubName = "CheckURIVisited")
+ @WrapForJNI(stubName = "CheckURIVisited")
static void checkUriVisited(String uri) {
GlobalHistory.getInstance().checkUriVisited(uri);
}
- @WrapElementForJNI(stubName = "MarkURIVisited")
+ @WrapForJNI(stubName = "MarkURIVisited")
static void markUriVisited(final String uri) {
final Context context = getContext();
final BrowserDB db = GeckoProfile.get(context).getDB();
@@ -2364,7 +2364,7 @@ public class GeckoAppShell
});
}
- @WrapElementForJNI(stubName = "SetURITitle")
+ @WrapForJNI(stubName = "SetURITitle")
static void setUriTitle(final String uri, final String title) {
final Context context = getContext();
final BrowserDB db = GeckoProfile.get(context).getDB();
@@ -2376,7 +2376,7 @@ public class GeckoAppShell
});
}
- @WrapElementForJNI
+ @WrapForJNI
static void hideProgressDialog() {
// unused stub
}
@@ -2384,7 +2384,7 @@ public class GeckoAppShell
/*
* WebSMS related methods.
*/
- @WrapElementForJNI(stubName = "SendMessageWrapper")
+ @WrapForJNI(stubName = "SendMessageWrapper")
public static void sendMessage(String aNumber, String aMessage, int aRequestId) {
if (!SmsManager.isEnabled()) {
return;
@@ -2393,7 +2393,7 @@ public class GeckoAppShell
SmsManager.getInstance().send(aNumber, aMessage, aRequestId);
}
- @WrapElementForJNI(stubName = "GetMessageWrapper")
+ @WrapForJNI(stubName = "GetMessageWrapper")
public static void getMessage(int aMessageId, int aRequestId) {
if (!SmsManager.isEnabled()) {
return;
@@ -2402,7 +2402,7 @@ public class GeckoAppShell
SmsManager.getInstance().getMessage(aMessageId, aRequestId);
}
- @WrapElementForJNI(stubName = "DeleteMessageWrapper")
+ @WrapForJNI(stubName = "DeleteMessageWrapper")
public static void deleteMessage(int aMessageId, int aRequestId) {
if (!SmsManager.isEnabled()) {
return;
@@ -2411,7 +2411,7 @@ public class GeckoAppShell
SmsManager.getInstance().deleteMessage(aMessageId, aRequestId);
}
- @WrapElementForJNI(stubName = "CreateMessageListWrapper")
+ @WrapForJNI(stubName = "CreateMessageListWrapper")
public static void createMessageList(long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, String aDelivery, boolean aHasRead, boolean aRead, long aThreadId, boolean aReverse, int aRequestId) {
if (!SmsManager.isEnabled()) {
return;
@@ -2420,7 +2420,7 @@ public class GeckoAppShell
SmsManager.getInstance().createMessageList(aStartDate, aEndDate, aNumbers, aNumbersCount, aDelivery, aHasRead, aRead, aThreadId, aReverse, aRequestId);
}
- @WrapElementForJNI(stubName = "GetNextMessageInListWrapper")
+ @WrapForJNI(stubName = "GetNextMessageInListWrapper")
public static void getNextMessageInList(int aListId, int aRequestId) {
if (!SmsManager.isEnabled()) {
return;
@@ -2429,7 +2429,7 @@ public class GeckoAppShell
SmsManager.getInstance().getNextMessageInList(aListId, aRequestId);
}
- @WrapElementForJNI
+ @WrapForJNI
public static void clearMessageList(int aListId) {
if (!SmsManager.isEnabled()) {
return;
@@ -2439,7 +2439,7 @@ public class GeckoAppShell
}
/* Called by JNI from AndroidBridge, and by reflection from tests/BaseTest.java.in */
- @WrapElementForJNI
+ @WrapForJNI
@RobocopTarget
public static boolean isTablet() {
return HardwareUtils.isTablet();
@@ -2453,12 +2453,12 @@ public class GeckoAppShell
}
}
- @WrapElementForJNI(stubName = "GetCurrentNetworkInformationWrapper")
+ @WrapForJNI(stubName = "GetCurrentNetworkInformationWrapper")
public static double[] getCurrentNetworkInformation() {
return GeckoNetworkManager.getInstance().getCurrentInformation();
}
- @WrapElementForJNI
+ @WrapForJNI
public static void enableNetworkNotifications() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
@@ -2468,7 +2468,7 @@ public class GeckoAppShell
});
}
- @WrapElementForJNI
+ @WrapForJNI
public static void disableNetworkNotifications() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
@@ -2478,32 +2478,32 @@ public class GeckoAppShell
});
}
- @WrapElementForJNI(stubName = "GetScreenOrientationWrapper")
+ @WrapForJNI(stubName = "GetScreenOrientationWrapper")
public static short getScreenOrientation() {
return GeckoScreenOrientation.getInstance().getScreenOrientation().value;
}
- @WrapElementForJNI
+ @WrapForJNI
public static void enableScreenOrientationNotifications() {
GeckoScreenOrientation.getInstance().enableNotifications();
}
- @WrapElementForJNI
+ @WrapForJNI
public static void disableScreenOrientationNotifications() {
GeckoScreenOrientation.getInstance().disableNotifications();
}
- @WrapElementForJNI
+ @WrapForJNI
public static void lockScreenOrientation(int aOrientation) {
GeckoScreenOrientation.getInstance().lock(aOrientation);
}
- @WrapElementForJNI
+ @WrapForJNI
public static void unlockScreenOrientation() {
GeckoScreenOrientation.getInstance().unlock();
}
- @WrapElementForJNI
+ @WrapForJNI
public static boolean pumpMessageLoop(final Message msg) {
final Handler geckoHandler = ThreadUtils.sGeckoHandler;
@@ -2521,13 +2521,13 @@ public class GeckoAppShell
return true;
}
- @WrapElementForJNI
+ @WrapForJNI
public static void notifyWakeLockChanged(String topic, String state) {
if (getGeckoInterface() != null)
getGeckoInterface().notifyWakeLockChanged(topic, state);
}
- @WrapElementForJNI(allowMultithread = true)
+ @WrapForJNI(allowMultithread = true)
public static void registerSurfaceTextureFrameListener(Object surfaceTexture, final int id) {
((SurfaceTexture)surfaceTexture).setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() {
@Override
@@ -2537,12 +2537,12 @@ public class GeckoAppShell
});
}
- @WrapElementForJNI(allowMultithread = true)
+ @WrapForJNI(allowMultithread = true)
public static void unregisterSurfaceTextureFrameListener(Object surfaceTexture) {
((SurfaceTexture)surfaceTexture).setOnFrameAvailableListener(null);
}
- @WrapElementForJNI
+ @WrapForJNI
public static boolean unlockProfile() {
// Try to kill any zombie Fennec's that might be running
GeckoAppShell.killAnyZombies();
@@ -2556,7 +2556,7 @@ public class GeckoAppShell
return false;
}
- @WrapElementForJNI(stubName = "GetProxyForURIWrapper")
+ @WrapForJNI(stubName = "GetProxyForURIWrapper")
public static String getProxyForURI(String spec, String scheme, String host, int port) {
final ProxySelector ps = new ProxySelector();
@@ -2653,12 +2653,12 @@ public class GeckoAppShell
toast.show();
}
- @WrapElementForJNI(allowMultithread = true)
+ @WrapForJNI(allowMultithread = true)
static InputStream createInputStream(URLConnection connection) throws IOException {
return connection.getInputStream();
}
- @WrapElementForJNI(allowMultithread = true, narrowChars = true)
+ @WrapForJNI(allowMultithread = true, narrowChars = true)
static URLConnection getConnection(String url) {
try {
String spec;
@@ -2679,7 +2679,7 @@ public class GeckoAppShell
return null;
}
- @WrapElementForJNI(allowMultithread = true, narrowChars = true)
+ @WrapForJNI(allowMultithread = true, narrowChars = true)
static String connectionGetMimeType(URLConnection connection) {
return connection.getContentType();
}
@@ -2690,7 +2690,7 @@ public class GeckoAppShell
* @param type The type of directory to return
* @return Absolute path of the specified directory or null on failure
*/
- @WrapElementForJNI
+ @WrapForJNI
static String getExternalPublicDirectory(final String type) {
final String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state) &&
@@ -2719,7 +2719,7 @@ public class GeckoAppShell
return Environment.getExternalStoragePublicDirectory(systemType).getAbsolutePath();
}
- @WrapElementForJNI
+ @WrapForJNI
static int getMaxTouchPoints() {
PackageManager pm = getContext().getPackageManager();
if (pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND)) {
diff --git a/mobile/android/base/GeckoJavaSampler.java b/mobile/android/base/GeckoJavaSampler.java
index f2304764cbca..0ba1abb1ab38 100644
--- a/mobile/android/base/GeckoJavaSampler.java
+++ b/mobile/android/base/GeckoJavaSampler.java
@@ -9,7 +9,7 @@ import android.os.SystemClock;
import android.util.Log;
import android.util.SparseArray;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
+import org.mozilla.gecko.annotation.WrapForJNI;
import java.lang.Thread;
import java.util.Set;
@@ -126,7 +126,7 @@ public class GeckoJavaSampler {
}
- @WrapElementForJNI(allowMultithread = true, stubName = "GetThreadNameJavaProfilingWrapper")
+ @WrapForJNI(allowMultithread = true, stubName = "GetThreadNameJavaProfilingWrapper")
public synchronized static String getThreadName(int aThreadId) {
if (aThreadId == 0 && sMainThread != null) {
return sMainThread.getName();
@@ -138,7 +138,7 @@ public class GeckoJavaSampler {
return sSamplingRunnable.getSample(aThreadId, aSampleId);
}
- @WrapElementForJNI(allowMultithread = true, stubName = "GetSampleTimeJavaProfiling")
+ @WrapForJNI(allowMultithread = true, stubName = "GetSampleTimeJavaProfiling")
public synchronized static double getSampleTime(int aThreadId, int aSampleId) {
Sample sample = getSample(aThreadId, aSampleId);
if (sample != null) {
@@ -152,7 +152,7 @@ public class GeckoJavaSampler {
return 0;
}
- @WrapElementForJNI(allowMultithread = true, stubName = "GetFrameNameJavaProfilingWrapper")
+ @WrapForJNI(allowMultithread = true, stubName = "GetFrameNameJavaProfilingWrapper")
public synchronized static String getFrameName(int aThreadId, int aSampleId, int aFrameId) {
Sample sample = getSample(aThreadId, aSampleId);
if (sample != null && aFrameId < sample.mFrames.length) {
@@ -165,7 +165,7 @@ public class GeckoJavaSampler {
return null;
}
- @WrapElementForJNI(allowMultithread = true, stubName = "StartJavaProfiling")
+ @WrapForJNI(allowMultithread = true, stubName = "StartJavaProfiling")
public static void start(int aInterval, int aSamples) {
synchronized (GeckoJavaSampler.class) {
if (sSamplingRunnable != null) {
@@ -177,21 +177,21 @@ public class GeckoJavaSampler {
}
}
- @WrapElementForJNI(allowMultithread = true, stubName = "PauseJavaProfiling")
+ @WrapForJNI(allowMultithread = true, stubName = "PauseJavaProfiling")
public static void pause() {
synchronized (GeckoJavaSampler.class) {
sSamplingRunnable.mPauseSampler = true;
}
}
- @WrapElementForJNI(allowMultithread = true, stubName = "UnpauseJavaProfiling")
+ @WrapForJNI(allowMultithread = true, stubName = "UnpauseJavaProfiling")
public static void unpause() {
synchronized (GeckoJavaSampler.class) {
sSamplingRunnable.mPauseSampler = false;
}
}
- @WrapElementForJNI(allowMultithread = true, stubName = "StopJavaProfiling")
+ @WrapForJNI(allowMultithread = true, stubName = "StopJavaProfiling")
public static void stop() {
synchronized (GeckoJavaSampler.class) {
if (sSamplingThread == null) {
diff --git a/mobile/android/base/RestrictedProfiles.java b/mobile/android/base/RestrictedProfiles.java
index ec8dc6e9912b..a5c017aecfef 100644
--- a/mobile/android/base/RestrictedProfiles.java
+++ b/mobile/android/base/RestrictedProfiles.java
@@ -5,9 +5,9 @@
package org.mozilla.gecko;
+import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.mozglue.RobocopTarget;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
import org.mozilla.gecko.restrictions.DefaultConfiguration;
import org.mozilla.gecko.restrictions.GuestProfileConfiguration;
import org.mozilla.gecko.restrictions.RestrictedProfileConfiguration;
@@ -90,7 +90,7 @@ public class RestrictedProfiles {
return getConfiguration(context).canLoadUrl(url);
}
- @WrapElementForJNI
+ @WrapForJNI
public static boolean isUserRestricted() {
return isUserRestricted(GeckoAppShell.getContext());
}
@@ -103,7 +103,7 @@ public class RestrictedProfiles {
return getConfiguration(context).isAllowed(restriction);
}
- @WrapElementForJNI
+ @WrapForJNI
public static boolean isAllowed(int action, String url) {
final Restriction restriction;
try {
diff --git a/mobile/android/base/SurfaceBits.java b/mobile/android/base/SurfaceBits.java
index 0647aca78f1a..6bffa3a60282 100644
--- a/mobile/android/base/SurfaceBits.java
+++ b/mobile/android/base/SurfaceBits.java
@@ -4,11 +4,11 @@
package org.mozilla.gecko;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
+import org.mozilla.gecko.annotation.WrapForJNI;
import java.nio.ByteBuffer;
-@WrapElementForJNI
+@WrapForJNI
public class SurfaceBits {
public int width;
public int height;
diff --git a/mobile/android/base/ThumbnailHelper.java b/mobile/android/base/ThumbnailHelper.java
index e905d4e02f29..225d544455a0 100644
--- a/mobile/android/base/ThumbnailHelper.java
+++ b/mobile/android/base/ThumbnailHelper.java
@@ -5,9 +5,9 @@
package org.mozilla.gecko;
+import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.gfx.BitmapUtils;
import org.mozilla.gecko.mozglue.DirectBufferAllocator;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -153,7 +153,7 @@ public final class ThumbnailHelper {
}
/* This method is invoked by JNI once the thumbnail data is ready. */
- @WrapElementForJNI(stubName = "SendThumbnail")
+ @WrapForJNI(stubName = "SendThumbnail")
public static void notifyThumbnail(ByteBuffer data, int tabId, boolean success, boolean shouldStore) {
Tab tab = Tabs.getInstance().getTab(tabId);
ThumbnailHelper helper = ThumbnailHelper.getInstance();
diff --git a/mobile/android/base/mozglue/generatorannotations/WrapElementForJNI.java b/mobile/android/base/annotation/WrapForJNI.java
similarity index 96%
rename from mobile/android/base/mozglue/generatorannotations/WrapElementForJNI.java
rename to mobile/android/base/annotation/WrapForJNI.java
index d9fc485db6d7..87ec2ad649b0 100644
--- a/mobile/android/base/mozglue/generatorannotations/WrapElementForJNI.java
+++ b/mobile/android/base/annotation/WrapForJNI.java
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-package org.mozilla.gecko.mozglue.generatorannotations;
+package org.mozilla.gecko.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -24,7 +24,7 @@ import java.lang.annotation.Target;
*/
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
-public @interface WrapElementForJNI {
+public @interface WrapForJNI {
// Optional parameter specifying the name of the generated method stub. If omitted, the name
// of the Java method will be used.
String stubName() default "";
diff --git a/mobile/android/base/gfx/DisplayPortMetrics.java b/mobile/android/base/gfx/DisplayPortMetrics.java
index 4bb5e8de8018..40a0015059f4 100644
--- a/mobile/android/base/gfx/DisplayPortMetrics.java
+++ b/mobile/android/base/gfx/DisplayPortMetrics.java
@@ -5,7 +5,7 @@
package org.mozilla.gecko.gfx;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
+import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.util.FloatUtils;
import android.graphics.RectF;
@@ -19,16 +19,16 @@ import android.graphics.RectF;
* subsection of that with compositor scaling.
*/
public final class DisplayPortMetrics {
- @WrapElementForJNI
+ @WrapForJNI
public final float resolution;
- @WrapElementForJNI
+ @WrapForJNI
private final RectF mPosition;
public DisplayPortMetrics() {
this(0, 0, 0, 0, 1);
}
- @WrapElementForJNI
+ @WrapForJNI
public DisplayPortMetrics(float left, float top, float right, float bottom, float resolution) {
this.resolution = resolution;
mPosition = new RectF(left, top, right, bottom);
diff --git a/mobile/android/base/gfx/GLController.java b/mobile/android/base/gfx/GLController.java
index 900662e37ba3..cead8a544e27 100644
--- a/mobile/android/base/gfx/GLController.java
+++ b/mobile/android/base/gfx/GLController.java
@@ -5,11 +5,11 @@
package org.mozilla.gecko.gfx;
+import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.AppConstants;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.GeckoThread;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
import org.mozilla.gecko.util.ThreadUtils;
import android.util.Log;
@@ -250,7 +250,7 @@ public class GLController {
return mEGLSurfaceForCompositor != null;
}
- @WrapElementForJNI(allowMultithread = true, stubName = "CreateEGLSurfaceForCompositorWrapper")
+ @WrapForJNI(allowMultithread = true, stubName = "CreateEGLSurfaceForCompositorWrapper")
private synchronized EGLSurface createEGLSurfaceForCompositor() {
AttemptPreallocateEGLSurfaceForCompositor();
EGLSurface result = mEGLSurfaceForCompositor;
diff --git a/mobile/android/base/gfx/GeckoLayerClient.java b/mobile/android/base/gfx/GeckoLayerClient.java
index d9f3d5196dfc..612f27859473 100644
--- a/mobile/android/base/gfx/GeckoLayerClient.java
+++ b/mobile/android/base/gfx/GeckoLayerClient.java
@@ -5,6 +5,7 @@
package org.mozilla.gecko.gfx;
+import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.gfx.LayerView.DrawListener;
@@ -12,7 +13,6 @@ import org.mozilla.gecko.Tab;
import org.mozilla.gecko.Tabs;
import org.mozilla.gecko.ZoomConstraints;
import org.mozilla.gecko.mozglue.RobocopTarget;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.util.FloatUtils;
import org.mozilla.gecko.AppConstants;
@@ -436,7 +436,7 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
return mDisplayPort;
}
- @WrapElementForJNI
+ @WrapForJNI
DisplayPortMetrics getDisplayPort(boolean pageSizeUpdate, boolean isBrowserContentDisplayed, int tabId, ImmutableViewportMetrics metrics) {
Tabs tabs = Tabs.getInstance();
if (isBrowserContentDisplayed && tabs.isSelectedTabId(tabId)) {
@@ -453,12 +453,12 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
}
}
- @WrapElementForJNI
+ @WrapForJNI
void contentDocumentChanged() {
mContentDocumentIsDisplayed = false;
}
- @WrapElementForJNI
+ @WrapForJNI
boolean isContentDocumentDisplayed() {
return mContentDocumentIsDisplayed;
}
@@ -468,7 +468,7 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
// to abort the current update and continue with any subsequent ones. This
// is useful for slow-to-render pages when the display-port starts lagging
// behind enough that continuing to draw it is wasted effort.
- @WrapElementForJNI(allowMultithread = true)
+ @WrapForJNI(allowMultithread = true)
public ProgressiveUpdateData progressiveUpdateCallback(boolean aHasPendingNewThebesContent,
float x, float y, float width, float height,
float resolution, boolean lowPrecision) {
@@ -582,7 +582,7 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
* viewport information provided. setPageRect will never be invoked on the same frame that
* this function is invoked on; and this function will always be called prior to syncViewportInfo.
*/
- @WrapElementForJNI(allowMultithread = true)
+ @WrapForJNI(allowMultithread = true)
public void setFirstPaintViewport(float offsetX, float offsetY, float zoom,
float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom) {
synchronized (getLock()) {
@@ -642,7 +642,7 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
* is invoked on a frame, then this function will not be. For any given frame, this
* function will be invoked before syncViewportInfo.
*/
- @WrapElementForJNI(allowMultithread = true)
+ @WrapForJNI(allowMultithread = true)
public void setPageRect(float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom) {
synchronized (getLock()) {
RectF cssPageRect = new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom);
@@ -663,7 +663,7 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
* every time we're called. NOTE: we might be able to return a ImmutableViewportMetrics
* which would avoid the copy into mCurrentViewTransform.
*/
- @WrapElementForJNI(allowMultithread = true)
+ @WrapForJNI(allowMultithread = true)
public ViewTransform syncViewportInfo(int x, int y, int width, int height, float resolution, boolean layersUpdated) {
// getViewportMetrics is thread safe so we don't need to synchronize.
// We save the viewport metrics here, so we later use it later in
@@ -720,7 +720,7 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
return mCurrentViewTransform;
}
- @WrapElementForJNI(allowMultithread = true)
+ @WrapForJNI(allowMultithread = true)
public ViewTransform syncFrameMetrics(float offsetX, float offsetY, float zoom,
float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom,
boolean layersUpdated, int x, int y, int width, int height, float resolution,
@@ -734,7 +734,7 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
return syncViewportInfo(x, y, width, height, resolution, layersUpdated);
}
- @WrapElementForJNI(allowMultithread = true)
+ @WrapForJNI(allowMultithread = true)
public LayerRenderer.Frame createFrame() {
// Create the shaders and textures if necessary.
if (!mLayerRendererInitialized) {
@@ -754,12 +754,12 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
}
}
- @WrapElementForJNI(allowMultithread = true)
+ @WrapForJNI(allowMultithread = true)
public void activateProgram() {
mLayerRenderer.activateDefaultProgram();
}
- @WrapElementForJNI(allowMultithread = true)
+ @WrapForJNI(allowMultithread = true)
public void deactivateProgramAndRestoreState(boolean enableScissor,
int scissorX, int scissorY, int scissorW, int scissorH)
{
diff --git a/mobile/android/base/gfx/ImmutableViewportMetrics.java b/mobile/android/base/gfx/ImmutableViewportMetrics.java
index 817190c6c45f..656b3408509a 100644
--- a/mobile/android/base/gfx/ImmutableViewportMetrics.java
+++ b/mobile/android/base/gfx/ImmutableViewportMetrics.java
@@ -5,7 +5,7 @@
package org.mozilla.gecko.gfx;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
+import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.util.FloatUtils;
import android.graphics.PointF;
@@ -53,7 +53,7 @@ public class ImmutableViewportMetrics {
/** This constructor is used by native code in AndroidJavaWrappers.cpp, be
* careful when modifying the signature.
*/
- @WrapElementForJNI(allowMultithread = true)
+ @WrapForJNI(allowMultithread = true)
public ImmutableViewportMetrics(float aPageRectLeft, float aPageRectTop,
float aPageRectRight, float aPageRectBottom, float aCssPageRectLeft,
float aCssPageRectTop, float aCssPageRectRight, float aCssPageRectBottom,
diff --git a/mobile/android/base/gfx/LayerView.java b/mobile/android/base/gfx/LayerView.java
index cef1944aa5b5..8fa2820d56a7 100644
--- a/mobile/android/base/gfx/LayerView.java
+++ b/mobile/android/base/gfx/LayerView.java
@@ -10,6 +10,7 @@ import java.nio.IntBuffer;
import java.util.ArrayList;
import org.mozilla.gecko.AndroidGamepadManager;
+import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoAccessibility;
@@ -20,7 +21,6 @@ import org.mozilla.gecko.Tab;
import org.mozilla.gecko.Tabs;
import org.mozilla.gecko.ZoomConstraints;
import org.mozilla.gecko.mozglue.RobocopTarget;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
import android.content.Context;
import android.graphics.Bitmap;
@@ -515,7 +515,7 @@ public class LayerView extends FrameLayout implements Tabs.OnTabsChangedListener
return mTextureView.getSurfaceTexture();
}
- @WrapElementForJNI(allowMultithread = true, stubName = "RegisterCompositorWrapper")
+ @WrapForJNI(allowMultithread = true, stubName = "RegisterCompositorWrapper")
public static GLController registerCxxCompositor() {
try {
LayerView layerView = GeckoAppShell.getLayerView();
@@ -529,7 +529,7 @@ public class LayerView extends FrameLayout implements Tabs.OnTabsChangedListener
}
//This method is called on the Gecko main thread.
- @WrapElementForJNI(allowMultithread = true, stubName = "updateZoomedView")
+ @WrapForJNI(allowMultithread = true, stubName = "updateZoomedView")
public static void updateZoomedView(ByteBuffer data) {
LayerView layerView = GeckoAppShell.getLayerView();
if (layerView != null) {
diff --git a/mobile/android/base/gfx/NativePanZoomController.java b/mobile/android/base/gfx/NativePanZoomController.java
index 45fe1dea36f4..947c1f2715f9 100644
--- a/mobile/android/base/gfx/NativePanZoomController.java
+++ b/mobile/android/base/gfx/NativePanZoomController.java
@@ -5,9 +5,9 @@
package org.mozilla.gecko.gfx;
+import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.GeckoThread;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.util.GeckoEventListener;
@@ -97,7 +97,7 @@ class NativePanZoomController implements PanZoomController, GeckoEventListener {
@Override
public native int getOverScrollMode();
- @WrapElementForJNI(allowMultithread = true, stubName = "RequestContentRepaintWrapper")
+ @WrapForJNI(allowMultithread = true, stubName = "RequestContentRepaintWrapper")
private void requestContentRepaint(float x, float y, float width, float height, float resolution) {
mTarget.forceRedraw(new DisplayPortMetrics(x, y, x + width, y + height, resolution));
}
diff --git a/mobile/android/base/gfx/ProgressiveUpdateData.java b/mobile/android/base/gfx/ProgressiveUpdateData.java
index 7dd103aeddf5..d961a2569f1b 100644
--- a/mobile/android/base/gfx/ProgressiveUpdateData.java
+++ b/mobile/android/base/gfx/ProgressiveUpdateData.java
@@ -5,7 +5,7 @@
package org.mozilla.gecko.gfx;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
+import org.mozilla.gecko.annotation.WrapForJNI;
/**
* This is the data structure that's returned by the progressive tile update
@@ -13,7 +13,7 @@ import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
* representing whether the front-end is interested in the current progressive
* update continuing.
*/
-@WrapElementForJNI
+@WrapForJNI
public class ProgressiveUpdateData {
public float x;
public float y;
diff --git a/mobile/android/base/gfx/ViewTransform.java b/mobile/android/base/gfx/ViewTransform.java
index 1b381ddd32c2..ee557ccf4639 100644
--- a/mobile/android/base/gfx/ViewTransform.java
+++ b/mobile/android/base/gfx/ViewTransform.java
@@ -5,9 +5,9 @@
package org.mozilla.gecko.gfx;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
+import org.mozilla.gecko.annotation.WrapForJNI;
-@WrapElementForJNI
+@WrapForJNI
public class ViewTransform {
public float x;
public float y;
diff --git a/mobile/android/base/mdns/MulticastDNSManager.java b/mobile/android/base/mdns/MulticastDNSManager.java
index ad0dd1f46886..ed3a78de9264 100644
--- a/mobile/android/base/mdns/MulticastDNSManager.java
+++ b/mobile/android/base/mdns/MulticastDNSManager.java
@@ -37,7 +37,8 @@ public abstract class MulticastDNSManager {
public static MulticastDNSManager getInstance(final Context context) {
if (instance == null) {
- if (Versions.feature16Plus) {
+ // Bug 1188935: There's a bug on Android 4.4 and before.
+ if (Versions.feature21Plus) {
instance = new NsdMulticastDNSManager(context);
} else {
instance = new DummyMulticastDNSManager();
diff --git a/mobile/android/base/moz.build b/mobile/android/base/moz.build
index e4c2fe6fada5..aa19e3ae2607 100644
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -14,6 +14,7 @@ thirdparty_source_dir = TOPSRCDIR + '/mobile/android/thirdparty/'
constants_jar = add_java_jar('constants')
constants_jar.sources = [
'adjust/AdjustHelperInterface.java',
+ 'annotation/WrapForJNI.java',
'SysInfo.java',
]
constants_jar.generated_sources = [
@@ -54,7 +55,6 @@ mgjar.sources += [
'mozglue/ContextUtils.java',
'mozglue/DirectBufferAllocator.java',
'mozglue/GeckoLoader.java',
- 'mozglue/generatorannotations/WrapElementForJNI.java',
'mozglue/JNIObject.java',
'mozglue/JNITarget.java',
'mozglue/NativeReference.java',
@@ -133,6 +133,7 @@ if CONFIG['MOZ_WEBRTC']:
audio_root + 'WebRtcAudioTrack.java',
]
wrjar.extra_jars = [
+ 'constants.jar',
'gecko-R.jar',
'gecko-browser.jar',
'gecko-util.jar',
diff --git a/mobile/android/base/mozglue/NativeZip.java b/mobile/android/base/mozglue/NativeZip.java
index 84e8ac643785..8a35d155fb91 100644
--- a/mobile/android/base/mozglue/NativeZip.java
+++ b/mobile/android/base/mozglue/NativeZip.java
@@ -5,7 +5,7 @@
package org.mozilla.gecko.mozglue;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
+import org.mozilla.gecko.mozglue.JNITarget;
import java.io.InputStream;
import java.nio.ByteBuffer;
@@ -69,7 +69,7 @@ public class NativeZip implements NativeReference {
private static native void _release(long obj);
private native InputStream _getInputStream(long obj, String path);
- @WrapElementForJNI
+ @JNITarget
private InputStream createInputStream(ByteBuffer buffer, int compression) {
if (compression != STORE && compression != DEFLATE) {
throw new IllegalArgumentException("Unexpected compression: " + compression);
diff --git a/mobile/android/base/sqlite/MatrixBlobCursor.java b/mobile/android/base/sqlite/MatrixBlobCursor.java
index 5026994a150b..5a6b146a7b3b 100644
--- a/mobile/android/base/sqlite/MatrixBlobCursor.java
+++ b/mobile/android/base/sqlite/MatrixBlobCursor.java
@@ -20,8 +20,8 @@ package org.mozilla.gecko.sqlite;
import java.nio.ByteBuffer;
import java.util.ArrayList;
+import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.AppConstants;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
import android.database.AbstractCursor;
import android.database.CursorIndexOutOfBoundsException;
@@ -56,7 +56,7 @@ public class MatrixBlobCursor extends AbstractCursor {
* determines column ordering elsewhere in this cursor
* @param initialCapacity in rows
*/
- @WrapElementForJNI
+ @WrapForJNI
public MatrixBlobCursor(String[] columnNames, int initialCapacity) {
this.columnNames = columnNames;
this.columnCount = columnNames.length;
@@ -77,7 +77,7 @@ public class MatrixBlobCursor extends AbstractCursor {
* @param columnNames names of the columns, the ordering of which
* determines column ordering elsewhere in this cursor
*/
- @WrapElementForJNI
+ @WrapForJNI
public MatrixBlobCursor(String[] columnNames) {
this(columnNames, 16);
}
@@ -132,7 +132,7 @@ public class MatrixBlobCursor extends AbstractCursor {
* @param columnValues in the same order as the the column names specified
* at cursor construction time
*/
- @WrapElementForJNI
+ @WrapForJNI
public void addRow(Object[] columnValues) {
if (columnValues.length != columnCount) {
throw new IllegalArgumentException("columnNames.length = "
@@ -154,7 +154,7 @@ public class MatrixBlobCursor extends AbstractCursor {
* @param columnValues in the same order as the the column names specified
* at cursor construction time
*/
- @WrapElementForJNI
+ @WrapForJNI
public void addRow(Iterable> columnValues) {
final int start = rowCount * columnCount;
@@ -188,7 +188,7 @@ public class MatrixBlobCursor extends AbstractCursor {
}
/** Optimization for {@link ArrayList}. */
- @WrapElementForJNI
+ @WrapForJNI
private void addRow(ArrayList> columnValues, int start) {
final int size = columnValues.size();
if (size != columnCount) {
diff --git a/mobile/android/base/sqlite/SQLiteBridgeException.java b/mobile/android/base/sqlite/SQLiteBridgeException.java
index 1e341e03bbb9..25598290878f 100644
--- a/mobile/android/base/sqlite/SQLiteBridgeException.java
+++ b/mobile/android/base/sqlite/SQLiteBridgeException.java
@@ -5,9 +5,9 @@
package org.mozilla.gecko.sqlite;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
+import org.mozilla.gecko.annotation.WrapForJNI;
-@WrapElementForJNI
+@WrapForJNI
public class SQLiteBridgeException extends RuntimeException {
static final long serialVersionUID = 1L;
diff --git a/mobile/android/base/util/Clipboard.java b/mobile/android/base/util/Clipboard.java
index f8fce482709a..4daeb8d80bc8 100644
--- a/mobile/android/base/util/Clipboard.java
+++ b/mobile/android/base/util/Clipboard.java
@@ -6,8 +6,8 @@ package org.mozilla.gecko.util;
import java.util.concurrent.SynchronousQueue;
+import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.AppConstants.Versions;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
import android.content.ClipData;
import android.content.Context;
@@ -32,7 +32,7 @@ public final class Clipboard {
mContext = c.getApplicationContext();
}
- @WrapElementForJNI(stubName = "GetClipboardTextWrapper")
+ @WrapForJNI(stubName = "GetClipboardTextWrapper")
public static String getText() {
// If we're on the UI thread or the background thread, we have a looper on the thread
// and can just call this directly. For any other threads, post the call to the
@@ -59,7 +59,7 @@ public final class Clipboard {
}
}
- @WrapElementForJNI(stubName = "SetClipboardText")
+ @WrapForJNI(stubName = "SetClipboardText")
public static void setText(final CharSequence text) {
ThreadUtils.postToBackgroundThread(new Runnable() {
@Override
@@ -90,7 +90,7 @@ public final class Clipboard {
/**
* @return true if the clipboard is nonempty, false otherwise.
*/
- @WrapElementForJNI
+ @WrapForJNI
public static boolean hasText() {
if (Versions.feature11Plus) {
android.content.ClipboardManager cm = (android.content.ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
@@ -105,7 +105,7 @@ public final class Clipboard {
/**
* Deletes all text from the clipboard.
*/
- @WrapElementForJNI
+ @WrapForJNI
public static void clearText() {
setText(null);
}
diff --git a/mobile/android/base/util/NativeJSContainer.java b/mobile/android/base/util/NativeJSContainer.java
index b0747c4ef4c1..0c939cadea30 100644
--- a/mobile/android/base/util/NativeJSContainer.java
+++ b/mobile/android/base/util/NativeJSContainer.java
@@ -5,7 +5,7 @@
package org.mozilla.gecko.util;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
+import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.mozglue.JNITarget;
/**
@@ -16,8 +16,7 @@ import org.mozilla.gecko.mozglue.JNITarget;
* thread, call {@link #clone()} to make a copy, and use the copy on the other thread.
* When a copy is first used, it becomes attached to the thread using it.
*/
-@JNITarget
-@WrapElementForJNI
+@WrapForJNI
public final class NativeJSContainer extends NativeJSObject
{
private NativeJSContainer() {
diff --git a/mobile/android/base/util/NativeJSObject.java b/mobile/android/base/util/NativeJSObject.java
index 426b301a8478..ad5b645d6480 100644
--- a/mobile/android/base/util/NativeJSObject.java
+++ b/mobile/android/base/util/NativeJSObject.java
@@ -5,7 +5,7 @@
package org.mozilla.gecko.util;
-import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
+import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.mozglue.JNIObject;
import org.mozilla.gecko.mozglue.JNITarget;
@@ -15,8 +15,7 @@ import android.os.Bundle;
* NativeJSObject is a wrapper around the SpiderMonkey JSAPI to make it possible to
* access Javascript objects in Java.
*/
-@JNITarget
-@WrapElementForJNI
+@WrapForJNI
public class NativeJSObject extends JNIObject
{
@SuppressWarnings("serial")
diff --git a/mobile/android/config/proguard/proguard.cfg b/mobile/android/config/proguard/proguard.cfg
index b4c02397afeb..466ea1a6a16f 100644
--- a/mobile/android/config/proguard/proguard.cfg
+++ b/mobile/android/config/proguard/proguard.cfg
@@ -179,20 +179,20 @@
}
# Keep generator-targeted entry points.
--keep @interface org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI
--keep @org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI class *
+-keep @interface org.mozilla.gecko.annotation.WrapForJNI
+-keep @org.mozilla.gecko.annotation.WrapForJNI class *
-keepclassmembers class * {
- @org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI *;
+ @org.mozilla.gecko.annotation.WrapForJNI *;
}
-keepclasseswithmembers class * {
- @org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI ;
+ @org.mozilla.gecko.annotation.WrapForJNI ;
}
-keepclasseswithmembers class * {
- @org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI ;
+ @org.mozilla.gecko.annotation.WrapForJNI ;
}
# Keep all members of an annotated class.
--keepclassmembers @org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI class * {
+-keepclassmembers @org.mozilla.gecko.annotation.WrapForJNI class * {
*;
}
diff --git a/netwerk/dns/mdns/libmdns/moz.build b/netwerk/dns/mdns/libmdns/moz.build
index 0096cc4aa180..b612bbead183 100644
--- a/netwerk/dns/mdns/libmdns/moz.build
+++ b/netwerk/dns/mdns/libmdns/moz.build
@@ -4,7 +4,7 @@
# 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/.
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android' and CONFIG['ANDROID_VERSION'] >= '21':
EXTRA_COMPONENTS += [
'nsDNSServiceDiscovery.js',
'nsDNSServiceDiscovery.manifest',
diff --git a/toolkit/components/telemetry/TelemetrySession.jsm b/toolkit/components/telemetry/TelemetrySession.jsm
index 261e3257a9a8..2b34db4db17d 100644
--- a/toolkit/components/telemetry/TelemetrySession.jsm
+++ b/toolkit/components/telemetry/TelemetrySession.jsm
@@ -85,8 +85,6 @@ const TELEMETRY_TEST_DELAY = 100;
const SCHEDULER_TICK_INTERVAL_MS = 5 * 60 * 1000;
// When user is idle, execute a scheduler tick every 60 minutes.
const SCHEDULER_TICK_IDLE_INTERVAL_MS = 60 * 60 * 1000;
-// The maximum number of times a scheduled operation can fail.
-const SCHEDULER_RETRY_ATTEMPTS = 3;
// The tolerance we have when checking if it's midnight (15 minutes).
const SCHEDULER_MIDNIGHT_TOLERANCE_MS = 15 * 60 * 1000;
@@ -381,9 +379,6 @@ let TelemetryScheduler = {
_log: null,
- // The number of times a daily ping fails.
- _dailyPingRetryAttempts: 0,
-
// The timer which drives the scheduler.
_schedulerTimer: null,
// The interval used by the scheduler timer.
@@ -546,8 +541,8 @@ let TelemetryScheduler = {
if (shouldSendDaily) {
this._log.trace("_schedulerTickLogic - Daily ping due.");
- return Impl._sendDailyPing().then(() => this._dailyPingSucceeded(now),
- () => this._dailyPingFailed(now));
+ this._lastDailyPingTime = now;
+ return Impl._sendDailyPing();
}
// Check if the aborted-session ping is due. If a daily ping was saved above, it was
@@ -561,10 +556,6 @@ let TelemetryScheduler = {
// No ping is due.
this._log.trace("_schedulerTickLogic - No ping due.");
- // It's possible, because of sleeps, that we're no longer within midnight tolerance for
- // daily pings. Because of that, daily retry attempts would not be 0 on the next midnight.
- // Reset that count on do-nothing ticks.
- this._dailyPingRetryAttempts = 0;
return Promise.resolve();
},
@@ -597,33 +588,6 @@ let TelemetryScheduler = {
this._rescheduleTimeout();
},
- /**
- * Called when a scheduled operation successfully completes (ping sent or saved).
- * @param {Number} now The current time, in milliseconds.
- */
- _dailyPingSucceeded: function(now) {
- this._log.trace("_dailyPingSucceeded");
- this._lastDailyPingTime = now;
- this._dailyPingRetryAttempts = 0;
- },
-
- /**
- * Called when a scheduled operation fails (ping sent or saved).
- * @param {Number} now The current time, in milliseconds.
- */
- _dailyPingFailed: function(now) {
- this._log.error("_dailyPingFailed");
- this._dailyPingRetryAttempts++;
-
- // If we reach the maximum number of retry attempts for a daily ping, log the error
- // and skip this daily ping.
- if (this._dailyPingRetryAttempts >= SCHEDULER_RETRY_ATTEMPTS) {
- this._log.error("_pingFailed - The daily ping failed too many times. Skipping it.");
- this._dailyPingRetryAttempts = 0;
- this._lastDailyPingTime = now;
- }
- },
-
/**
* Stops the scheduler.
*/
@@ -1894,8 +1858,8 @@ let Impl = {
// Also save the payload as an aborted session. If we delay this, aborted-session can
// lag behind for the profileSubsessionCounter and other state, complicating analysis.
if (IS_UNIFIED_TELEMETRY) {
- let abortedPromise = this._saveAbortedSessionPing(payload);
- promise = promise.then(() => abortedPromise);
+ this._saveAbortedSessionPing(payload)
+ .catch(e => this._log.error("_sendDailyPing - Failed to save the aborted session ping", e));
}
return promise;
diff --git a/toolkit/components/telemetry/tests/unit/test_TelemetrySession.js b/toolkit/components/telemetry/tests/unit/test_TelemetrySession.js
index 46dcf5eedf5c..570f17fb7d74 100644
--- a/toolkit/components/telemetry/tests/unit/test_TelemetrySession.js
+++ b/toolkit/components/telemetry/tests/unit/test_TelemetrySession.js
@@ -1682,6 +1682,106 @@ add_task(function* test_schedulerUserIdle() {
yield TelemetrySession.shutdown();
});
+add_task(function* test_DailyDueAndIdle() {
+ if (gIsAndroid || gIsGonk) {
+ // We don't have the aborted session or the daily ping here.
+ return;
+ }
+
+ yield TelemetrySession.reset();
+ clearPendingPings();
+ PingServer.clearRequests();
+
+ let receivedPingRequest = null;
+ // Register a ping handler that will assert when receiving multiple daily pings.
+ PingServer.registerPingHandler(req => {
+ Assert.ok(!receivedPingRequest, "Telemetry must only send one daily ping.");
+ receivedPingRequest = req;
+ });
+
+ let schedulerTickCallback = null;
+ let now = new Date(2030, 1, 1, 0, 0, 0);
+ fakeNow(now);
+ // Fake scheduler functions to control daily collection flow in tests.
+ fakeSchedulerTimer(callback => schedulerTickCallback = callback, () => {});
+ yield TelemetrySession.setup();
+
+ // Trigger the daily ping.
+ let firstDailyDue = new Date(2030, 1, 2, 0, 0, 0);
+ fakeNow(firstDailyDue);
+
+ // Run a scheduler tick: it should trigger the daily ping.
+ Assert.ok(!!schedulerTickCallback);
+ let tickPromise = schedulerTickCallback();
+
+ // Send an idle and then an active user notification.
+ fakeIdleNotification("idle");
+ fakeIdleNotification("active");
+
+ // Wait on the tick promise.
+ yield tickPromise;
+
+ yield TelemetrySend.testWaitOnOutgoingPings();
+
+ // Decode the ping contained in the request and check that's a daily ping.
+ Assert.ok(receivedPingRequest, "Telemetry must send one daily ping.");
+ const receivedPing = decodeRequestPayload(receivedPingRequest);
+ checkPingFormat(receivedPing, PING_TYPE_MAIN, true, true);
+ Assert.equal(receivedPing.payload.info.reason, REASON_DAILY);
+
+ yield TelemetrySession.shutdown();
+});
+
+add_task(function* test_userIdleAndSchedlerTick() {
+ if (gIsAndroid || gIsGonk) {
+ // We don't have the aborted session or the daily ping here.
+ return;
+ }
+
+ yield TelemetrySession.reset();
+ clearPendingPings();
+ PingServer.clearRequests();
+
+ let receivedPingRequest = null;
+ // Register a ping handler that will assert when receiving multiple daily pings.
+ PingServer.registerPingHandler(req => {
+ Assert.ok(!receivedPingRequest, "Telemetry must only send one daily ping.");
+ receivedPingRequest = req;
+ });
+
+ let schedulerTickCallback = null;
+ let now = new Date(2030, 1, 1, 0, 0, 0);
+ fakeNow(now);
+ // Fake scheduler functions to control daily collection flow in tests.
+ fakeSchedulerTimer(callback => schedulerTickCallback = callback, () => {});
+ yield TelemetrySession.setup();
+
+ // Move the current date/time to midnight.
+ let firstDailyDue = new Date(2030, 1, 2, 0, 0, 0);
+ fakeNow(firstDailyDue);
+
+ // The active notification should trigger a scheduler tick. The latter will send the
+ // due daily ping.
+ fakeIdleNotification("active");
+
+ // Immediately running another tick should not send a daily ping again.
+ Assert.ok(!!schedulerTickCallback);
+ yield schedulerTickCallback();
+
+ // A new "idle" notification should not send a new daily ping.
+ fakeIdleNotification("idle");
+
+ yield TelemetrySend.testWaitOnOutgoingPings();
+
+ // Decode the ping contained in the request and check that's a daily ping.
+ Assert.ok(receivedPingRequest, "Telemetry must send one daily ping.");
+ const receivedPing = decodeRequestPayload(receivedPingRequest);
+ checkPingFormat(receivedPing, PING_TYPE_MAIN, true, true);
+ Assert.equal(receivedPing.payload.info.reason, REASON_DAILY);
+
+ yield TelemetrySession.shutdown();
+});
+
add_task(function* stopServer(){
yield PingServer.stop();
do_test_finished();
diff --git a/toolkit/devtools/gcli/commands/rulers.js b/toolkit/devtools/gcli/commands/rulers.js
index a4ac49d9d1d7..2fd046175bcd 100644
--- a/toolkit/devtools/gcli/commands/rulers.js
+++ b/toolkit/devtools/gcli/commands/rulers.js
@@ -59,13 +59,13 @@ exports.items = [
hidden: true,
exec: function(args, context) {
let env = context.environment;
+ let { document } = env;
// Calling the command again after the rulers have been shown once hides
// them.
- if (highlighters.has(env.document)) {
- let { highlighter, environment } = highlighters.get(env.document);
+ if (highlighters.has(document)) {
+ let { highlighter } = highlighters.get(document);
highlighter.destroy();
- environment.destroy();
return false;
}
@@ -76,15 +76,15 @@ exports.items = [
// Store the instance of the rulers highlighter for this document so we
// can hide it later.
- highlighters.set(env.document, { highlighter, environment });
+ highlighters.set(document, { highlighter, environment });
// Listen to the highlighter's destroy event which may happen if the
// window is refreshed or closed with the rulers shown.
events.once(highlighter, "destroy", () => {
- if (highlighters.has(env.document)) {
- let { environment } = highlighters.get(env.document);
+ if (highlighters.has(document)) {
+ let { environment } = highlighters.get(document);
environment.destroy();
- highlighters.delete(env.document);
+ highlighters.delete(document);
}
});
diff --git a/toolkit/devtools/server/actors/gcli.js b/toolkit/devtools/server/actors/gcli.js
index f11fbec88857..33a73cf9806d 100644
--- a/toolkit/devtools/server/actors/gcli.js
+++ b/toolkit/devtools/server/actors/gcli.js
@@ -265,7 +265,7 @@ const GcliActor = ActorClass({
},
get document() {
- return tabActor.window.document;
+ return tabActor.window && tabActor.window.document;
}
};
diff --git a/toolkit/devtools/server/actors/highlighter.css b/toolkit/devtools/server/actors/highlighter.css
index 4beb0292ea00..be9f44c9df86 100644
--- a/toolkit/devtools/server/actors/highlighter.css
+++ b/toolkit/devtools/server/actors/highlighter.css
@@ -248,15 +248,6 @@
fill: #fff;
}
-/*
- Setting `stroke-width` with a low floating point number, ensure that `path`
- draws always 1px despites the zoom level, with `crispEdges` on the ancestor.
-*/
-:-moz-native-anonymous .rulers-highlighter-ruler-graduations,
-:-moz-native-anonymous .rulers-highlighter-ruler-markers {
- stroke-width: 0.0001;
-}
-
:-moz-native-anonymous .rulers-highlighter-ruler-graduations {
stroke: #bebebe;
}
@@ -282,4 +273,3 @@
transform: rotate(-90deg);
text-anchor: end;
}
-
diff --git a/toolkit/devtools/server/actors/highlighter.js b/toolkit/devtools/server/actors/highlighter.js
index fae41e599d3f..a0ef209415ed 100644
--- a/toolkit/devtools/server/actors/highlighter.js
+++ b/toolkit/devtools/server/actors/highlighter.js
@@ -2933,6 +2933,45 @@ RulersHighlighter.prototype = {
.setAttribute("transform", `translate(0, ${-scrollY})`);
},
+ _update: function() {
+ setIgnoreLayoutChanges(true);
+
+ let zoom = LayoutHelpers.getCurrentZoom(this.win);
+ let isZoomChanged = zoom !== this._zoom;
+
+ if (isZoomChanged) {
+ this._zoom = zoom;
+ this.updateViewport();
+ }
+
+ setIgnoreLayoutChanges(false, this.win.document.documentElement);
+
+ this._rafID = this.win.requestAnimationFrame(() => this._update());
+ },
+
+ _cancelUpdate: function() {
+ if (this._rafID) {
+ this.win.cancelAnimationFrame(this._rafID);
+ this._rafID = 0;
+ }
+ },
+ updateViewport: function() {
+ let { devicePixelRatio } = this.win;
+
+ // Because `devicePixelRatio` is affected by zoom (see bug 809788),
+ // in order to get the "real" device pixel ratio, we need divide by `zoom`
+ let pixelRatio = devicePixelRatio / this._zoom;
+
+ // The "real" device pixel ratio is used to calculate the max stroke
+ // width we can actually assign: on retina, for instance, it would be 0.5,
+ // where on non high dpi monitor would be 1.
+ let minWidth = 1 / pixelRatio;
+ let strokeWidth = Math.min(minWidth, minWidth / this._zoom);
+
+ this.markup.getElement(this.ID_CLASS_PREFIX + "root").setAttribute("style",
+ `stroke-width:${strokeWidth};`);
+ },
+
destroy: function() {
this.hide();
@@ -2947,12 +2986,17 @@ RulersHighlighter.prototype = {
show: function() {
this.markup.removeAttributeForElement(this.ID_CLASS_PREFIX + "elements",
"hidden");
+
+ this._update();
+
return true;
},
hide: function() {
this.markup.setAttributeForElement(this.ID_CLASS_PREFIX + "elements",
"hidden", "true");
+
+ this._cancelUpdate();
}
};
diff --git a/widget/android/GeneratedJNIWrappers.cpp b/widget/android/GeneratedJNIWrappers.cpp
index c29ce4d491df..7d5023439b77 100644
--- a/widget/android/GeneratedJNIWrappers.cpp
+++ b/widget/android/GeneratedJNIWrappers.cpp
@@ -1214,16 +1214,6 @@ void ViewTransform::Y(float a0) const
return mozilla::jni::Field::Set(this, nullptr, a0);
}
-constexpr char NativeZip::name[];
-
-constexpr char NativeZip::CreateInputStream_t::name[];
-constexpr char NativeZip::CreateInputStream_t::signature[];
-
-mozilla::jni::Object::LocalRef NativeZip::CreateInputStream(mozilla::jni::Object::Param a0, int32_t a1) const
-{
- return mozilla::jni::Method::Call(this, nullptr, a0, a1);
-}
-
constexpr char MatrixBlobCursor::name[];
constexpr char MatrixBlobCursor::New_t::name[];
diff --git a/widget/android/GeneratedJNIWrappers.h b/widget/android/GeneratedJNIWrappers.h
index d7be1ceef293..c743d4f7ab25 100644
--- a/widget/android/GeneratedJNIWrappers.h
+++ b/widget/android/GeneratedJNIWrappers.h
@@ -2826,41 +2826,6 @@ public:
};
-class NativeZip : public mozilla::jni::Class
-{
-public:
- typedef mozilla::jni::Ref Ref;
- typedef mozilla::jni::LocalRef LocalRef;
- typedef mozilla::jni::GlobalRef GlobalRef;
- typedef const mozilla::jni::Param& Param;
-
- static constexpr char name[] =
- "org/mozilla/gecko/mozglue/NativeZip";
-
-protected:
- NativeZip(jobject instance) : Class(instance) {}
-
-public:
- struct CreateInputStream_t {
- typedef NativeZip Owner;
- typedef mozilla::jni::Object::LocalRef ReturnType;
- typedef mozilla::jni::Object::Param SetterType;
- typedef mozilla::jni::Args<
- mozilla::jni::Object::Param,
- int32_t> Args;
- static constexpr char name[] = "createInputStream";
- static constexpr char signature[] =
- "(Ljava/nio/ByteBuffer;I)Ljava/io/InputStream;";
- static const bool isStatic = false;
- static const bool isMultithreaded = false;
- static const mozilla::jni::ExceptionMode exceptionMode =
- mozilla::jni::ExceptionMode::ABORT;
- };
-
- mozilla::jni::Object::LocalRef CreateInputStream(mozilla::jni::Object::Param, int32_t) const;
-
-};
-
class MatrixBlobCursor : public mozilla::jni::Class
{
public: