diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 85a947e8d3b..fb50bd7498f 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index e72b2c1bc6f..98e826f3134 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 f3100eea956..c6863bc3960 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 67940d3949b..32e8d3981ef 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/sources.xml b/b2g/config/emulator/sources.xml index e72b2c1bc6f..98e826f3134 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 6c1380b4cb1..76b53aa6efa 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 4734af2d2df..60e5ab9012a 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 271b736e1b8..758a1534c30 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "e7a7c126f48f4ea3bded1f2e9ee5e4f79ae1be9e", + "revision": "c1fd0c75afd4ccbc7f32465d50d3022eaa55e7b6", "repo_path": "/integration/gaia-central" } diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 42b12e9bb44..86adf88687b 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 66530c8e182..fc05afddfbf 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 8b0d19d9fb6..a5586e3ebcb 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 4d8749579ee..aac51f2a3c6 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/dev/app/moz.build b/b2g/dev/app/moz.build index bdb19346930..6fbe8159b2d 100644 --- a/b2g/dev/app/moz.build +++ b/b2g/dev/app/moz.build @@ -1,6 +1,3 @@ # 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/. - -DIST_SUBDIR = 'browser' -export('DIST_SUBDIR') diff --git a/browser/devtools/framework/sidebar.js b/browser/devtools/framework/sidebar.js index 3c17276eb05..073c3ae2af4 100644 --- a/browser/devtools/framework/sidebar.js +++ b/browser/devtools/framework/sidebar.js @@ -70,12 +70,16 @@ ToolSidebar.prototype = { let tab = this._tabbox.tabs.appendItem(); tab.setAttribute("label", ""); // Avoid showing "undefined" while the tab is loading + tab.setAttribute("id", "sidebar-tab-" + id); + + let onIFrameLoaded = (event) => { + let doc = event.target; + let win = doc.defaultView; + tab.setAttribute("label", doc.title); - let onIFrameLoaded = () => { - tab.setAttribute("label", iframe.contentDocument.title); iframe.removeEventListener("load", onIFrameLoaded, true); - if ("setPanel" in iframe.contentWindow) { - iframe.contentWindow.setPanel(this._toolPanel, iframe); + if ("setPanel" in win) { + win.setPanel(this._toolPanel, iframe); } this.emit(id + "-ready"); }; @@ -109,6 +113,27 @@ ToolSidebar.prototype = { this.emit("new-tab-registered", id); }, + /** + * Remove an existing tab. + */ + removeTab: function(id) { + let tab = this._tabbox.tabs.querySelector("tab#sidebar-tab-" + id); + if (!tab) { + return; + } + + tab.remove(); + + let panel = this.getTab(id); + if (panel) { + panel.remove(); + } + + this._tabs.delete(id); + + this.emit("tab-unregistered", id); + }, + /** * Select a specific tab. */ diff --git a/browser/devtools/framework/test/browser_toolbox_sidebar.js b/browser/devtools/framework/test/browser_toolbox_sidebar.js index f9ec0611179..752580da995 100644 --- a/browser/devtools/framework/test/browser_toolbox_sidebar.js +++ b/browser/devtools/framework/test/browser_toolbox_sidebar.js @@ -108,6 +108,7 @@ function test() { for (let tab of tabs) { is(tab.getAttribute("label"), label++, "Tab has the right title"); } + is(label, 4, "Found the right amount of tabs."); is(panel.sidebar._tabbox.selectedPanel, panels[0], "First tab is selected"); ok(panel.sidebar.getCurrentTabID(), "tab1", "getCurrentTabID() is correct"); @@ -119,13 +120,32 @@ function test() { panel.sidebar.hide(); is(panel.sidebar._tabbox.getAttribute("hidden"), "true", "Sidebar hidden"); is(panel.sidebar.getWindowForTab("tab1").location.href, tab1URL, "Window is accessible"); - testWidth(panel); + testRemoval(panel); }); }); panel.sidebar.select("tab2"); } + function testRemoval(panel) { + panel.sidebar.once("tab-unregistered", function(event, id) { + info(event); + registeredTabs[id] = false; + + is(id, "tab3", "The right tab must be removed"); + + let tabs = panel.sidebar._tabbox.querySelectorAll("tab"); + let panels = panel.sidebar._tabbox.querySelectorAll("tabpanel"); + + is(tabs.length, 2, "There is the right number of tabs"); + is(panels.length, 2, "There is the right number of panels"); + + testWidth(panel); + }); + + panel.sidebar.removeTab("tab3"); + } + function testWidth(panel) { let tabbox = panel.panelDoc.getElementById("sidebar"); tabbox.width = 420; diff --git a/browser/devtools/inspector/inspector-panel.js b/browser/devtools/inspector/inspector-panel.js index db742577381..b3e343ce01c 100644 --- a/browser/devtools/inspector/inspector-panel.js +++ b/browser/devtools/inspector/inspector-panel.js @@ -736,6 +736,19 @@ InspectorPanel.prototype = { } }, + /** + * Show DOM properties + */ + showDOMProperties: function InspectorPanel_showDOMProperties() { + this._toolbox.openSplitConsole().then(() => { + let panel = this._toolbox.getPanel("webconsole"); + let jsterm = panel.hud.jsterm; + + jsterm.execute("inspect($0)"); + jsterm.focusInput(); + }); + }, + /** * Clear any pseudo-class locks applied to the current hierarchy. */ diff --git a/browser/devtools/inspector/inspector.xul b/browser/devtools/inspector/inspector.xul index dfae344d029..f4be54f26ea 100644 --- a/browser/devtools/inspector/inspector.xul +++ b/browser/devtools/inspector/inspector.xul @@ -55,6 +55,9 @@ + { }); let test = asyncTest(function* () { - let { inspector } = yield openInspectorForURL(TEST_URL); + let { inspector, toolbox } = yield openInspectorForURL(TEST_URL); yield testMenuItemSensitivity(); yield testPasteOuterHTMLMenuItemSensitivity(); yield testCopyMenuItems(); + yield testShowDOMProperties(); yield testPasteOuterHTMLMenu(); yield testDeleteNode(); yield testDeleteRootNode(); @@ -154,6 +155,27 @@ let test = asyncTest(function* () { } } + function* testShowDOMProperties() { + info("Testing 'Show DOM Properties' menu item."); + let showDOMPropertiesNode = inspector.panelDoc.getElementById("node-menu-showdomproperties"); + ok(showDOMPropertiesNode, "the popup menu has a show dom properties item"); + + let consoleOpened = toolbox.once("webconsole-ready"); + + info("Triggering 'Show DOM Properties' and waiting for inspector open"); + dispatchCommandEvent(showDOMPropertiesNode); + yield consoleOpened; + + let webconsoleUI = toolbox.getPanel("webconsole").hud.ui; + let messagesAdded = webconsoleUI.once("messages-added"); + yield messagesAdded; + + info("Checking if 'inspect($0)' was evaluated"); + ok(webconsoleUI.jsterm.history[0] === 'inspect($0)'); + + yield toolbox.toggleSplitConsole(); + } + function* testPasteOuterHTMLMenu() { info("Testing that 'Paste Outer HTML' menu item works."); clipboard.set("this was pasted"); diff --git a/browser/devtools/markupview/markup-view.css b/browser/devtools/markupview/markup-view.css index a5d7dff360d..15a3d526c7a 100644 --- a/browser/devtools/markupview/markup-view.css +++ b/browser/devtools/markupview/markup-view.css @@ -36,6 +36,9 @@ .html-editor-inner { border: solid .1px; flex: 1 1 main-size; + + /* Keep the editor away from the markup view floating scrollbars */ + -moz-margin-end: 12px; } .html-editor iframe { diff --git a/browser/locales/en-US/chrome/browser/devtools/inspector.dtd b/browser/locales/en-US/chrome/browser/devtools/inspector.dtd index 27efa3718c8..b05ffa52b5d 100644 --- a/browser/locales/en-US/chrome/browser/devtools/inspector.dtd +++ b/browser/locales/en-US/chrome/browser/devtools/inspector.dtd @@ -22,3 +22,5 @@ + + diff --git a/build/autoconf/android.m4 b/build/autoconf/android.m4 index 26a36275584..8862a73b5c0 100644 --- a/build/autoconf/android.m4 +++ b/build/autoconf/android.m4 @@ -413,6 +413,16 @@ case "$target" in ;; esac +MOZ_ARG_ENABLE_BOOL(android-resource-constrained, +[ --enable-android-resource-constrained + exclude hi-res images and similar from the final APK], + MOZ_ANDROID_RESOURCE_CONSTRAINED=1) + +if test -n "$MOZ_ANDROID_RESOURCE_CONSTRAINED"; then + AC_DEFINE(MOZ_ANDROID_RESOURCE_CONSTRAINED, $MOZ_ANDROID_RESOURCE_CONSTRAINED) + AC_SUBST(MOZ_ANDROID_RESOURCE_CONSTRAINED) +fi + MOZ_ARG_WITH_STRING(android-min-sdk, [ --with-android-min-sdk=[VER] Impose a minimum Firefox for Android SDK version], [ MOZ_ANDROID_MIN_SDK_VERSION=$withval ]) @@ -433,10 +443,12 @@ if test -n "$MOZ_ANDROID_MIN_SDK_VERSION"; then fi AC_DEFINE_UNQUOTED(MOZ_ANDROID_MIN_SDK_VERSION, $MOZ_ANDROID_MIN_SDK_VERSION) + AC_SUBST(MOZ_ANDROID_MIN_SDK_VERSION) fi if test -n "$MOZ_ANDROID_MAX_SDK_VERSION"; then AC_DEFINE_UNQUOTED(MOZ_ANDROID_MAX_SDK_VERSION, $MOZ_ANDROID_MAX_SDK_VERSION) + AC_SUBST(MOZ_ANDROID_MAX_SDK_VERSION) fi ]) diff --git a/content/base/src/nsXMLHttpRequest.cpp b/content/base/src/nsXMLHttpRequest.cpp index 0791da2b707..2168f62af3f 100644 --- a/content/base/src/nsXMLHttpRequest.cpp +++ b/content/base/src/nsXMLHttpRequest.cpp @@ -4074,8 +4074,8 @@ ArrayBufferBuilder::mapToFileInPackage(const nsCString& aFile, return rv; } nsZipItem* zipItem = zip->GetItem(aFile.get()); - if (NS_FAILED(rv)) { - return rv; + if (!zipItem) { + return NS_ERROR_FILE_TARGET_DOES_NOT_EXIST; } // If file was added to the package as stored(uncompressed), map to the diff --git a/docshell/base/nsDefaultURIFixup.cpp b/docshell/base/nsDefaultURIFixup.cpp index 0061f3ea886..f233c03d621 100644 --- a/docshell/base/nsDefaultURIFixup.cpp +++ b/docshell/base/nsDefaultURIFixup.cpp @@ -386,14 +386,35 @@ nsDefaultURIFixup::GetFixupURIInfo(const nsACString& aStringURI, uint32_t aFixup info->mFixupCreatedAlternateURI = MakeAlternateURI(info->mFixedURI); } + // If there is no relevent dot in the host, do we require the domain to + // be whitelisted? + if (info->mFixedURI) { + if (aFixupFlags & FIXUP_FLAG_REQUIRE_WHITELISTED_HOST) { + + nsAutoCString asciiHost; + if (NS_SUCCEEDED(info->mFixedURI->GetAsciiHost(asciiHost)) && + !asciiHost.IsEmpty()) { + + uint32_t dotLoc = uint32_t(asciiHost.FindChar('.')); + + if ((dotLoc == uint32_t(kNotFound) || dotLoc == asciiHost.Length() - 1)) { + if (IsDomainWhitelisted(asciiHost, dotLoc)) { + info->mPreferredURI = info->mFixedURI; + } + } else { + info->mPreferredURI = info->mFixedURI; + } + } + } else { + info->mPreferredURI = info->mFixedURI; + } + + return NS_OK; + } + // If we still haven't been able to construct a valid URI, try to force a // keyword match. This catches search strings with '.' or ':' in them. - if (info->mFixedURI) - { - info->mPreferredURI = info->mFixedURI; - } - else if (sFixupKeywords && (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP)) - { + if (sFixupKeywords && (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP)) { rv = KeywordToURI(aStringURI, aPostData, getter_AddRefs(info->mPreferredURI)); if (NS_SUCCEEDED(rv) && info->mPreferredURI) { @@ -964,26 +985,17 @@ void nsDefaultURIFixup::KeywordURIFixup(const nsACString & aURIString, (dotLoc == lastDotLoc && (dotLoc == 0 || dotLoc == aURIString.Length() - 1))) && colonLoc == uint32_t(kNotFound) && qMarkLoc == uint32_t(kNotFound)) { + nsAutoCString asciiHost; if (aFixupInfo->mFixedURI && NS_SUCCEEDED(aFixupInfo->mFixedURI->GetAsciiHost(asciiHost)) && - !asciiHost.IsEmpty()) - { - // Check if this domain is whitelisted as an actual - // domain (which will prevent a keyword query) - // NB: any processing of the host here should stay in sync with - // code in the front-end(s) that set the pref. - nsAutoCString pref("browser.fixup.domainwhitelist."); - if (dotLoc == aURIString.Length() - 1) { - pref.Append(Substring(asciiHost, 0, asciiHost.Length() - 1)); - } else { - pref.Append(asciiHost); - } - if (Preferences::GetBool(pref.get(), false)) - { + !asciiHost.IsEmpty()) { + + if (IsDomainWhitelisted(asciiHost, dotLoc)) { return; } } + // If we get here, we don't have a valid URI, or we did but the // host is not whitelisted, so we do a keyword search *anyway*: rv = KeywordToURI(aFixupInfo->mOriginalInput, aPostData, @@ -995,6 +1007,25 @@ void nsDefaultURIFixup::KeywordURIFixup(const nsACString & aURIString, } } +bool nsDefaultURIFixup::IsDomainWhitelisted(const nsAutoCString aAsciiHost, + const uint32_t aDotLoc) +{ + // Check if this domain is whitelisted as an actual + // domain (which will prevent a keyword query) + // NB: any processing of the host here should stay in sync with + // code in the front-end(s) that set the pref. + + nsAutoCString pref("browser.fixup.domainwhitelist."); + + if (aDotLoc == aAsciiHost.Length() - 1) { + pref.Append(Substring(aAsciiHost, 0, aAsciiHost.Length() - 1)); + } else { + pref.Append(aAsciiHost); + } + + return Preferences::GetBool(pref.get(), false); +} + nsresult NS_NewURIFixup(nsIURIFixup **aURIFixup) { diff --git a/docshell/base/nsDefaultURIFixup.h b/docshell/base/nsDefaultURIFixup.h index ab92e242bcd..1088349ff59 100644 --- a/docshell/base/nsDefaultURIFixup.h +++ b/docshell/base/nsDefaultURIFixup.h @@ -37,6 +37,8 @@ private: bool PossiblyHostPortUrl(const nsACString& aUrl); bool MakeAlternateURI(nsIURI *aURI); bool IsLikelyFTP(const nsCString& aHostSpec); + bool IsDomainWhitelisted(const nsAutoCString aAsciiHost, + const uint32_t aDotLoc); }; class nsDefaultURIFixupInfo : public nsIURIFixupInfo diff --git a/docshell/base/nsIURIFixup.idl b/docshell/base/nsIURIFixup.idl index 71a24d37a12..7384f8c99d8 100644 --- a/docshell/base/nsIURIFixup.idl +++ b/docshell/base/nsIURIFixup.idl @@ -63,7 +63,7 @@ interface nsIURIFixupInfo : nsISupports /** * Interface implemented by objects capable of fixing up strings into URIs */ -[scriptable, uuid(80d4932e-bb2e-4afb-98e0-de9cc9ea7d82)] +[scriptable, uuid(49298f2b-3630-4874-aecc-522300a7fead)] interface nsIURIFixup : nsISupports { /** No fixup flags. */ @@ -83,12 +83,18 @@ interface nsIURIFixup : nsISupports const unsigned long FIXUP_FLAGS_MAKE_ALTERNATE_URI = 2; /** + * For an input that may be just a domain with only 1 level (eg, "mozilla"), + * require that the host be whitelisted. + * + * Overridden by FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP. + */ + const unsigned long FIXUP_FLAG_REQUIRE_WHITELISTED_HOST = 4; + + /* * Fix common scheme typos. */ const unsigned long FIXUP_FLAG_FIX_SCHEME_TYPOS = 8; - /* Note that flag 4 is available. */ - /** * Converts an internal URI (e.g. a wyciwyg URI) into one which we can * expose to the user, for example on the URL bar. diff --git a/docshell/test/unit/test_nsDefaultURIFixup_info.js b/docshell/test/unit/test_nsDefaultURIFixup_info.js index c63f5cb2207..fb1b7ddb67b 100644 --- a/docshell/test/unit/test_nsDefaultURIFixup_info.js +++ b/docshell/test/unit/test_nsDefaultURIFixup_info.js @@ -3,7 +3,8 @@ let urifixup = Cc["@mozilla.org/docshell/urifixup;1"]. Components.utils.import("resource://gre/modules/Services.jsm"); -let prefList = ["browser.fixup.typo.scheme", "keyword.enabled"]; +let prefList = ["browser.fixup.typo.scheme", "keyword.enabled", + "browser.fixup.domainwhitelist.whitelisted"]; for (let pref of prefList) { Services.prefs.setBoolPref(pref, true); } @@ -34,7 +35,8 @@ do_register_cleanup(function() { let flagInputs = [ urifixup.FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP, urifixup.FIXUP_FLAGS_MAKE_ALTERNATE_URI, - urifixup.FIXUP_FLAG_FIX_SCHEME_TYPOS + urifixup.FIXUP_FLAG_FIX_SCHEME_TYPOS, + urifixup.FIXUP_FLAG_REQUIRE_WHITELISTED_HOST, ]; flagInputs.concat([ @@ -44,42 +46,192 @@ flagInputs.concat([ flagInputs[0] | flagInputs[1] | flagInputs[2] ]); -let testcases = [ - ["http://www.mozilla.org", "http://www.mozilla.org/", null, false, false], - ["http://127.0.0.1/", "http://127.0.0.1/", null, false, false], - ["file:///foo/bar", "file:///foo/bar", null, false, false], - ["://www.mozilla.org", "http://www.mozilla.org/", null, false, true], - ["www.mozilla.org", "http://www.mozilla.org/", null, false, true], - ["http://mozilla/", "http://mozilla/", "http://www.mozilla.com/", false, false], - ["http://test./", "http://test./", "http://www.test./", false, false], - ["127.0.0.1", "http://127.0.0.1/", null, false, true], - ["1234", "http://1234/", "http://www.1234.com/", true, true], - ["host/foo.txt", "http://host/foo.txt", "http://www.host.com/foo.txt", false, true], - ["mozilla", "http://mozilla/", "http://www.mozilla.com/", true, true], - ["test.", "http://test./", "http://www.test./", true, true], - [".test", "http://.test/", "http://www..test/", true, true], - ["mozilla is amazing", null, null, true, true], - ["mozilla ", "http://mozilla/", "http://www.mozilla.com/", true, true], - [" mozilla ", "http://mozilla/", "http://www.mozilla.com/", true, true], - ["mozilla \\", null, null, true, true], - ["mozilla \\ foo.txt", null, null, true, true], - ["mozilla \\\r foo.txt", null, null, true, true], - ["mozilla\n", "http://mozilla/", "http://www.mozilla.com/", true, true], - ["mozilla \r\n", "http://mozilla/", "http://www.mozilla.com/", true, true], - ["moz\r\nfirefox\nos\r", "http://mozfirefoxos/", "http://www.mozfirefoxos.com/", true, true], - ["moz\r\n firefox\n", null, null, true, true], - ["", null, null, true, true], - ["[]", null, null, true, true] -]; +/* + The following properties are supported for these test cases: + { + input: "", // Input string, required + fixedURI: "", // Expected fixedURI + alternateURI: "", // Expected alternateURI + keywordLookup: false, // Whether a keyword lookup is expected + protocolChange: false, // Whether a protocol change is expected + affectedByWhitelist: false, // Whether the input host is affected by the whitelist + inWhitelist: false, // Whether the input host is in the whitelist + } +*/ +let testcases = [ { + input: "http://www.mozilla.org", + fixedURI: "http://www.mozilla.org/", + }, { + input: "http://127.0.0.1/", + fixedURI: "http://127.0.0.1/", + }, { + input: "file:///foo/bar", + fixedURI: "file:///foo/bar", + }, { + input: "://www.mozilla.org", + fixedURI: "http://www.mozilla.org/", + protocolChange: true, + }, { + input: "www.mozilla.org", + fixedURI: "http://www.mozilla.org/", + protocolChange: true, + }, { + input: "http://mozilla/", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + }, { + input: "http://test./", + fixedURI: "http://test./", + alternateURI: "http://www.test./", + }, { + input: "127.0.0.1", + fixedURI: "http://127.0.0.1/", + protocolChange: true, + }, { + input: "1234", + fixedURI: "http://1234/", + alternateURI: "http://www.1234.com/", + keywordLookup: true, + protocolChange: true, + affectedByWhitelist: true, + }, { + input: "host/foo.txt", + fixedURI: "http://host/foo.txt", + alternateURI: "http://www.host.com/foo.txt", + protocolChange: true, + affectedByWhitelist: true, + }, { + input: "mozilla", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + keywordLookup: true, + protocolChange: true, + affectedByWhitelist: true, + }, { + input: "test.", + fixedURI: "http://test./", + alternateURI: "http://www.test./", + keywordLookup: true, + protocolChange: true, + affectedByWhitelist: true, + }, { + input: ".test", + fixedURI: "http://.test/", + alternateURI: "http://www..test/", + keywordLookup: true, + protocolChange: true, + }, { + input: "mozilla is amazing", + keywordLookup: true, + protocolChange: true, + }, { + input: "mozilla ", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + keywordLookup: true, + protocolChange: true, + affectedByWhitelist: true, + }, { + input: " mozilla ", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + keywordLookup: true, + protocolChange: true, + affectedByWhitelist: true, + }, { + input: "mozilla \\", + keywordLookup: true, + protocolChange: true, + affectedByWhitelist: true, + }, { + input: "mozilla \\ foo.txt", + keywordLookup: true, + protocolChange: true, + }, { + input: "mozilla \\\r foo.txt", + keywordLookup: true, + protocolChange: true, + }, { + input: "mozilla\n", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + keywordLookup: true, + protocolChange: true, + affectedByWhitelist: true, + }, { + input: "mozilla \r\n", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + keywordLookup: true, + protocolChange: true, + affectedByWhitelist: true, + }, { + input: "moz\r\nfirefox\nos\r", + fixedURI: "http://mozfirefoxos/", + alternateURI: "http://www.mozfirefoxos.com/", + keywordLookup: true, + protocolChange: true, + affectedByWhitelist: true, + }, { + input: "moz\r\n firefox\n", + keywordLookup: true, + protocolChange: true, + }, { + input: "", + keywordLookup: true, + protocolChange: true, + }, { + input: "[]", + keywordLookup: true, + protocolChange: true, + }, { + input: "http://whitelisted/", + fixedURI: "http://whitelisted/", + alternateURI: "http://www.whitelisted.com/", + affectedByWhitelist: true, + inWhitelist: true, + }]; if (Services.appinfo.OS.toLowerCase().startsWith("win")) { - testcases.push(["C:\\some\\file.txt", "file:///C:/some/file.txt", null, false, true]); - testcases.push(["//mozilla", "http://mozilla/", "http://www.mozilla.com/", false, true]); - testcases.push(["mozilla\\", "http://mozilla/", "http://www.mozilla.com/", true, true]); + testcases.push({ + input: "C:\\some\\file.txt", + fixedURI: "file:///C:/some/file.txt", + protocolChange: true, + }); + testcases.push({ + input: "//mozilla", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + protocolChange: true, + affectedByWhitelist: true, + }); + testcases.push({ + input: "mozilla\\", + fixedURI: "http://mozilla/", + alternateURI: "http://www.mozilla.com/", + keywordLookup: true, + protocolChange: true, + affectedByWhitelist: true, + }); } else { - testcases.push(["/some/file.txt", "file:///some/file.txt", null, false, true]); - testcases.push(["//mozilla", "file:////mozilla", null, false, true]); - testcases.push(["mozilla\\", "http://mozilla\\/", "http://www.mozilla/", true, true]); + testcases.push({ + input: "/some/file.txt", + fixedURI: "file:///some/file.txt", + protocolChange: true, + }); + testcases.push({ + input: "//mozilla", + fixedURI: "file:////mozilla", + protocolChange: true, + }); + testcases.push({ + input: "mozilla\\", + fixedURI: "http://mozilla\\/", + alternateURI: "http://www.mozilla/", + keywordLookup: true, + protocolChange: true, + affectedByWhitelist: true, + }); } function sanitize(input) { @@ -87,8 +239,20 @@ function sanitize(input) { } function run_test() { - for (let [testInput, expectedFixedURI, alternativeURI, - expectKeywordLookup, expectProtocolChange] of testcases) { + for (let { input: testInput, + fixedURI: expectedFixedURI, + alternateURI: alternativeURI, + keywordLookup: expectKeywordLookup, + protocolChange: expectProtocolChange, + affectedByWhitelist: affectedByWhitelist, + inWhitelist: inWhitelist } of testcases) { + + // Explicitly force these into a boolean + expectKeywordLookup = !!expectKeywordLookup; + expectProtocolChange = !!expectProtocolChange; + affectedByWhitelist = !!affectedByWhitelist; + inWhitelist = !!inWhitelist; + for (let flags of flagInputs) { let info; let fixupURIOnly = null; @@ -109,10 +273,12 @@ function run_test() { continue; } - do_print("Checking " + testInput + " with flags " + flags); + do_print("Checking \"" + testInput + "\" with flags " + flags); // Both APIs should then also be using the same spec. - do_check_eq(fixupURIOnly.spec, info.preferredURI.spec); + do_check_eq(!!fixupURIOnly, !!info.preferredURI); + if (fixupURIOnly) + do_check_eq(fixupURIOnly.spec, info.preferredURI.spec); let isFileURL = expectedFixedURI && expectedFixedURI.startsWith("file"); @@ -131,10 +297,25 @@ function run_test() { do_check_eq(info.fixupCreatedAlternateURI, makeAlternativeURI && alternativeURI != null); // Check the preferred URI - if (couldDoKeywordLookup && expectKeywordLookup) { + let requiresWhitelistedDomain = flags & urifixup.FIXUP_FLAG_REQUIRE_WHITELISTED_HOST + if (couldDoKeywordLookup) { + if (expectKeywordLookup) { + if (!affectedByWhitelist || (affectedByWhitelist && !inWhitelist)) { let urlparamInput = encodeURIComponent(sanitize(testInput)).replace("%20", "+", "g"); let searchURL = kSearchEngineURL.replace("{searchTerms}", urlparamInput); do_check_eq(info.preferredURI.spec, searchURL); + } else { + do_check_eq(info.preferredURI, null); + } + } else { + do_check_eq(info.preferredURI.spec, info.fixedURI.spec); + } + } else if (requiresWhitelistedDomain) { + // Not a keyword search, but we want to enforce the host whitelist + if (!affectedByWhitelist || (affectedByWhitelist && inWhitelist)) + do_check_eq(info.preferredURI.spec, info.fixedURI.spec); + else + do_check_eq(info.preferredURI, null); } else { // In these cases, we should never be doing a keyword lookup and // the fixed URI should be preferred: diff --git a/dom/apps/Webapps.jsm b/dom/apps/Webapps.jsm index 7d14d02982f..e7b6f1bbbb8 100755 --- a/dom/apps/Webapps.jsm +++ b/dom/apps/Webapps.jsm @@ -633,10 +633,23 @@ this.DOMApplicationRegistry = { yield this.loadCurrentRegistry(); + try { + let systemManifestURL = + Services.prefs.getCharPref("b2g.system_manifest_url"); + let systemAppFound = + this.webapps.some(v => v.manifestURL == systemManifestURL); + + // We configured a system app but can't find it. That prevents us + // from starting so we clear our registry to start again from scratch. + if (!systemAppFound) { + runUpdate = true; + } + } catch(e) {} // getCharPref will throw on non-b2g platforms. That's ok. + if (runUpdate) { // Run migration before uninstall of core apps happens. - Services.obs.notifyObservers(null, "webapps-before-update-merge", null); + Services.obs.notifyObservers(null, "webapps-before-update-merge", null); #ifdef MOZ_WIDGET_GONK yield this.installSystemApps(); diff --git a/dom/devicestorage/nsDeviceStorage.cpp b/dom/devicestorage/nsDeviceStorage.cpp index b2926ccbf1e..a3d7fe1bfd6 100644 --- a/dom/devicestorage/nsDeviceStorage.cpp +++ b/dom/devicestorage/nsDeviceStorage.cpp @@ -871,13 +871,17 @@ DeviceStorageFile::GetRootDirectoryForType(const nsAString& aStorageType, InitDirs(); #ifdef MOZ_WIDGET_GONK + nsresult rv; nsString volMountPoint; if (DeviceStorageTypeChecker::IsVolumeBased(aStorageType)) { nsCOMPtr vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID); NS_ENSURE_TRUE_VOID(vs); - nsresult rv; nsCOMPtr vol; rv = vs->GetVolumeByName(aStorageName, getter_AddRefs(vol)); + if(NS_FAILED(rv)) { + printf_stderr("##### DeviceStorage: GetVolumeByName('%s') failed\n", + NS_LossyConvertUTF16toASCII(aStorageName).get()); + } NS_ENSURE_SUCCESS_VOID(rv); vol->GetMountPoint(volMountPoint); } @@ -886,7 +890,12 @@ DeviceStorageFile::GetRootDirectoryForType(const nsAString& aStorageType, // Picture directory if (aStorageType.EqualsLiteral(DEVICESTORAGE_PICTURES)) { #ifdef MOZ_WIDGET_GONK - NS_NewLocalFile(volMountPoint, false, getter_AddRefs(f)); + rv = NS_NewLocalFile(volMountPoint, false, getter_AddRefs(f)); + if(NS_FAILED(rv)) { + printf_stderr("##### DeviceStorage: NS_NewLocalFile failed StorageType: '%s' path '%s'\n", + NS_LossyConvertUTF16toASCII(volMountPoint).get(), + NS_LossyConvertUTF16toASCII(aStorageType).get()); + } #else f = sDirs->pictures; #endif @@ -895,7 +904,12 @@ DeviceStorageFile::GetRootDirectoryForType(const nsAString& aStorageType, // Video directory else if (aStorageType.EqualsLiteral(DEVICESTORAGE_VIDEOS)) { #ifdef MOZ_WIDGET_GONK - NS_NewLocalFile(volMountPoint, false, getter_AddRefs(f)); + rv = NS_NewLocalFile(volMountPoint, false, getter_AddRefs(f)); + if(NS_FAILED(rv)) { + printf_stderr("##### DeviceStorage: NS_NewLocalFile failed StorageType: '%s' path '%s'\n", + NS_LossyConvertUTF16toASCII(volMountPoint).get(), + NS_LossyConvertUTF16toASCII(aStorageType).get()); + } #else f = sDirs->videos; #endif @@ -904,7 +918,12 @@ DeviceStorageFile::GetRootDirectoryForType(const nsAString& aStorageType, // Music directory else if (aStorageType.EqualsLiteral(DEVICESTORAGE_MUSIC)) { #ifdef MOZ_WIDGET_GONK - NS_NewLocalFile(volMountPoint, false, getter_AddRefs(f)); + rv = NS_NewLocalFile(volMountPoint, false, getter_AddRefs(f)); + if(NS_FAILED(rv)) { + printf_stderr("##### DeviceStorage: NS_NewLocalFile failed StorageType: '%s' path '%s'\n", + NS_LossyConvertUTF16toASCII(volMountPoint).get(), + NS_LossyConvertUTF16toASCII(aStorageType).get()); + } #else f = sDirs->music; #endif @@ -919,7 +938,12 @@ DeviceStorageFile::GetRootDirectoryForType(const nsAString& aStorageType, // default SDCard else if (aStorageType.EqualsLiteral(DEVICESTORAGE_SDCARD)) { #ifdef MOZ_WIDGET_GONK - NS_NewLocalFile(volMountPoint, false, getter_AddRefs(f)); + rv = NS_NewLocalFile(volMountPoint, false, getter_AddRefs(f)); + if(NS_FAILED(rv)) { + printf_stderr("##### DeviceStorage: NS_NewLocalFile failed StorageType: '%s' path '%s'\n", + NS_LossyConvertUTF16toASCII(volMountPoint).get(), + NS_LossyConvertUTF16toASCII(aStorageType).get()); + } #else f = sDirs->sdcard; #endif @@ -945,6 +969,12 @@ DeviceStorageFile::GetRootDirectoryForType(const nsAString& aStorageType, if (f) { f->Clone(aFile); + } else { + // This should never happen unless something is severely wrong. So + // scream a little. + printf_stderr("##### GetRootDirectoryForType('%s', '%s') failed #####", + NS_LossyConvertUTF16toASCII(aStorageType).get(), + NS_LossyConvertUTF16toASCII(aStorageName).get()); } } diff --git a/dom/settings/SettingsManager.js b/dom/settings/SettingsManager.js index 07bbdab4a82..b8fb3c08d59 100644 --- a/dom/settings/SettingsManager.js +++ b/dom/settings/SettingsManager.js @@ -55,7 +55,7 @@ function SettingsLock(aSettingsManager) { "Settings:Clear:OK", "Settings:Clear:KO", "Settings:Set:OK", "Settings:Set:KO", "Settings:Finalize:OK", "Settings:Finalize:KO"]); - this.sendMessage("Settings:CreateLock", {lockID: this._id, isInternalLock: false}); + this.sendMessage("Settings:CreateLock", {lockID: this._id, isServiceLock: false}); Services.tm.currentThread.dispatch(this._closeHelper.bind(this), Ci.nsIThread.DISPATCH_NORMAL); } diff --git a/dom/settings/SettingsRequestManager.jsm b/dom/settings/SettingsRequestManager.jsm index eb5e778c2f9..415e50aee3a 100644 --- a/dom/settings/SettingsRequestManager.jsm +++ b/dom/settings/SettingsRequestManager.jsm @@ -601,7 +601,7 @@ let SettingsRequestManager = { p.reject("Invalid operation: " + currentTask.operation); } p.then(function(ret) { - ret.task.defer.resolve(ret.results); + ret.task.defer.resolve("results" in ret ? ret.results : null); }.bind(currentTask), function(ret) { ret.task.defer.reject(ret.error); }); diff --git a/dom/system/gonk/AutoMounter.cpp b/dom/system/gonk/AutoMounter.cpp index ed3eee0fc86..0ab4fe43a4d 100644 --- a/dom/system/gonk/AutoMounter.cpp +++ b/dom/system/gonk/AutoMounter.cpp @@ -96,9 +96,10 @@ namespace system { #define SYS_USB_CONFIG "sys.usb.config" #define PERSIST_SYS_USB_CONFIG "persist.sys.usb.config" -#define USB_FUNC_ADB "adb" -#define USB_FUNC_MTP "mtp" -#define USB_FUNC_UMS "mass_storage" +#define USB_FUNC_ADB "adb" +#define USB_FUNC_MTP "mtp" +#define USB_FUNC_RNDIS "rndis" +#define USB_FUNC_UMS "mass_storage" class AutoMounter; @@ -420,17 +421,21 @@ private: // mass_storage has been configured and we can start sharing once the user // enables it. STATE_UMS_CONFIGURED, + + // USB Tethering is enabled + STATE_RNDIS_CONFIGURED, }; const char *StateStr(STATE aState) { switch (aState) { - case STATE_IDLE: return "IDLE"; - case STATE_MTP_CONFIGURING: return "MTP_CONFIGURING"; - case STATE_MTP_CONNECTED: return "MTP_CONNECTED"; - case STATE_MTP_STARTED: return "MTP_STARTED"; - case STATE_UMS_CONFIGURING: return "UMS_CONFIGURING"; - case STATE_UMS_CONFIGURED: return "UMS_CONFIGURED"; + case STATE_IDLE: return "IDLE"; + case STATE_MTP_CONFIGURING: return "MTP_CONFIGURING"; + case STATE_MTP_CONNECTED: return "MTP_CONNECTED"; + case STATE_MTP_STARTED: return "MTP_STARTED"; + case STATE_UMS_CONFIGURING: return "UMS_CONFIGURING"; + case STATE_UMS_CONFIGURED: return "UMS_CONFIGURED"; + case STATE_RNDIS_CONFIGURED: return "RNDIS_CONFIGURED"; } return "STATE_???"; } @@ -660,6 +665,7 @@ AutoMounter::UpdateState() bool mtpAvail = false; bool mtpConfigured = false; bool mtpEnabled = false; + bool rndisConfigured = false; bool usbCablePluggedIn = IsUsbCablePluggedIn(); if (access(ICS_SYS_USB_FUNCTIONS, F_OK) == 0) { @@ -690,6 +696,8 @@ AutoMounter::UpdateState() mtpConfigured = false; mtpEnabled = false; } + + rndisConfigured = strstr(functionsStr, USB_FUNC_RNDIS) != nullptr; } bool enabled = mtpEnabled || umsEnabled; @@ -704,9 +712,9 @@ AutoMounter::UpdateState() } } - DBG("UpdateState: ums:A%dC%dE%d mtp:A%dC%dE%d mode:%d usb:%d mState:%s", + DBG("UpdateState: ums:A%dC%dE%d mtp:A%dC%dE%d rndis:%d mode:%d usb:%d mState:%s", umsAvail, umsConfigured, umsEnabled, - mtpAvail, mtpConfigured, mtpEnabled, + mtpAvail, mtpConfigured, mtpEnabled, rndisConfigured, mMode, usbCablePluggedIn, StateStr(mState)); switch (mState) { @@ -717,6 +725,11 @@ AutoMounter::UpdateState() // UEvent when the usb cable is plugged in. break; } + if (rndisConfigured) { + // USB Tethering uses RNDIS. We'll just wait until its turned off. + SetState(STATE_RNDIS_CONFIGURED); + break; + } if (mtpEnabled) { if (mtpConfigured) { // The USB layer has already been configured. Now we can go ahead @@ -726,7 +739,7 @@ AutoMounter::UpdateState() StartMtpServer(); SetState(STATE_MTP_STARTED); } else { - // The MTP USB layer is configuring. Wait for it to finish + // We need to configure USB to use mtp. Wait for it to be configured // before we start the MTP server. SetUsbFunction(USB_FUNC_MTP); SetState(STATE_MTP_CONFIGURING); @@ -752,6 +765,11 @@ AutoMounter::UpdateState() // the MTP server. StartMtpServer(); SetState(STATE_MTP_STARTED); + break; + } + if (rndisConfigured) { + SetState(STATE_RNDIS_CONFIGURED); + break; } break; @@ -764,6 +782,10 @@ AutoMounter::UpdateState() "mtpConfigured = %d mtpEnabled = %d usbCablePluggedIn: %d", mtpConfigured, mtpEnabled, usbCablePluggedIn); StopMtpServer(); + if (rndisConfigured) { + SetState(STATE_RNDIS_CONFIGURED); + break; + } if (umsAvail) { // Switch back to UMS SetUsbFunction(USB_FUNC_UMS); @@ -790,6 +812,10 @@ AutoMounter::UpdateState() } SetState(STATE_UMS_CONFIGURED); } + if (rndisConfigured) { + SetState(STATE_RNDIS_CONFIGURED); + break; + } break; case STATE_UMS_CONFIGURED: @@ -805,6 +831,18 @@ AutoMounter::UpdateState() break; } } + if (rndisConfigured) { + SetState(STATE_RNDIS_CONFIGURED); + break; + } + SetState(STATE_IDLE); + break; + + case STATE_RNDIS_CONFIGURED: + if (usbCablePluggedIn && rndisConfigured) { + // Normal state when RNDIS is enabled. + break; + } SetState(STATE_IDLE); break; diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index 6316c18c9d6..a67a2054564 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -548,7 +548,7 @@ void nsCaret::ResetBlinking() { mIsBlinkOn = true; - if (mReadOnly) { + if (mReadOnly || !mVisible) { StopBlinking(); return; } diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index 7894bd870a5..74b7b7d4a9a 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -281,11 +281,7 @@ pref("browser.search.official", true); #endif // Control media casting feature -#ifdef RELEASE_BUILD -pref("browser.casting.enabled", false); -#else pref("browser.casting.enabled", true); -#endif // Enable sparse localization by setting a few package locale overrides pref("chrome.override_package.global", "browser"); diff --git a/mobile/android/base/AppConstants.java.in b/mobile/android/base/AppConstants.java.in index 8ab98aadc20..ffea6474f67 100644 --- a/mobile/android/base/AppConstants.java.in +++ b/mobile/android/base/AppConstants.java.in @@ -137,6 +137,17 @@ public class AppConstants { null; #endif + /** + * Whether this APK was built with constrained resources -- + * no xhdpi+ images, for example. + */ + public static final boolean MOZ_ANDROID_RESOURCE_CONSTRAINED = +#ifdef MOZ_ANDROID_RESOURCE_CONSTRAINED + true; +#else + false; +#endif + public static final boolean MOZ_SERVICES_HEALTHREPORT = #ifdef MOZ_SERVICES_HEALTHREPORT true; diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index b9ffeabd4b6..d9807b389ff 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -353,12 +353,14 @@ extra_packages := $(subst $(NULL) ,:,$(strip $(extra_packages))) # are fresher than the target, preventing a subsequent invocation from # thinking aapt's outputs are stale. This is safe because Make # removes the target file if any recipe command fails. + define aapt_command $(1): $$(call mkdir_deps,$(filter-out ./,$(dir $(3) $(4) $(5)))) $(2) @$$(TOUCH) $$@ $$(AAPT) package -f -m \ -M AndroidManifest.xml \ -I $(ANDROID_SDK)/android.jar \ + $(if $(MOZ_ANDROID_MAX_SDK_VERSION),--max-res-version $(MOZ_ANDROID_MAX_SDK_VERSION),) \ --auto-add-overlay \ $$(addprefix -S ,$$(ANDROID_RES_DIRS)) \ $(if $(extra_res_dirs),$$(addprefix -S ,$$(extra_res_dirs)),) \ @@ -368,6 +370,7 @@ $(1): $$(call mkdir_deps,$(filter-out ./,$(dir $(3) $(4) $(5)))) $(2) -F $(3) \ -J $(4) \ --output-text-symbols $(5) \ + $(if $(MOZ_ANDROID_RESOURCE_CONSTRAINED),-c hdpi,) \ --ignore-assets "$$(ANDROID_AAPT_IGNORE)" endef diff --git a/mobile/android/base/animation/PropertyAnimator.java b/mobile/android/base/animation/PropertyAnimator.java index 03d3b65bbb2..e35b6aacb26 100644 --- a/mobile/android/base/animation/PropertyAnimator.java +++ b/mobile/android/base/animation/PropertyAnimator.java @@ -159,22 +159,24 @@ public class PropertyAnimator implements Runnable { treeObserver = null; } + final ViewTreeObserver.OnPreDrawListener preDrawListener = new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + if (treeObserver.isAlive()) { + treeObserver.removeOnPreDrawListener(this); + } + + mFramePoster.postFirstAnimationFrame(); + return true; + } + }; + // Try to start animation after any on-going layout round // in the current view tree. OnPreDrawListener seems broken // on pre-Honeycomb devices, start animation immediatelly // in this case. if (Versions.feature11Plus && treeObserver != null && treeObserver.isAlive()) { - treeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - if (treeObserver.isAlive()) { - treeObserver.removeOnPreDrawListener(this); - } - - mFramePoster.postFirstAnimationFrame(); - return true; - } - }); + treeObserver.addOnPreDrawListener(preDrawListener); } else { mFramePoster.postFirstAnimationFrame(); } diff --git a/mobile/android/base/preferences/SyncPreference.java b/mobile/android/base/preferences/SyncPreference.java index d26ff9eb761..2adfb369c8f 100644 --- a/mobile/android/base/preferences/SyncPreference.java +++ b/mobile/android/base/preferences/SyncPreference.java @@ -5,6 +5,9 @@ package org.mozilla.gecko.preferences; +import org.mozilla.gecko.Telemetry; +import org.mozilla.gecko.TelemetryContract; +import org.mozilla.gecko.TelemetryContract.Method; import org.mozilla.gecko.fxa.activities.FxAccountGetStartedActivity; import org.mozilla.gecko.sync.setup.SyncAccounts; import org.mozilla.gecko.sync.setup.activities.SetupSyncActivity; @@ -60,6 +63,7 @@ class SyncPreference extends Preference { // open the settings page. if (SyncAccounts.syncAccountsExist(mContext)) { if (SyncAccounts.openSyncSettings(mContext) != null) { + Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, Method.SETTINGS, "sync_settings"); return; } } @@ -67,5 +71,6 @@ class SyncPreference extends Preference { // Otherwise, launch the FxA "Get started" activity, which will // dispatch to the right location. launchFxASetup(); + Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, Method.SETTINGS, "sync_setup"); } } diff --git a/mobile/android/base/resources/xml/preferences_devtools.xml b/mobile/android/base/resources/xml/preferences_devtools.xml index d9308d997b4..c4db6dae8e3 100644 --- a/mobile/android/base/resources/xml/preferences_devtools.xml +++ b/mobile/android/base/resources/xml/preferences_devtools.xml @@ -15,7 +15,9 @@ - diff --git a/mobile/android/base/resources/xml/preferences_vendor.xml b/mobile/android/base/resources/xml/preferences_vendor.xml index 6a73fdc1f8f..c200de3e3f3 100644 --- a/mobile/android/base/resources/xml/preferences_vendor.xml +++ b/mobile/android/base/resources/xml/preferences_vendor.xml @@ -8,13 +8,19 @@ android:title="@string/pref_category_vendor" android:enabled="false"> - - - diff --git a/mobile/android/chrome/content/SelectionHandler.js b/mobile/android/chrome/content/SelectionHandler.js index 4361d84124c..3b380fd41b2 100644 --- a/mobile/android/chrome/content/SelectionHandler.js +++ b/mobile/android/chrome/content/SelectionHandler.js @@ -797,8 +797,8 @@ var SelectionHandler = { }, isElementEditableText: function (aElement) { - return ((aElement instanceof HTMLInputElement && aElement.mozIsTextField(false)) || - (aElement instanceof HTMLTextAreaElement)); + return (((aElement instanceof HTMLInputElement && aElement.mozIsTextField(false)) || + (aElement instanceof HTMLTextAreaElement)) && !aElement.readOnly); }, /* diff --git a/mobile/android/search/java/org/mozilla/search/providers/SearchEngineManager.java b/mobile/android/search/java/org/mozilla/search/providers/SearchEngineManager.java index 900bdc9a957..145f4c993fc 100644 --- a/mobile/android/search/java/org/mozilla/search/providers/SearchEngineManager.java +++ b/mobile/android/search/java/org/mozilla/search/providers/SearchEngineManager.java @@ -11,6 +11,7 @@ import android.text.TextUtils; import android.util.Log; import org.mozilla.gecko.AppConstants; +import org.mozilla.gecko.BrowserLocaleManager; import org.mozilla.gecko.GeckoSharedPrefs; import org.mozilla.gecko.util.GeckoJarReader; import org.mozilla.search.R; @@ -23,6 +24,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; +import java.util.Locale; public class SearchEngineManager implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String LOG_TAG = "SearchEngineManager"; @@ -118,8 +120,7 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference */ public List getAllEngines() { // First try to read the engine list from the jar. - final String url = getSearchPluginsJarUrl("list.txt"); - InputStream in = GeckoJarReader.getStream(url); + InputStream in = getInputStreamFromJar("list.txt"); // Fallback for standalone search activity. if (in == null) { @@ -167,7 +168,7 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference * @return SearchEngine instance for identifier */ private SearchEngine createEngine(String identifier) { - InputStream in = getEngineFromJar(identifier); + InputStream in = getInputStreamFromJar(identifier + ".xml"); // Fallback for standalone search activity. if (in == null) { @@ -210,27 +211,43 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference } /** - * Reads open search plugin XML file from the gecko jar. This will only work + * Reads a file from the searchplugins directory in the Gecko jar. This will only work * if the search activity is built as part of mozilla-central. * - * @param identifier search engine identifier (e.g. "google") - * @return InputStream for open search plugin XML + * @param fileName name of the file to read + * @return InputStream for file */ - private InputStream getEngineFromJar(String identifier) { - final String url = getSearchPluginsJarUrl(identifier + ".xml"); + private InputStream getInputStreamFromJar(String fileName) { + final Locale locale = Locale.getDefault(); + + // First, try a file path for the full locale. + final String languageTag = BrowserLocaleManager.getLanguageTag(locale); + String url = getSearchPluginsJarURL(languageTag, fileName); + + final InputStream in = GeckoJarReader.getStream(url); + if (in != null) { + return in; + } + + // If that doesn't work, try a file path for just the language. + final String language = BrowserLocaleManager.getLanguage(locale); + if (languageTag.equals(language)) { + // We already tried this, so just return null. + return null; + } + + url = getSearchPluginsJarURL(language, fileName); return GeckoJarReader.getStream(url); } /** * Gets the jar URL for a file in the searchplugins directory * - * @param fileName - * @return + * @param locale String representing the Gecko locale (e.g. "en-US") + * @param fileName name of the file to read + * @return URL for jar file */ - private String getSearchPluginsJarUrl(String fileName) { - // TODO: Get the real value for this - final String locale = "en-US"; - + private String getSearchPluginsJarURL(String locale, String fileName) { final String path = "!/chrome/" + locale + "/locale/" + locale + "/browser/searchplugins/" + fileName; return "jar:jar:file://" + context.getPackageResourcePath() + "!/" + AppConstants.OMNIJAR_NAME + path; } diff --git a/mobile/android/search/res/layout/search_suggestions_row.xml b/mobile/android/search/res/layout/search_suggestions_row.xml index 10dbe7f1c8a..34d865ae0e0 100644 --- a/mobile/android/search/res/layout/search_suggestions_row.xml +++ b/mobile/android/search/res/layout/search_suggestions_row.xml @@ -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/. --> - - + diff --git a/security/manager/boot/src/StaticHPKPins.h b/security/manager/boot/src/StaticHPKPins.h index 19c204523dc..0e90b592c53 100644 --- a/security/manager/boot/src/StaticHPKPins.h +++ b/security/manager/boot/src/StaticHPKPins.h @@ -1087,4 +1087,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = { static const int32_t kUnknownId = -1; -static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1418406258075000); +static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1418465237331000); diff --git a/security/manager/boot/src/nsSTSPreloadList.errors b/security/manager/boot/src/nsSTSPreloadList.errors index 63ca8f0d688..51b226356e0 100644 --- a/security/manager/boot/src/nsSTSPreloadList.errors +++ b/security/manager/boot/src/nsSTSPreloadList.errors @@ -46,6 +46,7 @@ email.lookout.com: could not connect to host encrypted.google.com: did not receive HSTS header (error ignored - included regardless) epoxate.com: did not receive HSTS header espra.com: could not connect to host +f-droid.org: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 124" data: no] fatzebra.com.au: did not receive HSTS header gamesdepartment.co.uk: did not receive HSTS header get.zenpayroll.com: did not receive HSTS header @@ -73,11 +74,11 @@ jitsi.org: did not receive HSTS header jottit.com: could not connect to host keymaster.lookout.com: did not receive HSTS header kiwiirc.com: max-age too low: 5256000 +klaxn.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 124" data: no] ledgerscope.net: did not receive HSTS header liberty.lavabit.com: could not connect to host lifeguard.aecom.com: did not receive HSTS header lists.mayfirst.org: did not receive HSTS header -loenshotel.de: could not connect to host login.corp.google.com: max-age too low: 7776000 (error ignored - included regardless) logotype.se: did not receive HSTS header ludwig.im: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 124" data: no] @@ -110,6 +111,7 @@ profiles.google.com: did not receive HSTS header (error ignored - included regar promecon-gmbh.de: did not receive HSTS header rapidresearch.me: could not connect to host riseup.net: did not receive HSTS header +roddis.net: could not connect to host sah3.net: could not connect to host saturngames.co.uk: did not receive HSTS header script.google.com: did not receive HSTS header (error ignored - included regardless) @@ -148,7 +150,6 @@ www.gmail.com: did not receive HSTS header (error ignored - included regardless) www.googlemail.com: did not receive HSTS header (error ignored - included regardless) www.greplin.com: did not receive HSTS header www.jitsi.org: did not receive HSTS header -www.lastpass.com: did not receive HSTS header www.ledgerscope.net: did not receive HSTS header www.logentries.com: did not receive HSTS header www.moneybookers.com: did not receive HSTS header @@ -156,7 +157,7 @@ www.neonisi.com: could not connect to host www.paycheckrecords.com: max-age too low: 86400 www.paypal.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 124" data: no] www.rme.li: did not receive HSTS header -www.roddis.net: did not receive HSTS header +www.roddis.net: could not connect to host www.sandbox.mydigipass.com: could not connect to host www.surfeasy.com: did not receive HSTS header zoo24.de: max-age too low: 2592000 diff --git a/security/manager/boot/src/nsSTSPreloadList.inc b/security/manager/boot/src/nsSTSPreloadList.inc index 0a5a4f4152e..2e2ad6b5150 100644 --- a/security/manager/boot/src/nsSTSPreloadList.inc +++ b/security/manager/boot/src/nsSTSPreloadList.inc @@ -8,7 +8,7 @@ /*****************************************************************************/ #include -const PRTime gPreloadListExpirationTime = INT64_C(1420280117245000); +const PRTime gPreloadListExpirationTime = INT64_C(1420884435199000); class nsSTSPreload { @@ -152,7 +152,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "fairbill.com", true }, { "faq.lookout.com", false }, { "feedbin.com", false }, - { "ferienhaus-polchow-ruegen.de", true }, + { "ferienhaus-polchow-ruegen.de", false }, { "fiken.no", true }, { "firemail.io", true }, { "fischer-its.com", true }, @@ -497,6 +497,7 @@ static const nsSTSPreload kSTSPreloadList[] = { { "www.heliosnet.com", true }, { "www.intercom.io", false }, { "www.irccloud.com", false }, + { "www.lastpass.com", false }, { "www.linode.com", false }, { "www.lookout.com", false }, { "www.makeyourlaws.org", true }, diff --git a/toolkit/components/places/History.cpp b/toolkit/components/places/History.cpp index f0aa0ebbee0..ee033310e75 100644 --- a/toolkit/components/places/History.cpp +++ b/toolkit/components/places/History.cpp @@ -185,33 +185,69 @@ struct RemoveVisitsFilter { class PlaceHashKey : public nsCStringHashKey { - public: - explicit PlaceHashKey(const nsACString& aSpec) +public: + explicit PlaceHashKey(const nsACString& aSpec) : nsCStringHashKey(&aSpec) - , visitCount(-1) - , bookmarked(-1) - { - } + , mVisitCount(0) + , mBookmarked(false) +#ifdef DEBUG + , mIsInitialized(false) +#endif + { + } - explicit PlaceHashKey(const nsACString* aSpec) + explicit PlaceHashKey(const nsACString* aSpec) : nsCStringHashKey(aSpec) - , visitCount(-1) - , bookmarked(-1) - { - } + , mVisitCount(0) + , mBookmarked(false) +#ifdef DEBUG + , mIsInitialized(false) +#endif + { + } - PlaceHashKey(const PlaceHashKey& aOther) + PlaceHashKey(const PlaceHashKey& aOther) : nsCStringHashKey(&aOther.GetKey()) - { - MOZ_ASSERT(false, "Do not call me!"); - } + { + MOZ_ASSERT(false, "Do not call me!"); + } - // Visit count for this place. - int32_t visitCount; - // Whether this place is bookmarked. - int32_t bookmarked; - // Array of VisitData objects. - nsTArray visits; + void SetProperties(uint32_t aVisitCount, bool aBookmarked) + { + mVisitCount = aVisitCount; + mBookmarked = aBookmarked; +#ifdef DEBUG + mIsInitialized = true; +#endif + } + + uint32_t VisitCount() const + { +#ifdef DEBUG + MOZ_ASSERT(mIsInitialized, "PlaceHashKey::mVisitCount not set"); +#endif + return mVisitCount; + } + + bool IsBookmarked() const + { +#ifdef DEBUG + MOZ_ASSERT(mIsInitialized, "PlaceHashKey::mBookmarked not set"); +#endif + return mBookmarked; + } + + // Array of VisitData objects. + nsTArray mVisits; +private: + // Visit count for this place. + uint32_t mVisitCount; + // Whether this place is bookmarked. + bool mBookmarked; +#ifdef DEBUG + // Whether previous attributes are set. + bool mIsInitialized; +#endif }; //////////////////////////////////////////////////////////////////////////////// @@ -1568,9 +1604,8 @@ static PLDHashOperator TransferHashEntries(PlaceHashKey* aEntry, nsTHashtable* hash = static_cast *>(aHash); PlaceHashKey* copy = hash->PutEntry(aEntry->GetKey()); - copy->visitCount = aEntry->visitCount; - copy->bookmarked = aEntry->bookmarked; - aEntry->visits.SwapElements(copy->visits); + copy->SetProperties(aEntry->VisitCount(), aEntry->IsBookmarked()); + aEntry->mVisits.SwapElements(copy->mVisits); return PL_DHASH_NEXT; } @@ -1581,13 +1616,12 @@ static PLDHashOperator NotifyVisitRemoval(PlaceHashKey* aEntry, void* aHistory) { nsNavHistory* history = static_cast(aHistory); - const nsTArray& visits = aEntry->visits; + const nsTArray& visits = aEntry->mVisits; nsCOMPtr uri; (void)NS_NewURI(getter_AddRefs(uri), visits[0].spec); - // XXX visitCount should really just be unsigned (bug 1049812) bool removingPage = - visits.Length() == static_cast(aEntry->visitCount) && - !aEntry->bookmarked; + visits.Length() == aEntry->VisitCount() && + !aEntry->IsBookmarked(); // FindRemovableVisits only sets the transition type on the VisitData objects // it collects if the visits were filtered by transition type. // RemoveVisitsFilter currently only supports filtering by transition type, so @@ -1662,11 +1696,10 @@ private: static PLDHashOperator ListToBeRemovedPlaceIds(PlaceHashKey* aEntry, void* aIdsList) { - const nsTArray& visits = aEntry->visits; + const nsTArray& visits = aEntry->mVisits; // Only orphan ids should be listed. - // XXX visitCount should really just be unsigned (bug 1049812) - if (visits.Length() == static_cast(aEntry->visitCount) && - !aEntry->bookmarked) { + if (visits.Length() == aEntry->VisitCount() && + !aEntry->IsBookmarked()) { nsCString* list = static_cast(aIdsList); if (!list->IsEmpty()) list->Append(','); @@ -1815,9 +1848,8 @@ private: if (!entry) { entry = aPlaces.PutEntry(visit.spec); } - entry->visitCount = visitCount; - entry->bookmarked = bookmarked; - entry->visits.AppendElement(visit); + entry->SetProperties(static_cast(visitCount), static_cast(bookmarked)); + entry->mVisits.AppendElement(visit); } NS_ENSURE_SUCCESS(rv, rv); diff --git a/toolkit/modules/Finder.jsm b/toolkit/modules/Finder.jsm index 3abbf62fa2e..59286d47d1b 100644 --- a/toolkit/modules/Finder.jsm +++ b/toolkit/modules/Finder.jsm @@ -197,9 +197,12 @@ Finder.prototype = { // Allow Finder listeners to cancel focusing the content. for (let l of this._listeners) { try { - if (!l.shouldFocusContent()) + if ("shouldFocusContent" in l && + !l.shouldFocusContent()) return; - } catch (ex) {} + } catch (ex) { + Cu.reportError(ex); + } } let fastFind = this._fastFind; diff --git a/toolkit/modules/RemoteFinder.jsm b/toolkit/modules/RemoteFinder.jsm index 9899160e0df..768b120a6c4 100644 --- a/toolkit/modules/RemoteFinder.jsm +++ b/toolkit/modules/RemoteFinder.jsm @@ -83,6 +83,17 @@ RemoteFinder.prototype = { }, focusContent: function () { + // Allow Finder listeners to cancel focusing the content. + for (let l of this._listeners) { + try { + if ("shouldFocusContent" in l && + !l.shouldFocusContent()) + return; + } catch (ex) { + Cu.reportError(ex); + } + } + this._browser.messageManager.sendAsyncMessage("Finder:FocusContent"); }, @@ -134,12 +145,6 @@ RemoteFinderListener.prototype = { this._global.sendAsyncMessage("Finder:MatchesResult", aData); }, - //XXXmikedeboer-20131016: implement |shouldFocusContent| here to mitigate - // issues like bug 921338 and bug 921308. - shouldFocusContent: function () { - return true; - }, - receiveMessage: function (aMessage) { let data = aMessage.data;