Bug 1249642 - Implement remote modes in aboutNewTabService.js r?oyiptong
MozReview-Commit-ID: 7DiwSSVMJf2
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1378,16 +1378,19 @@ pref("browser.newtabpage.columns", 5);
pref("browser.newtabpage.directory.source", "https://tiles.services.mozilla.com/v3/links/fetch/%LOCALE%/%CHANNEL%");
// endpoint to send newtab click and view pings
pref("browser.newtabpage.directory.ping", "https://tiles.services.mozilla.com/v3/links/");
// activates the remote-hosted newtab page
pref("browser.newtabpage.remote", false);
+// Toggles endpoints allowed for remote newtab communications
+pref("browser.newtabpage.remote.mode", "production");
+
// Enable the DOM fullscreen API.
pref("full-screen-api.enabled", true);
// Startup Crash Tracking
// number of startup crashes that can occur before starting into safe mode automatically
// (this pref has no effect if more than 6 hours have passed since the last crash)
pref("toolkit.startup.max_resumed_crashes", 3);
--- a/browser/components/newtab/NewTabPrefsProvider.jsm
+++ b/browser/components/newtab/NewTabPrefsProvider.jsm
@@ -13,16 +13,17 @@ Cu.import("resource://gre/modules/XPCOMU
XPCOMUtils.defineLazyGetter(this, "EventEmitter", function() {
const {EventEmitter} = Cu.import("resource://devtools/shared/event-emitter.js", {});
return EventEmitter;
});
// Supported prefs and data type
const gPrefsMap = new Map([
["browser.newtabpage.remote", "bool"],
+ ["browser.newtabpage.remote.mode", "str"],
["browser.newtabpage.enabled", "bool"],
["browser.newtabpage.enhanced", "bool"],
["browser.newtabpage.pinned", "str"],
["intl.locale.matchOS", "bool"],
["general.useragent.locale", "localized"],
]);
let PrefsProvider = function PrefsProvider() {
new file mode 100644
--- /dev/null
+++ b/browser/components/newtab/NewTabRemoteResources.jsm
@@ -0,0 +1,13 @@
+/* exported MODE_CHANNEL_MAP */
+
+"use strict";
+
+this.EXPORTED_SYMBOLS = ["MODE_CHANNEL_MAP"];
+
+const MODE_CHANNEL_MAP = {
+ "production": {origin: "https://content.cdn.mozilla.net"},
+ "staging": {origin: "https://content-cdn.stage.mozaws.net"},
+ "test": {origin: "https://example.com"},
+ "test2": {origin: "http://mochi.test:8888"},
+ "dev": {origin: "http://localhost:8888"}
+};
--- a/browser/components/newtab/aboutNewTabService.js
+++ b/browser/components/newtab/aboutNewTabService.js
@@ -1,54 +1,60 @@
/*
* 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/.
*/
/* globals XPCOMUtils, NewTabPrefsProvider, Services,
- Locale, UpdateUtils
+ Locale, UpdateUtils, MODE_CHANNEL_MAP
*/
"use strict";
const {utils: Cu, interfaces: Ci} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "NewTabPrefsProvider",
"resource:///modules/NewTabPrefsProvider.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Locale",
"resource://gre/modules/Locale.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "MODE_CHANNEL_MAP",
+ "resource:///modules/NewTabRemoteResources.jsm");
const LOCAL_NEWTAB_URL = "chrome://browser/content/newtab/newTab.xhtml";
-const REMOTE_NEWTAB_URL = "https://newtab.cdn.mozilla.net/" +
- "v%VERSION%/%CHANNEL%/%LOCALE%/index.html";
+const REMOTE_NEWTAB_PATH = "/v%VERSION%/%CHANNEL%/%LOCALE%/index.html";
const ABOUT_URL = "about:newtab";
// Pref that tells if remote newtab is enabled
const PREF_REMOTE_ENABLED = "browser.newtabpage.remote";
// The preference that tells whether to match the OS locale
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
// The preference that tells what locale the user selected
const PREF_SELECTED_LOCALE = "general.useragent.locale";
+// The preference that tells what remote mode is enabled.
+const PREF_REMOTE_MODE = "browser.newtabpage.remote.mode";
+
const VALID_CHANNELS = new Set(["esr", "release", "beta", "aurora", "nightly"]);
const REMOTE_NEWTAB_VERSION = "0";
function AboutNewTabService() {
NewTabPrefsProvider.prefs.on(PREF_REMOTE_ENABLED, this._handleToggleEvent.bind(this));
+ this._updateRemoteMaybe = this._updateRemoteMaybe.bind(this);
+
// trigger remote change if needed, according to pref
this.toggleRemote(Services.prefs.getBoolPref(PREF_REMOTE_ENABLED));
}
/*
* A service that allows for the overriding, at runtime, of the newtab page's url.
* Additionally, the service manages pref state between a remote and local newtab page.
*
@@ -119,40 +125,48 @@ AboutNewTabService.prototype = {
// exit there is no change of state
return false;
}
if (stateEnabled) {
this._remoteURL = this.generateRemoteURL();
NewTabPrefsProvider.prefs.on(
PREF_SELECTED_LOCALE,
- this._updateRemoteMaybe.bind(this));
+ this._updateRemoteMaybe);
NewTabPrefsProvider.prefs.on(
PREF_MATCH_OS_LOCALE,
- this._updateRemoteMaybe.bind(this));
+ this._updateRemoteMaybe);
+ NewTabPrefsProvider.prefs.on(
+ PREF_REMOTE_MODE,
+ this._updateRemoteMaybe);
this._remoteEnabled = true;
} else {
NewTabPrefsProvider.prefs.off(PREF_SELECTED_LOCALE, this._updateRemoteMaybe);
NewTabPrefsProvider.prefs.off(PREF_MATCH_OS_LOCALE, this._updateRemoteMaybe);
+ NewTabPrefsProvider.prefs.off(PREF_REMOTE_MODE, this._updateRemoteMaybe);
this._remoteEnabled = false;
}
this._newTabURL = ABOUT_URL;
return true;
},
/*
- * Generate a default url based on locale and update channel
+ * Generate a default url based on remote mode, version, locale and update channel
*/
generateRemoteURL() {
let releaseName = this.releaseFromUpdateChannel(UpdateUtils.UpdateChannel);
- let url = REMOTE_NEWTAB_URL
+ let path = REMOTE_NEWTAB_PATH
.replace("%VERSION%", REMOTE_NEWTAB_VERSION)
.replace("%LOCALE%", Locale.getLocale())
.replace("%CHANNEL%", releaseName);
- return url;
+ let mode = Services.prefs.getCharPref(PREF_REMOTE_MODE, "production");
+ if (!(mode in MODE_CHANNEL_MAP)) {
+ mode = "production";
+ }
+ return MODE_CHANNEL_MAP[mode].origin + path;
},
/*
* Returns the default URL.
*
* This URL only depends on the browser.newtabpage.remote pref. Overriding
* the newtab page has no effect on the result of this function.
*
--- a/browser/components/newtab/moz.build
+++ b/browser/components/newtab/moz.build
@@ -7,16 +7,17 @@
BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
XPCSHELL_TESTS_MANIFESTS += [
'tests/xpcshell/xpcshell.ini',
]
EXTRA_JS_MODULES += [
'NewTabPrefsProvider.jsm',
+ 'NewTabRemoteResources.jsm',
'NewTabURL.jsm',
'PlacesProvider.jsm'
]
XPIDL_SOURCES += [
'nsIAboutNewTabService.idl',
]
--- a/browser/components/newtab/tests/xpcshell/test_AboutNewTabService.js
+++ b/browser/components/newtab/tests/xpcshell/test_AboutNewTabService.js
@@ -100,35 +100,50 @@ add_task(function* test_override_remote_
add_task(function* test_updates() {
/*
* Simulates a "cold-boot" situation, with some pref already set before testing a series
* of changes.
*/
Preferences.set("browser.newtabpage.remote", true);
aboutNewTabService.resetNewTabURL(); // need to set manually because pref notifs are off
let notificationPromise;
- let expectedHref = "https://newtab.cdn.mozilla.net" +
- `/v${aboutNewTabService.remoteVersion}` +
+ let productionModeBaseUrl = "https://content.cdn.mozilla.net";
+ let testModeBaseUrl = "https://example.com";
+ let expectedPath = `/v${aboutNewTabService.remoteVersion}` +
`/${aboutNewTabService.remoteReleaseName}` +
"/en-GB" +
"/index.html";
+ let expectedHref = productionModeBaseUrl + expectedPath;
Preferences.set("intl.locale.matchOS", true);
Preferences.set("general.useragent.locale", "en-GB");
+ Preferences.set("browser.newtabpage.remote.mode", "production");
NewTabPrefsProvider.prefs.init();
// test update checks for prefs
notificationPromise = nextChangeNotificationPromise(
expectedHref, "Remote href should be updated");
Preferences.set("intl.locale.matchOS", false);
yield notificationPromise;
notificationPromise = nextChangeNotificationPromise(
DEFAULT_HREF, "Remote href changes back to default");
Preferences.set("general.useragent.locale", "en-US");
+ yield notificationPromise;
+ // test update fires when mode is changed
+ expectedPath = expectedPath.replace("/en-GB/", "/en-US/");
+ notificationPromise = nextChangeNotificationPromise(
+ testModeBaseUrl + expectedPath, "Remote href changes back to origin of test mode");
+ Preferences.set("browser.newtabpage.remote.mode", "test");
+ yield notificationPromise;
+
+ // test invalid mode ends up pointing to production url
+ notificationPromise = nextChangeNotificationPromise(
+ DEFAULT_HREF, "Remote href changes back to production default");
+ Preferences.set("browser.newtabpage.remote.mode", "invalid");
yield notificationPromise;
// test update fires on override and reset
let testURL = "https://example.com/";
notificationPromise = nextChangeNotificationPromise(
testURL, "a notification occurs on override");
aboutNewTabService.newTabURL = testURL;
yield notificationPromise;