Bug 1192924: Expose the update URL formatting code a new UpdateUtils module. r=rstrong

The GMP manager uses a copy of the update service's url formatting code and has
since fallen out of sync. We'll also want to use the same formatting code for
the system add-on update checks so this just exposes it in a shared API.

I've moved the contents of UpdateChannel.jsm to UpdateUtils.jsm and exposed
formatUpdateURL there as well as a few properties that the update service still
needs access to.

UpdateUtils.UpdateChannel is intended to be a lazy getter but isn't for now
since tests expect to be able to change the update channel at runtime.

--HG--
extra : commitid : KsbH21csjH4
extra : rebase_source : bc7c08de1ec6e802261b8cd294d88ee2c4e75c2d
This commit is contained in:
Dave Townsend 2015-09-14 11:04:19 -07:00
parent bf5662d318
commit a22c2d1f9e
36 changed files with 733 additions and 595 deletions

View File

@ -72,7 +72,7 @@ function init(aEvent)
let defaults = Services.prefs.getDefaultBranch("");
let channelLabel = document.getElementById("currentChannel");
let currentChannelText = document.getElementById("currentChannelText");
channelLabel.value = UpdateChannel.get();
channelLabel.value = UpdateUtils.UpdateChannel;
if (/^release($|\-)/.test(channelLabel.value))
currentChannelText.hidden = true;
#endif
@ -89,8 +89,8 @@ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
Components.utils.import("resource://gre/modules/AddonManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
var gAppUpdater;

View File

@ -42,8 +42,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "Log",
"resource://gre/modules/Log.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
"resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "Favicons",
"@mozilla.org/browser/favicon-service;1",
"mozIAsyncFavicons");
@ -2919,7 +2919,7 @@ var BrowserOnClick = {
version: 1,
build: gAppInfo.appBuildID,
product: gAppInfo.name,
channel: UpdateChannel.get()
channel: UpdateUtils.UpdateChannel
}
let reportURL = Services.prefs.getCharPref("security.ssl.errorReporting.url");

View File

@ -18,8 +18,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "Rect",
"resource://gre/modules/Geometry.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
var {
links: gLinks,

View File

@ -60,7 +60,7 @@ add_task(function*() {
let updateChannel = null;
try {
updateChannel = Cu.import("resource://gre/modules/UpdateChannel.jsm", {}).UpdateChannel.get();
updateChannel = Cu.import("resource://gre/modules/UpdateUtils.jsm", {}).UpdateUtils.UpdateChannel;
} catch (ex) {}
if (!updateChannel) {
Assert.ok(!('updateChannel' in got.message.application),

View File

@ -25,8 +25,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "PageMetadata",
"resource://gre/modules/PageMetadata.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UITour",
"resource:///modules/UITour.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Social",
@ -810,7 +810,7 @@ function injectLoopAPI(targetWindow) {
// which doesn't have what we need, so log an error.
try {
appVersionInfo = Cu.cloneInto({
channel: UpdateChannel.get(),
channel: UpdateUtils.UpdateChannel,
version: appInfo.version,
OS: appInfo.OS
}, targetWindow);

View File

@ -124,8 +124,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "ContentSearch",
"resource:///modules/ContentSearch.jsm");
#ifdef E10S_TESTING_ONLY
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
#endif
#ifdef MOZ_CRASHREPORTER
@ -2977,7 +2977,7 @@ var E10SUINotification = {
checkStatus: function() {
let skipE10sChecks = false;
try {
let updateChannel = UpdateChannel.get();
let updateChannel = UpdateUtils.UpdateChannel;
let channelAuthorized = updateChannel == "nightly" || updateChannel == "aurora";
skipE10sChecks = !channelAuthorized ||

View File

@ -165,8 +165,8 @@ var gMainPane = {
}
let tmp = {};
Components.utils.import("resource://gre/modules/UpdateChannel.jsm", tmp);
if (!e10sCheckbox.checked && tmp.UpdateChannel.get() != "default") {
Components.utils.import("resource://gre/modules/UpdateUtils.jsm", tmp);
if (!e10sCheckbox.checked && tmp.UpdateUtils.UpdateChannel != "default") {
Services.prefs.setBoolPref("browser.requestE10sFeedback", true);
Services.prompt.alert(window, brandName, bundle.getString("e10sFeedbackAfterRestart"));
}

View File

@ -20,8 +20,8 @@ Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/AsyncShutdown.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate",
@ -275,7 +275,7 @@ Experiments.Policy.prototype = {
},
updatechannel: function () {
return UpdateChannel.get();
return UpdateUtils.UpdateChannel;
},
locale: function () {

View File

@ -26,8 +26,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm")
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
"resource://gre/modules/Promise.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "eTLD",
"@mozilla.org/network/effective-tld-service;1",
"nsIEffectiveTLDService");
@ -280,7 +280,7 @@ var DirectoryLinksProvider = {
_fetchAndCacheLinks: function DirectoryLinksProvider_fetchAndCacheLinks(uri) {
// Replace with the same display locale used for selecting links data
uri = uri.replace("%LOCALE%", this.locale);
uri = uri.replace("%CHANNEL%", UpdateChannel.get());
uri = uri.replace("%CHANNEL%", UpdateUtils.UpdateChannel);
return this._downloadJsonData(uri).then(json => {
return OS.File.writeAtomic(this._directoryFilePath, json, {tmpPath: this._directoryFilePath + ".tmp"});

View File

@ -22,7 +22,7 @@ const FLOATY_ICON_XXHDPI = "chrome://browser/skin/images/icon_floaty_xxhdpi.png"
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Messaging.jsm");
Cu.import("resource://gre/modules/UpdateChannel.jsm");
Cu.import("resource://gre/modules/UpdateUtils.jsm");
document.addEventListener("DOMContentLoaded", init, false);
function dump(a) {
@ -138,7 +138,7 @@ function sendFeedback(aEvent) {
data["platform"] = Services.appinfo.OS;
data["version"] = Services.appinfo.version;
data["locale"] = Services.locale.getSystemLocale().getCategory("NSILOCALE_CTYPE");
data["channel"] = UpdateChannel.get();
data["channel"] = UpdateUtils.UpdateChannel;
// Source field is added only when Fennec prompts the user.
let getParam = window.location.href.split("?");

View File

@ -27,7 +27,7 @@ XPCOMUtils.defineLazyModuleGetter(
this, "Promise", "resource://gre/modules/Promise.jsm");
XPCOMUtils.defineLazyModuleGetter(
this, "UpdateChannel", "resource://gre/modules/UpdateChannel.jsm");
this, "UpdateUtils", "resource://gre/modules/UpdateUtils.jsm");
XPCOMUtils.defineLazyServiceGetter(
this, "gUpdateTimer", "@mozilla.org/updates/timer-manager;1", "nsIUpdateTimerManager");
@ -192,7 +192,7 @@ this.UserAgentUpdates = {
"%APP_VERSION%": function() { return gApp.version; },
"%BUILD_ID%": function() { return gApp.appBuildID; },
"%OS%": function() { return gApp.OS; },
"%CHANNEL%": function() { return UpdateChannel.get(); },
"%CHANNEL%": function() { return UpdateUtils.UpdateChannel; },
"%DISTRIBUTION%": function() { return this._getPref(PREF_APP_DISTRIBUTION, ""); },
"%DISTRIBUTION_VERSION%": function() { return this._getPref(PREF_APP_DISTRIBUTION_VERSION, ""); },
};

View File

@ -25,7 +25,7 @@ Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://services-common/utils.js");
Cu.import("resource://gre/modules/UpdateChannel.jsm");
Cu.import("resource://gre/modules/UpdateUtils.jsm");
// The current policy version number. If the version number stored in the prefs
// is smaller than this, data upload will be disabled until the user is re-notified
@ -388,7 +388,7 @@ this.DataReportingPolicy.prototype = Object.freeze({
*/
get minimumPolicyVersion() {
// First check if the current channel has an ove
let channel = UpdateChannel.get(false);
let channel = UpdateUtils.getUpdateChannel(false);
let channelPref = this._prefs.get("minimumPolicyVersion.channel-" + channel);
return channelPref !== undefined ?
channelPref : this._prefs.get("minimumPolicyVersion", 1);

View File

@ -8,7 +8,7 @@ const {utils: Cu} = Components;
Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/services/datareporting/policy.jsm");
Cu.import("resource://testing-common/services/datareporting/mocks.jsm");
Cu.import("resource://gre/modules/UpdateChannel.jsm");
Cu.import("resource://gre/modules/UpdateUtils.jsm");
Cu.import("resource://gre/modules/Task.jsm");
function getPolicy(name,
@ -23,7 +23,7 @@ function getPolicy(name,
, defaultBranch: true });
defaultPolicyPrefs.set("currentPolicyVersion", aCurrentPolicyVersion);
defaultPolicyPrefs.set("minimumPolicyVersion", aMinimumPolicyVersion);
let branchOverridePrefName = "minimumPolicyVersion.channel-" + UpdateChannel.get(false);
let branchOverridePrefName = "minimumPolicyVersion.channel-" + UpdateUtils.getUpdateChannel(false);
if (aBranchMinimumVersionOverride !== undefined)
defaultPolicyPrefs.set(branchOverridePrefName, aBranchMinimumVersionOverride);
else

View File

@ -30,8 +30,8 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryController",
"resource://gre/modules/TelemetryController.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
// Oldest year to allow in date preferences. This module was implemented in
// 2012 and no dates older than that should be encountered.
@ -1103,7 +1103,7 @@ AbstractHealthReporter.prototype = Object.freeze({
}
try {
out["updateChannel"] = UpdateChannel.get();
out["updateChannel"] = UpdateUtils.UpdateChannel;
} catch (ex) {
this._log.warn("Could not obtain update channel: " +
CommonUtils.exceptionStr(ex));

View File

@ -46,8 +46,8 @@ Cu.import("resource://services-common/utils.js");
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesDBUtils",
"resource://gre/modules/PlacesDBUtils.jsm");
@ -333,7 +333,7 @@ AppInfoProvider.prototype = Object.freeze({
}
try {
yield m.setLastText("updateChannel", UpdateChannel.get());
yield m.setLastText("updateChannel", UpdateUtils.UpdateChannel);
} catch (ex) {
this._log.warn("Could not obtain update channel: " +
CommonUtils.exceptionStr(ex));

View File

@ -80,8 +80,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "TelemetryEnvironment",
"resource://gre/modules/TelemetryEnvironment.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "SessionRecorder",
"resource://gre/modules/SessionRecorder.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryArchive",
"resource://gre/modules/TelemetryArchive.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TelemetrySession",
@ -412,7 +412,7 @@ var Impl = {
let updateChannel = null;
try {
updateChannel = UpdateChannel.get(false);
updateChannel = UpdateUtils.getUpdateChannel(false);
} catch (e) {
this._log.trace("assemblePing - Unable to get update channel.", e);
}

View File

@ -32,8 +32,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeManager",
#endif
XPCOMUtils.defineLazyModuleGetter(this, "ProfileAge",
"resource://gre/modules/ProfileAge.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
const CHANGE_THROTTLE_INTERVAL_MS = 5 * 60 * 1000;
@ -1007,7 +1007,7 @@ EnvironmentCache.prototype = {
_updateSettings: function () {
let updateChannel = null;
try {
updateChannel = UpdateChannel.get(false);
updateChannel = UpdateUtils.getUpdateChannel(false);
} catch (e) {}
this._currentEnvironment.settings = {

View File

@ -19,8 +19,8 @@ Cu.import("resource://services-common/observers.js", this);
XPCOMUtils.defineLazyModuleGetter(this, "TelemetrySend",
"resource://gre/modules/TelemetrySend.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
const LOGGER_NAME = "Toolkit.Telemetry";
const LOGGER_PREFIX = "TelemetryReportingPolicy::";
@ -251,7 +251,7 @@ var TelemetryReportingPolicyImpl = {
// use the general minimum policy version.
let channel = "";
try {
channel = UpdateChannel.get(false);
channel = UpdateUtils.getUpdateChannel(false);
} catch(e) {
this._log.error("minimumPolicyVersion - Unable to retrieve the current channel.");
return minPolicyVersion;

View File

@ -143,8 +143,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "ThirdPartyCookieProbe",
"resource://gre/modules/ThirdPartyCookieProbe.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UITelemetry",
"resource://gre/modules/UITelemetry.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryEnvironment",
"resource://gre/modules/TelemetryEnvironment.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils",

View File

@ -25,8 +25,8 @@ Cu.import("resource://gre/modules/Services.jsm");
const PREF_APP_DISTRIBUTION = "distribution.id";
const PREF_APP_DISTRIBUTION_VERSION = "distribution.version";
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
function nsURLFormatterService() {
XPCOMUtils.defineLazyGetter(this, "appInfo", function UFS_appInfo() {
@ -111,7 +111,7 @@ nsURLFormatterService.prototype = {
XPCOMABI: function() this.ABI,
BUILD_TARGET: function() this.appInfo.OS + "_" + this.ABI,
OS_VERSION: function() this.OSVersion,
CHANNEL: function() UpdateChannel.get(),
CHANNEL: function() UpdateUtils.UpdateChannel,
MOZILLA_API_KEY: function() "@MOZ_MOZILLA_API_KEY@",
GOOGLE_API_KEY: function() "@MOZ_GOOGLE_API_KEY@",
GOOGLE_OAUTH_API_CLIENTID:function() "@MOZ_GOOGLE_OAUTH_API_CLIENTID@",

View File

@ -4,4 +4,3 @@ tail =
skip-if = toolkit == 'gonk'
[test_contentAreaUtils.js]
[test_updateChannelModule.js]

View File

@ -213,8 +213,10 @@ this.AppConstants = Object.freeze({
MOZ_APP_VERSION_DISPLAY: "@MOZ_APP_VERSION_DISPLAY@",
MOZ_BUILD_APP: "@MOZ_BUILD_APP@",
MOZ_UPDATE_CHANNEL: "@MOZ_UPDATE_CHANNEL@",
INSTALL_LOCALE: "@AB_CD@",
MOZ_WIDGET_TOOLKIT: "@MOZ_WIDGET_TOOLKIT@",
ANDROID_PACKAGE_NAME: "@ANDROID_PACKAGE_NAME@",
MOZ_ANDROID_APZ:
#ifdef MOZ_ANDROID_APZ
true,

View File

@ -30,15 +30,11 @@ Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://gre/modules/osfile.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/ctypes.jsm");
Cu.import("resource://gre/modules/GMPUtils.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm");
this.EXPORTED_SYMBOLS = ["GMPInstallManager", "GMPExtractor", "GMPDownloader",
"GMPAddon"];
var gLocale = null;
// Shared code for suppressing bad cert dialogs
XPCOMUtils.defineLazyGetter(this, "gCertUtils", function() {
let temp = { };
@ -46,8 +42,8 @@ XPCOMUtils.defineLazyGetter(this, "gCertUtils", function() {
return temp;
});
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
/**
* Number of milliseconds after which we need to cancel `checkForAddons`.
@ -65,138 +61,6 @@ function getScopedLogger(prefix) {
return Log.repository.getLoggerWithMessagePrefix("Toolkit.GMP", prefix + " ");
}
// This is copied directly from nsUpdateService.js
// It is used for calculating the URL string w/ var replacement.
// TODO: refactor this out somewhere else
XPCOMUtils.defineLazyGetter(this, "gOSVersion", function aus_gOSVersion() {
let osVersion;
try {
osVersion = Services.sysinfo.getProperty("name") + " " +
Services.sysinfo.getProperty("version");
}
catch (e) {
LOG("gOSVersion - OS Version unknown: updates are not possible.");
}
if (osVersion) {
if (AppConstants.platform == "win") {
const BYTE = ctypes.uint8_t;
const WORD = ctypes.uint16_t;
const DWORD = ctypes.uint32_t;
const WCHAR = ctypes.char16_t;
const BOOL = ctypes.int;
// This structure is described at:
// http://msdn.microsoft.com/en-us/library/ms724833%28v=vs.85%29.aspx
const SZCSDVERSIONLENGTH = 128;
const OSVERSIONINFOEXW = new ctypes.StructType('OSVERSIONINFOEXW',
[
{dwOSVersionInfoSize: DWORD},
{dwMajorVersion: DWORD},
{dwMinorVersion: DWORD},
{dwBuildNumber: DWORD},
{dwPlatformId: DWORD},
{szCSDVersion: ctypes.ArrayType(WCHAR, SZCSDVERSIONLENGTH)},
{wServicePackMajor: WORD},
{wServicePackMinor: WORD},
{wSuiteMask: WORD},
{wProductType: BYTE},
{wReserved: BYTE}
]);
// This structure is described at:
// http://msdn.microsoft.com/en-us/library/ms724958%28v=vs.85%29.aspx
const SYSTEM_INFO = new ctypes.StructType('SYSTEM_INFO',
[
{wProcessorArchitecture: WORD},
{wReserved: WORD},
{dwPageSize: DWORD},
{lpMinimumApplicationAddress: ctypes.voidptr_t},
{lpMaximumApplicationAddress: ctypes.voidptr_t},
{dwActiveProcessorMask: DWORD.ptr},
{dwNumberOfProcessors: DWORD},
{dwProcessorType: DWORD},
{dwAllocationGranularity: DWORD},
{wProcessorLevel: WORD},
{wProcessorRevision: WORD}
]);
let kernel32 = false;
try {
kernel32 = ctypes.open("Kernel32");
} catch (e) {
LOG("gOSVersion - Unable to open kernel32! " + e);
osVersion += ".unknown (unknown)";
}
if(kernel32) {
try {
// Get Service pack info
try {
let GetVersionEx = kernel32.declare("GetVersionExW",
ctypes.default_abi,
BOOL,
OSVERSIONINFOEXW.ptr);
let winVer = OSVERSIONINFOEXW();
winVer.dwOSVersionInfoSize = OSVERSIONINFOEXW.size;
if(0 !== GetVersionEx(winVer.address())) {
osVersion += "." + winVer.wServicePackMajor
+ "." + winVer.wServicePackMinor;
} else {
LOG("gOSVersion - Unknown failure in GetVersionEX (returned 0)");
osVersion += ".unknown";
}
} catch (e) {
LOG("gOSVersion - error getting service pack information. Exception: " + e);
osVersion += ".unknown";
}
// Get processor architecture
let arch = "unknown";
try {
let GetNativeSystemInfo = kernel32.declare("GetNativeSystemInfo",
ctypes.default_abi,
ctypes.void_t,
SYSTEM_INFO.ptr);
let sysInfo = SYSTEM_INFO();
// Default to unknown
sysInfo.wProcessorArchitecture = 0xffff;
GetNativeSystemInfo(sysInfo.address());
switch(sysInfo.wProcessorArchitecture) {
case 9:
arch = "x64";
break;
case 6:
arch = "IA64";
break;
case 0:
arch = "x86";
break;
}
} catch (e) {
LOG("gOSVersion - error getting processor architecture. Exception: " + e);
} finally {
osVersion += " (" + arch + ")";
}
} finally {
kernel32.close();
}
}
}
try {
osVersion += " (" + sysInfo.getProperty("secondaryLibrary") + ")";
}
catch (e) {
// Not all platforms have a secondary widget library, so an error is nothing to worry about.
}
osVersion = encodeURIComponent(osVersion);
}
return osVersion;
});
/**
* Provides an easy API for downloading and installing GMP Addons
*/
@ -221,24 +85,8 @@ GMPInstallManager.prototype = {
log.info("Using url: " + url);
}
url =
url.replace(/%PRODUCT%/g, Services.appinfo.name)
.replace(/%VERSION%/g, Services.appinfo.version)
.replace(/%BUILD_ID%/g, Services.appinfo.appBuildID)
.replace(/%BUILD_TARGET%/g, Services.appinfo.OS + "_" + GMPUtils.ABI())
.replace(/%OS_VERSION%/g, gOSVersion);
if (/%LOCALE%/.test(url)) {
// TODO: Get the real local, does it actually matter for GMP plugins?
url = url.replace(/%LOCALE%/g, "en-US");
}
url =
url.replace(/%CHANNEL%/g, UpdateChannel.get())
.replace(/%PLATFORM_VERSION%/g, Services.appinfo.platformVersion)
.replace(/%DISTRIBUTION%/g,
GMPPrefs.get(GMPPrefs.KEY_APP_DISTRIBUTION))
.replace(/%DISTRIBUTION_VERSION%/g,
GMPPrefs.get(GMPPrefs.KEY_APP_DISTRIBUTION_VERSION))
.replace(/\+/g, "%2B");
url = UpdateUtils.formatUpdateURL(url);
log.info("Using url (with replacement): " + url);
return url;
},
@ -908,7 +756,7 @@ GMPDownloader.prototype = {
// Remember our ABI, so that if the profile is migrated to another
// platform or from 32 -> 64 bit, we notice and don't try to load the
// unexecutable plugin library.
GMPPrefs.set(GMPPrefs.KEY_PLUGIN_ABI, GMPUtils.ABI(), gmpAddon.id);
GMPPrefs.set(GMPPrefs.KEY_PLUGIN_ABI, UpdateUtils.ABI, gmpAddon.id);
// Setting the version pref signals installation completion to consumers,
// if you need to set other prefs etc. do it before this.
GMPPrefs.set(GMPPrefs.KEY_PLUGIN_VERSION, gmpAddon.version,

View File

@ -126,27 +126,6 @@ this.GMPUtils = {
hist.add(value);
}
},
ABI: function() {
// This is copied directly from nsUpdateService.js
let abi = null;
try {
abi = Services.appinfo.XPCOMABI;
}
catch (e) {
return "unknown";
}
if (AppConstants.platform == "macosx") {
// Mac universal build should report a different ABI than either macppc
// or mactel.
let macutils = Cc["@mozilla.org/xpcom/mac-utils;1"].
getService(Ci.nsIMacUtils);
if (macutils.isUniversalBinary)
abi += "-u-" + macutils.architecturesInBinary;
}
return abi;
}
};
/**

View File

@ -181,7 +181,7 @@ var dataProviders = {
};
if (AppConstants.MOZ_UPDATER)
data.updateChannel = Cu.import("resource://gre/modules/UpdateChannel.jsm", {}).UpdateChannel.get();
data.updateChannel = Cu.import("resource://gre/modules/UpdateUtils.jsm", {}).UpdateUtils.UpdateChannel;
try {
data.vendor = Services.prefs.getCharPref("app.support.vendor");

View File

@ -1,46 +0,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/. */
this.EXPORTED_SYMBOLS = ["UpdateChannel"];
const Cu = Components.utils;
Cu.import("resource://gre/modules/AppConstants.jsm");
Cu.import("resource://gre/modules/Services.jsm");
this.UpdateChannel = {
/**
* Read the update channel from defaults only. We do this to ensure that
* the channel is tightly coupled with the application and does not apply
* to other instances of the application that may use the same profile.
*
* @param [optional] aIncludePartners
* Whether or not to include the partner bits. Default: true.
*/
get: function UpdateChannel_get(aIncludePartners = true) {
let channel = AppConstants.MOZ_UPDATE_CHANNEL;
let defaults = Services.prefs.getDefaultBranch(null);
try {
channel = defaults.getCharPref("app.update.channel");
} catch (e) {
// use default value when pref not found
}
if (aIncludePartners) {
try {
let partners = Services.prefs.getChildList("app.partner.").sort();
if (partners.length) {
channel += "-cck";
partners.forEach(function (prefName) {
channel += "-" + Services.prefs.getCharPref(prefName);
});
}
} catch (e) {
Cu.reportError(e);
}
}
return channel;
}
};

View File

@ -0,0 +1,347 @@
/* 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/. */
this.EXPORTED_SYMBOLS = ["UpdateUtils"];
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/AppConstants.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/ctypes.jsm");
const FILE_UPDATE_LOCALE = "update.locale";
const PREF_APP_DISTRIBUTION = "distribution.id";
const PREF_APP_DISTRIBUTION_VERSION = "distribution.version";
const PREF_APP_B2G_VERSION = "b2g.version";
const PREF_APP_UPDATE_CUSTOM = "app.update.custom";
const PREF_APP_UPDATE_IMEI_HASH = "app.update.imei_hash";
this.UpdateUtils = {
/**
* Read the update channel from defaults only. We do this to ensure that
* the channel is tightly coupled with the application and does not apply
* to other instances of the application that may use the same profile.
*
* @param [optional] aIncludePartners
* Whether or not to include the partner bits. Default: true.
*/
getUpdateChannel(aIncludePartners = true) {
let channel = AppConstants.MOZ_UPDATE_CHANNEL;
let defaults = Services.prefs.getDefaultBranch(null);
try {
channel = defaults.getCharPref("app.update.channel");
} catch (e) {
// use default value when pref not found
}
if (aIncludePartners) {
try {
let partners = Services.prefs.getChildList("app.partner.").sort();
if (partners.length) {
channel += "-cck";
partners.forEach(function (prefName) {
channel += "-" + Services.prefs.getCharPref(prefName);
});
}
} catch (e) {
Cu.reportError(e);
}
}
return channel;
},
get UpdateChannel() {
return this.getUpdateChannel();
},
/**
* Formats a URL by replacing %...% values with OS, build and locale specific
* values.
*
* @param url
* The URL to format.
* @return The formatted URL.
*/
formatUpdateURL(url) {
url = url.replace(/%PRODUCT%/g, Services.appinfo.name);
url = url.replace(/%VERSION%/g, Services.appinfo.version);
url = url.replace(/%BUILD_ID%/g, Services.appinfo.appBuildID);
url = url.replace(/%BUILD_TARGET%/g, Services.appinfo.OS + "_" + this.ABI);
url = url.replace(/%OS_VERSION%/g, this.OSVersion);
if (/%LOCALE%/.test(url)) {
url = url.replace(/%LOCALE%/g, this.Locale);
}
url = url.replace(/%CHANNEL%/g, this.UpdateChannel);
url = url.replace(/%PLATFORM_VERSION%/g, Services.appinfo.platformVersion);
url = url.replace(/%DISTRIBUTION%/g,
getDistributionPrefValue(PREF_APP_DISTRIBUTION));
url = url.replace(/%DISTRIBUTION_VERSION%/g,
getDistributionPrefValue(PREF_APP_DISTRIBUTION_VERSION));
url = url.replace(/%CUSTOM%/g, Preferences.get(PREF_APP_UPDATE_CUSTOM, ""));
url = url.replace(/\+/g, "%2B");
if (AppConstants.platform == "gonk") {
let sysLibs = {};
Cu.import("resource://gre/modules/systemlibs.js", sysLibs);
let productDevice = sysLibs.libcutils.property_get("ro.product.device");
let buildType = sysLibs.libcutils.property_get("ro.build.type");
url = url.replace(/%PRODUCT_MODEL%/g,
sysLibs.libcutils.property_get("ro.product.model"));
if (buildType == "user" || buildType == "userdebug") {
url = url.replace(/%PRODUCT_DEVICE%/g, productDevice);
} else {
url = url.replace(/%PRODUCT_DEVICE%/g, productDevice + "-" + buildType);
}
url = url.replace(/%B2G_VERSION%/g,
Preferences.get(PREF_APP_B2G_VERSION, null));
url = url.replace(/%IMEI%/g,
Preferences.get(PREF_APP_UPDATE_IMEI_HASH, "default"));
}
return url;
}
};
/* Get the distribution pref values, from defaults only */
function getDistributionPrefValue(aPrefName) {
var prefValue = "default";
try {
prefValue = Services.prefs.getDefaultBranch(null).getCharPref(aPrefName);
} catch (e) {
// use default when pref not found
}
return prefValue;
}
/**
* Gets the locale from the update.locale file for replacing %LOCALE% in the
* update url. The update.locale file can be located in the application
* directory or the GRE directory with preference given to it being located in
* the application directory.
*/
XPCOMUtils.defineLazyGetter(UpdateUtils, "Locale", function() {
let channel;
let locale;
for (let res of ['app', 'gre']) {
channel = Services.io.newChannel2("resource://" + res + "/" + FILE_UPDATE_LOCALE,
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_INTERNAL_XMLHTTPREQUEST);
try {
let inputStream = channel.open();
locale = NetUtil.readInputStreamToString(inputStream, inputStream.available());
} catch(e) {}
if (locale)
return locale.trim();
}
Cu.reportError(FILE_UPDATE_LOCALE + " file doesn't exist in either the " +
"application or GRE directories");
return null;
});
/* Windows only getter that returns the processor architecture. */
XPCOMUtils.defineLazyGetter(this, "gWinCPUArch", function aus_gWinCPUArch() {
// Get processor architecture
let arch = "unknown";
const WORD = ctypes.uint16_t;
const DWORD = ctypes.uint32_t;
// This structure is described at:
// http://msdn.microsoft.com/en-us/library/ms724958%28v=vs.85%29.aspx
const SYSTEM_INFO = new ctypes.StructType('SYSTEM_INFO',
[
{wProcessorArchitecture: WORD},
{wReserved: WORD},
{dwPageSize: DWORD},
{lpMinimumApplicationAddress: ctypes.voidptr_t},
{lpMaximumApplicationAddress: ctypes.voidptr_t},
{dwActiveProcessorMask: DWORD.ptr},
{dwNumberOfProcessors: DWORD},
{dwProcessorType: DWORD},
{dwAllocationGranularity: DWORD},
{wProcessorLevel: WORD},
{wProcessorRevision: WORD}
]);
let kernel32 = false;
try {
kernel32 = ctypes.open("Kernel32");
} catch (e) {
Cu.reportError("Unable to open kernel32! Exception: " + e);
}
if (kernel32) {
try {
let GetNativeSystemInfo = kernel32.declare("GetNativeSystemInfo",
ctypes.default_abi,
ctypes.void_t,
SYSTEM_INFO.ptr);
let winSystemInfo = SYSTEM_INFO();
// Default to unknown
winSystemInfo.wProcessorArchitecture = 0xffff;
GetNativeSystemInfo(winSystemInfo.address());
switch (winSystemInfo.wProcessorArchitecture) {
case 9:
arch = "x64";
break;
case 6:
arch = "IA64";
break;
case 0:
arch = "x86";
break;
}
} catch (e) {
Cu.reportError("Error getting processor architecture. " +
"Exception: " + e);
} finally {
kernel32.close();
}
}
return arch;
});
XPCOMUtils.defineLazyGetter(UpdateUtils, "ABI", function() {
let abi = null;
try {
abi = Services.appinfo.XPCOMABI;
}
catch (e) {
Cu.reportError("XPCOM ABI unknown");
}
if (AppConstants.platform == "macosx") {
// Mac universal build should report a different ABI than either macppc
// or mactel.
let macutils = Cc["@mozilla.org/xpcom/mac-utils;1"].
getService(Ci.nsIMacUtils);
if (macutils.isUniversalBinary) {
abi += "-u-" + macutils.architecturesInBinary;
}
} else if (AppConstants.platform == "win") {
// Windows build should report the CPU architecture that it's running on.
abi += "-" + gWinCPUArch;
}
return abi;
});
XPCOMUtils.defineLazyGetter(UpdateUtils, "OSVersion", function() {
let osVersion;
try {
osVersion = Services.sysinfo.getProperty("name") + " " +
Services.sysinfo.getProperty("version");
}
catch (e) {
Cu.reportError("OS Version unknown.");
}
if (osVersion) {
if (AppConstants.platform == "win") {
const BYTE = ctypes.uint8_t;
const WORD = ctypes.uint16_t;
const DWORD = ctypes.uint32_t;
const WCHAR = ctypes.char16_t;
const BOOL = ctypes.int;
// This structure is described at:
// http://msdn.microsoft.com/en-us/library/ms724833%28v=vs.85%29.aspx
const SZCSDVERSIONLENGTH = 128;
const OSVERSIONINFOEXW = new ctypes.StructType('OSVERSIONINFOEXW',
[
{dwOSVersionInfoSize: DWORD},
{dwMajorVersion: DWORD},
{dwMinorVersion: DWORD},
{dwBuildNumber: DWORD},
{dwPlatformId: DWORD},
{szCSDVersion: ctypes.ArrayType(WCHAR, SZCSDVERSIONLENGTH)},
{wServicePackMajor: WORD},
{wServicePackMinor: WORD},
{wSuiteMask: WORD},
{wProductType: BYTE},
{wReserved: BYTE}
]);
// This structure is described at:
// http://msdn.microsoft.com/en-us/library/ms724958%28v=vs.85%29.aspx
const SYSTEM_INFO = new ctypes.StructType('SYSTEM_INFO',
[
{wProcessorArchitecture: WORD},
{wReserved: WORD},
{dwPageSize: DWORD},
{lpMinimumApplicationAddress: ctypes.voidptr_t},
{lpMaximumApplicationAddress: ctypes.voidptr_t},
{dwActiveProcessorMask: DWORD.ptr},
{dwNumberOfProcessors: DWORD},
{dwProcessorType: DWORD},
{dwAllocationGranularity: DWORD},
{wProcessorLevel: WORD},
{wProcessorRevision: WORD}
]);
let kernel32 = false;
try {
kernel32 = ctypes.open("Kernel32");
} catch (e) {
Cu.reportError("Unable to open kernel32! " + e);
osVersion += ".unknown (unknown)";
}
if (kernel32) {
try {
// Get Service pack info
try {
let GetVersionEx = kernel32.declare("GetVersionExW",
ctypes.default_abi,
BOOL,
OSVERSIONINFOEXW.ptr);
let winVer = OSVERSIONINFOEXW();
winVer.dwOSVersionInfoSize = OSVERSIONINFOEXW.size;
if(0 !== GetVersionEx(winVer.address())) {
osVersion += "." + winVer.wServicePackMajor +
"." + winVer.wServicePackMinor;
} else {
Cu.reportError("Unknown failure in GetVersionEX (returned 0)");
osVersion += ".unknown";
}
} catch (e) {
Cu.reportError("Error getting service pack information. Exception: " + e);
osVersion += ".unknown";
}
} finally {
kernel32.close();
}
// Add processor architecture
osVersion += " (" + gWinCPUArch + ")";
}
}
try {
osVersion += " (" + Services.sysinfo.getProperty("secondaryLibrary") + ")";
}
catch (e) {
// Not all platforms have a secondary widget library, so an error is nothing to worry about.
}
osVersion = encodeURIComponent(osVersion);
}
return osVersion;
});

View File

@ -75,7 +75,7 @@ EXTRA_JS_MODULES += [
'TelemetryTimestamps.jsm',
'Timer.jsm',
'Troubleshoot.jsm',
'UpdateChannel.jsm',
'UpdateUtils.jsm',
'WebChannel.jsm',
'WindowDraggingUtils.jsm',
'ZipUtils.jsm',

View File

@ -11,6 +11,7 @@ Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://testing-common/httpd.js");
Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/Preferences.jsm")
Cu.import("resource://gre/modules/UpdateUtils.jsm");
do_get_profile();
@ -490,7 +491,7 @@ function* test_checkForAddons_installAddon(id, includeSize, wantInstallReject) {
"1.1");
do_check_eq(GMPScope.GMPPrefs.get(GMPScope.GMPPrefs.KEY_PLUGIN_ABI, "",
gmpAddon.id),
GMPScope.GMPUtils.ABI());
UpdateUtils.ABI);
// Make sure it reports as being installed
do_check_true(gmpAddon.isInstalled);

View File

@ -3,8 +3,10 @@
* 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/. */
Components.utils.import("resource://gre/modules/Preferences.jsm");
Components.utils.import("resource://gre/modules/UpdateChannel.jsm");
const { utils: Cu } = Components;
Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/UpdateUtils.jsm");
const PREF_APP_UPDATE_CHANNEL = "app.update.channel";
const TEST_CHANNEL = "TestChannel";
@ -13,24 +15,24 @@ const TEST_PARTNER_A = "TestPartnerA";
const PREF_PARTNER_B = "app.partner.test_partner_b";
const TEST_PARTNER_B = "TestPartnerB";
function test_get() {
add_task(function* test_updatechannel() {
let defaultPrefs = new Preferences({ defaultBranch: true });
let currentChannel = defaultPrefs.get(PREF_APP_UPDATE_CHANNEL);
do_check_eq(UpdateChannel.get(), currentChannel);
do_check_eq(UpdateChannel.get(false), currentChannel);
do_check_eq(UpdateUtils.UpdateChannel, currentChannel);
do_check_eq(UpdateUtils.getUpdateChannel(true), currentChannel);
do_check_eq(UpdateUtils.getUpdateChannel(false), currentChannel);
defaultPrefs.set(PREF_APP_UPDATE_CHANNEL, TEST_CHANNEL);
do_check_eq(UpdateChannel.get(), TEST_CHANNEL);
do_check_eq(UpdateChannel.get(false), TEST_CHANNEL);
do_check_eq(UpdateUtils.UpdateChannel, TEST_CHANNEL);
do_check_eq(UpdateUtils.getUpdateChannel(true), TEST_CHANNEL);
do_check_eq(UpdateUtils.getUpdateChannel(false), TEST_CHANNEL);
defaultPrefs.set(PREF_PARTNER_A, TEST_PARTNER_A);
defaultPrefs.set(PREF_PARTNER_B, TEST_PARTNER_B);
do_check_eq(UpdateChannel.get(),
do_check_eq(UpdateUtils.UpdateChannel,
TEST_CHANNEL + "-cck-" + TEST_PARTNER_A + "-" + TEST_PARTNER_B);
do_check_eq(UpdateChannel.get(false), TEST_CHANNEL);
}
function run_test() {
test_get();
}
do_check_eq(UpdateUtils.getUpdateChannel(true),
TEST_CHANNEL + "-cck-" + TEST_PARTNER_A + "-" + TEST_PARTNER_B);
do_check_eq(UpdateUtils.getUpdateChannel(false), TEST_CHANNEL);
});

View File

@ -0,0 +1,292 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* 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/. */
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/UpdateUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm");
Cu.import("resource://testing-common/AppInfo.jsm");
Cu.import("resource://gre/modules/ctypes.jsm");
const PREF_APP_UPDATE_CHANNEL = "app.update.channel";
const PREF_APP_PARTNER_BRANCH = "app.partner.";
const PREF_DISTRIBUTION_ID = "distribution.id";
const PREF_DISTRIBUTION_VERSION = "distribution.version";
const URL_PREFIX = "http://localhost/";
const MSG_SHOULD_EQUAL = " should equal the expected value";
updateAppInfo();
const gAppInfo = getAppInfo();
const gDefaultPrefBranch = Services.prefs.getDefaultBranch(null);
function setUpdateChannel(aChannel) {
gDefaultPrefBranch.setCharPref(PREF_APP_UPDATE_CHANNEL, aChannel);
}
function getServicePack() {
// NOTE: This function is a helper function and not a test. Thus,
// it uses throw() instead of do_throw(). Any tests that use this function
// should catch exceptions thrown in this function and deal with them
// appropriately (usually by calling do_throw).
const BYTE = ctypes.uint8_t;
const WORD = ctypes.uint16_t;
const DWORD = ctypes.uint32_t;
const WCHAR = ctypes.char16_t;
const BOOL = ctypes.int;
// This structure is described at:
// http://msdn.microsoft.com/en-us/library/ms724833%28v=vs.85%29.aspx
const SZCSDVERSIONLENGTH = 128;
const OSVERSIONINFOEXW = new ctypes.StructType('OSVERSIONINFOEXW',
[
{dwOSVersionInfoSize: DWORD},
{dwMajorVersion: DWORD},
{dwMinorVersion: DWORD},
{dwBuildNumber: DWORD},
{dwPlatformId: DWORD},
{szCSDVersion: ctypes.ArrayType(WCHAR, SZCSDVERSIONLENGTH)},
{wServicePackMajor: WORD},
{wServicePackMinor: WORD},
{wSuiteMask: WORD},
{wProductType: BYTE},
{wReserved: BYTE}
]);
let kernel32 = ctypes.open("kernel32");
try {
let GetVersionEx = kernel32.declare("GetVersionExW",
ctypes.default_abi,
BOOL,
OSVERSIONINFOEXW.ptr);
let winVer = OSVERSIONINFOEXW();
winVer.dwOSVersionInfoSize = OSVERSIONINFOEXW.size;
if (0 === GetVersionEx(winVer.address())) {
// Using "throw" instead of "do_throw" (see NOTE above)
throw("Failure in GetVersionEx (returned 0)");
}
return winVer.wServicePackMajor + "." + winVer.wServicePackMinor;
} finally {
kernel32.close();
}
}
function getProcArchitecture() {
// NOTE: This function is a helper function and not a test. Thus,
// it uses throw() instead of do_throw(). Any tests that use this function
// should catch exceptions thrown in this function and deal with them
// appropriately (usually by calling do_throw).
const WORD = ctypes.uint16_t;
const DWORD = ctypes.uint32_t;
// This structure is described at:
// http://msdn.microsoft.com/en-us/library/ms724958%28v=vs.85%29.aspx
const SYSTEM_INFO = new ctypes.StructType('SYSTEM_INFO',
[
{wProcessorArchitecture: WORD},
{wReserved: WORD},
{dwPageSize: DWORD},
{lpMinimumApplicationAddress: ctypes.voidptr_t},
{lpMaximumApplicationAddress: ctypes.voidptr_t},
{dwActiveProcessorMask: DWORD.ptr},
{dwNumberOfProcessors: DWORD},
{dwProcessorType: DWORD},
{dwAllocationGranularity: DWORD},
{wProcessorLevel: WORD},
{wProcessorRevision: WORD}
]);
let kernel32 = ctypes.open("kernel32");
try {
let GetNativeSystemInfo = kernel32.declare("GetNativeSystemInfo",
ctypes.default_abi,
ctypes.void_t,
SYSTEM_INFO.ptr);
let sysInfo = SYSTEM_INFO();
// Default to unknown
sysInfo.wProcessorArchitecture = 0xffff;
GetNativeSystemInfo(sysInfo.address());
switch(sysInfo.wProcessorArchitecture) {
case 9:
return "x64";
case 6:
return "IA64";
case 0:
return "x86";
default:
// Using "throw" instead of "do_throw" (see NOTE above)
throw("Unknown architecture returned from GetNativeSystemInfo: " + sysInfo.wProcessorArchitecture);
}
} finally {
kernel32.close();
}
}
// Helper function for formatting a url and getting the result we're
// interested in
function getResult(url) {
url = UpdateUtils.formatUpdateURL(url);
return url.substr(URL_PREFIX.length).split("/")[0];
}
// url constructed with %PRODUCT%
add_task(function* test_product() {
let url = URL_PREFIX + "%PRODUCT%/";
Assert.equal(getResult(url), gAppInfo.name,
"the url param for %PRODUCT%" + MSG_SHOULD_EQUAL);
});
// url constructed with %VERSION%
add_task(function* test_version() {
let url = URL_PREFIX + "%VERSION%/";
Assert.equal(getResult(url), gAppInfo.version,
"the url param for %VERSION%" + MSG_SHOULD_EQUAL);
});
// url constructed with %BUILD_ID%
add_task(function* test_build_id() {
let url = URL_PREFIX + "%BUILD_ID%/";
Assert.equal(getResult(url), gAppInfo.appBuildID,
"the url param for %BUILD_ID%" + MSG_SHOULD_EQUAL);
});
// url constructed with %BUILD_TARGET%
// XXX TODO - it might be nice if we tested the actual ABI
add_task(function* test_build_target() {
let url = URL_PREFIX + "%BUILD_TARGET%/";
let abi;
try {
abi = gAppInfo.XPCOMABI;
} catch (e) {
do_throw("nsIXULAppInfo:XPCOMABI not defined\n");
}
if (AppConstants.platform == "macosx") {
// Mac universal build should report a different ABI than either macppc
// or mactel. This is necessary since nsUpdateService.js will set the ABI to
// Universal-gcc3 for Mac universal builds.
let macutils = Cc["@mozilla.org/xpcom/mac-utils;1"].
getService(Ci.nsIMacUtils);
if (macutils.isUniversalBinary) {
abi += "-u-" + macutils.architecturesInBinary;
}
} else if (AppConstants.platform == "win") {
// Windows build should report the CPU architecture that it's running on.
abi += "-" + getProcArchitecture();
}
Assert.equal(getResult(url), gAppInfo.OS + "_" + abi,
"the url param for %BUILD_TARGET%" + MSG_SHOULD_EQUAL);
});
// url constructed with %LOCALE%
// Bug 488936 added the update.locale file that stores the update locale
add_task(function* test_locale() {
// The code that gets the locale accesses the profile which is only available
// after calling do_get_profile in xpcshell tests. This prevents an error from
// being logged.
do_get_profile();
let url = URL_PREFIX + "%LOCALE%/";
Assert.equal(getResult(url), AppConstants.INSTALL_LOCALE,
"the url param for %LOCALE%" + MSG_SHOULD_EQUAL);
});
// url constructed with %CHANNEL%
add_task(function* test_channel() {
let url = URL_PREFIX + "%CHANNEL%/";
setUpdateChannel("test_channel");
Assert.equal(getResult(url), "test_channel",
"the url param for %CHANNEL%" + MSG_SHOULD_EQUAL);
});
// url constructed with %CHANNEL% with distribution partners
add_task(function* test_channel_distribution() {
let url = URL_PREFIX + "%CHANNEL%/";
gDefaultPrefBranch.setCharPref(PREF_APP_PARTNER_BRANCH + "test_partner1",
"test_partner1");
gDefaultPrefBranch.setCharPref(PREF_APP_PARTNER_BRANCH + "test_partner2",
"test_partner2");
Assert.equal(getResult(url),
"test_channel-cck-test_partner1-test_partner2",
"the url param for %CHANNEL%" + MSG_SHOULD_EQUAL);
});
// url constructed with %PLATFORM_VERSION%
add_task(function* test_platform_version() {
let url = URL_PREFIX + "%PLATFORM_VERSION%/";
Assert.equal(getResult(url), gAppInfo.platformVersion,
"the url param for %PLATFORM_VERSION%" + MSG_SHOULD_EQUAL);
});
// url constructed with %OS_VERSION%
add_task(function* test_os_version() {
let url = URL_PREFIX + "%OS_VERSION%/";
let osVersion;
let sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2);
osVersion = sysInfo.getProperty("name") + " " + sysInfo.getProperty("version");
if (AppConstants.platform == "win") {
try {
let servicePack = getServicePack();
osVersion += "." + servicePack;
} catch (e) {
do_throw("Failure obtaining service pack: " + e);
}
if ("5.0" === sysInfo.getProperty("version")) { // Win2K
osVersion += " (unknown)";
} else {
try {
osVersion += " (" + getProcArchitecture() + ")";
} catch (e) {
do_throw("Failed to obtain processor architecture: " + e);
}
}
}
if (osVersion) {
try {
osVersion += " (" + sysInfo.getProperty("secondaryLibrary") + ")";
} catch (e) {
// Not all platforms have a secondary widget library, so an error is
// nothing to worry about.
}
osVersion = encodeURIComponent(osVersion);
}
Assert.equal(getResult(url), osVersion,
"the url param for %OS_VERSION%" + MSG_SHOULD_EQUAL);
});
// url constructed with %DISTRIBUTION%
add_task(function* test_distribution() {
let url = URL_PREFIX + "%DISTRIBUTION%/";
gDefaultPrefBranch.setCharPref(PREF_DISTRIBUTION_ID, "test_distro");
Assert.equal(getResult(url), "test_distro",
"the url param for %DISTRIBUTION%" + MSG_SHOULD_EQUAL);
});
// url constructed with %DISTRIBUTION_VERSION%
add_task(function* test_distribution_version() {
let url = URL_PREFIX + "%DISTRIBUTION_VERSION%/";
gDefaultPrefBranch.setCharPref(PREF_DISTRIBUTION_VERSION, "test_distro_version");
Assert.equal(getResult(url), "test_distro_version",
"the url param for %DISTRIBUTION_VERSION%" + MSG_SHOULD_EQUAL);
});
add_task(function* test_custom() {
Services.prefs.setCharPref("app.update.custom", "custom");
let url = URL_PREFIX + "%CUSTOM%/";
Assert.equal(getResult(url), "custom",
"the url query string for %CUSTOM%" + MSG_SHOULD_EQUAL);
});

View File

@ -57,6 +57,8 @@ skip-if = toolkit == 'android'
skip-if = toolkit == 'android'
[test_timer.js]
skip-if = toolkit == 'android'
[test_UpdateUtils_url.js]
[test_UpdateUtils_updatechannel.js]
[test_web_channel.js]
[test_web_channel_broker.js]
[test_ZipUtils.js]

View File

@ -19,6 +19,7 @@ Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/GMPUtils.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm");
Cu.import("resource://gre/modules/UpdateUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(
this, "GMPInstallManager", "resource://gre/modules/GMPInstallManager.jsm");
@ -490,8 +491,8 @@ GMPWrapper.prototype = {
return { installed: false, valid: true };
}
let abi = GMPPrefs.get(GMPPrefs.KEY_PLUGIN_ABI, GMPUtils.ABI(), this._plugin.id);
if (abi != GMPUtils.ABI()) {
let abi = GMPPrefs.get(GMPPrefs.KEY_PLUGIN_ABI, UpdateUtils.ABI, this._plugin.id);
if (abi != UpdateUtils.ABI) {
// ABI doesn't match. Possibly this is a profile migrated across platforms
// or from 32 -> 64 bit.
return {

View File

@ -23,8 +23,8 @@ try {
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Task",
@ -559,7 +559,7 @@ Blocklist.prototype = {
dsURI = dsURI.replace(/%BUILD_TARGET%/g, gApp.OS + "_" + gABI);
dsURI = dsURI.replace(/%OS_VERSION%/g, gOSVersion);
dsURI = dsURI.replace(/%LOCALE%/g, getLocale());
dsURI = dsURI.replace(/%CHANNEL%/g, UpdateChannel.get());
dsURI = dsURI.replace(/%CHANNEL%/g, UpdateUtils.UpdateChannel);
dsURI = dsURI.replace(/%PLATFORM_VERSION%/g, gApp.platformVersion);
dsURI = dsURI.replace(/%DISTRIBUTION%/g,
getDistributionPrefValue(PREF_APP_DISTRIBUTION));

View File

@ -6,6 +6,7 @@
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
var GMPScope = Cu.import("resource://gre/modules/addons/GMPProvider.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm");
Cu.import("resource://gre/modules/UpdateUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "pluginsBundle",
() => Services.strings.createBundle("chrome://global/locale/plugins.properties"));
@ -338,7 +339,7 @@ add_task(function* test_pluginRegistration() {
clearPaths();
gPrefs.setCharPref(gGetKey(GMPScope.GMPPrefs.KEY_PLUGIN_VERSION, addon.id),
TEST_VERSION);
gPrefs.setCharPref(gGetKey(GMPScope.GMPPrefs.KEY_PLUGIN_ABI, addon.id), GMPScope.GMPUtils.ABI());
gPrefs.setCharPref(gGetKey(GMPScope.GMPPrefs.KEY_PLUGIN_ABI, addon.id), UpdateUtils.ABI);
yield promiseRestartManager();
Assert.notEqual(addedPaths.indexOf(file.path), -1);
Assert.deepEqual(removedPaths, []);

View File

@ -30,8 +30,6 @@ const PREF_APP_UPDATE_CERT_CHECKATTRS = "app.update.cert.checkAttributes";
const PREF_APP_UPDATE_CERT_ERRORS = "app.update.cert.errors";
const PREF_APP_UPDATE_CERT_MAXERRORS = "app.update.cert.maxErrors";
const PREF_APP_UPDATE_CERT_REQUIREBUILTIN = "app.update.cert.requireBuiltIn";
const PREF_APP_UPDATE_CUSTOM = "app.update.custom";
const PREF_APP_UPDATE_IMEI_HASH = "app.update.imei_hash";
const PREF_APP_UPDATE_ENABLED = "app.update.enabled";
const PREF_APP_UPDATE_IDLETIME = "app.update.idletime";
const PREF_APP_UPDATE_INCOMPATIBLE_MODE = "app.update.incompatible.mode";
@ -54,11 +52,6 @@ const PREF_APP_UPDATE_SERVICE_MAX_ERRORS = "app.update.service.maxErrors";
const PREF_APP_UPDATE_SOCKET_ERRORS = "app.update.socket.maxErrors";
const PREF_APP_UPDATE_RETRY_TIMEOUT = "app.update.socket.retryTimeout";
const PREF_APP_DISTRIBUTION = "distribution.id";
const PREF_APP_DISTRIBUTION_VERSION = "distribution.version";
const PREF_APP_B2G_VERSION = "b2g.version";
const PREF_EM_HOTFIX_ID = "extensions.hotfix.id";
const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul";
@ -87,7 +80,6 @@ const FILE_UPDATE_ACTIVE = "active-update.xml";
const FILE_PERMS_TEST = "update.test";
const FILE_LAST_LOG = "last-update.log";
const FILE_BACKUP_LOG = "backup-update.log";
const FILE_UPDATE_LOCALE = "update.locale";
const STATE_NONE = "null";
const STATE_DOWNLOADING = "downloading";
@ -210,8 +202,8 @@ XPCOMUtils.defineLazyGetter(this, "gExtStorage", function aus_gExtStorage() {
return Services.env.get("EXTERNAL_STORAGE");
});
XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
"resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
"resource://gre/modules/UpdateUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "gLogEnabled", function aus_gLogEnabled() {
return getPref("getBoolPref", PREF_APP_UPDATE_LOG, false);
@ -228,199 +220,6 @@ XPCOMUtils.defineLazyGetter(this, "gCertUtils", function aus_gCertUtils() {
return temp;
});
XPCOMUtils.defineLazyGetter(this, "gABI", function aus_gABI() {
let abi = null;
try {
abi = Services.appinfo.XPCOMABI;
}
catch (e) {
LOG("gABI - XPCOM ABI unknown: updates are not possible.");
}
if (AppConstants.platform == "macosx") {
// Mac universal build should report a different ABI than either macppc
// or mactel.
let macutils = Cc["@mozilla.org/xpcom/mac-utils;1"].
getService(Ci.nsIMacUtils);
if (macutils.isUniversalBinary) {
abi += "-u-" + macutils.architecturesInBinary;
}
} else if (AppConstants.platform == "win") {
// Windows build should report the CPU architecture that it's running on.
abi += "-" + gWinCPUArch;
}
return abi;
});
XPCOMUtils.defineLazyGetter(this, "gOSVersion", function aus_gOSVersion() {
let osVersion;
try {
osVersion = Services.sysinfo.getProperty("name") + " " +
Services.sysinfo.getProperty("version");
}
catch (e) {
LOG("gOSVersion - OS Version unknown: updates are not possible.");
}
if (osVersion) {
if (AppConstants.platform == "win") {
const BYTE = ctypes.uint8_t;
const WORD = ctypes.uint16_t;
const DWORD = ctypes.uint32_t;
const WCHAR = ctypes.char16_t;
const BOOL = ctypes.int;
// This structure is described at:
// http://msdn.microsoft.com/en-us/library/ms724833%28v=vs.85%29.aspx
const SZCSDVERSIONLENGTH = 128;
const OSVERSIONINFOEXW = new ctypes.StructType('OSVERSIONINFOEXW',
[
{dwOSVersionInfoSize: DWORD},
{dwMajorVersion: DWORD},
{dwMinorVersion: DWORD},
{dwBuildNumber: DWORD},
{dwPlatformId: DWORD},
{szCSDVersion: ctypes.ArrayType(WCHAR, SZCSDVERSIONLENGTH)},
{wServicePackMajor: WORD},
{wServicePackMinor: WORD},
{wSuiteMask: WORD},
{wProductType: BYTE},
{wReserved: BYTE}
]);
// This structure is described at:
// http://msdn.microsoft.com/en-us/library/ms724958%28v=vs.85%29.aspx
const SYSTEM_INFO = new ctypes.StructType('SYSTEM_INFO',
[
{wProcessorArchitecture: WORD},
{wReserved: WORD},
{dwPageSize: DWORD},
{lpMinimumApplicationAddress: ctypes.voidptr_t},
{lpMaximumApplicationAddress: ctypes.voidptr_t},
{dwActiveProcessorMask: DWORD.ptr},
{dwNumberOfProcessors: DWORD},
{dwProcessorType: DWORD},
{dwAllocationGranularity: DWORD},
{wProcessorLevel: WORD},
{wProcessorRevision: WORD}
]);
let kernel32 = false;
try {
kernel32 = ctypes.open("Kernel32");
} catch (e) {
LOG("gOSVersion - Unable to open kernel32! " + e);
osVersion += ".unknown (unknown)";
}
if (kernel32) {
try {
// Get Service pack info
try {
let GetVersionEx = kernel32.declare("GetVersionExW",
ctypes.default_abi,
BOOL,
OSVERSIONINFOEXW.ptr);
let winVer = OSVERSIONINFOEXW();
winVer.dwOSVersionInfoSize = OSVERSIONINFOEXW.size;
if(0 !== GetVersionEx(winVer.address())) {
osVersion += "." + winVer.wServicePackMajor +
"." + winVer.wServicePackMinor;
} else {
LOG("gOSVersion - Unknown failure in GetVersionEX (returned 0)");
osVersion += ".unknown";
}
} catch (e) {
LOG("gOSVersion - error getting service pack information. Exception: " + e);
osVersion += ".unknown";
}
} finally {
kernel32.close();
}
// Add processor architecture
osVersion += " (" + gWinCPUArch + ")";
}
}
try {
osVersion += " (" + Services.sysinfo.getProperty("secondaryLibrary") + ")";
}
catch (e) {
// Not all platforms have a secondary widget library, so an error is nothing to worry about.
}
osVersion = encodeURIComponent(osVersion);
}
return osVersion;
});
/* Windows only getter that returns the processor architecture. */
XPCOMUtils.defineLazyGetter(this, "gWinCPUArch", function aus_gWinCPUArch() {
// Get processor architecture
let arch = "unknown";
const WORD = ctypes.uint16_t;
const DWORD = ctypes.uint32_t;
// This structure is described at:
// http://msdn.microsoft.com/en-us/library/ms724958%28v=vs.85%29.aspx
const SYSTEM_INFO = new ctypes.StructType('SYSTEM_INFO',
[
{wProcessorArchitecture: WORD},
{wReserved: WORD},
{dwPageSize: DWORD},
{lpMinimumApplicationAddress: ctypes.voidptr_t},
{lpMaximumApplicationAddress: ctypes.voidptr_t},
{dwActiveProcessorMask: DWORD.ptr},
{dwNumberOfProcessors: DWORD},
{dwProcessorType: DWORD},
{dwAllocationGranularity: DWORD},
{wProcessorLevel: WORD},
{wProcessorRevision: WORD}
]);
let kernel32 = false;
try {
kernel32 = ctypes.open("Kernel32");
} catch (e) {
LOG("gWinCPUArch - Unable to open kernel32! Exception: " + e);
}
if (kernel32) {
try {
let GetNativeSystemInfo = kernel32.declare("GetNativeSystemInfo",
ctypes.default_abi,
ctypes.void_t,
SYSTEM_INFO.ptr);
let winSystemInfo = SYSTEM_INFO();
// Default to unknown
winSystemInfo.wProcessorArchitecture = 0xffff;
GetNativeSystemInfo(winSystemInfo.address());
switch (winSystemInfo.wProcessorArchitecture) {
case 9:
arch = "x64";
break;
case 6:
arch = "IA64";
break;
case 0:
arch = "x86";
break;
}
} catch (e) {
LOG("gWinCPUArch - error getting processor architecture. " +
"Exception: " + e);
} finally {
kernel32.close();
}
}
return arch;
});
/**
* Tests to make sure that we can write to a given directory.
*
@ -727,13 +526,13 @@ XPCOMUtils.defineLazyGetter(this, "gCanCheckForUpdates", function aus_gCanCheckF
}
// If we don't know the binary platform we're updating, we can't update.
if (!gABI) {
if (!UpdateUtils.ABI) {
LOG("gCanCheckForUpdates - unable to check for updates, unknown ABI");
return false;
}
// If we don't know the OS version we're updating, we can't update.
if (!gOSVersion) {
if (!UpdateUtils.OSVersion) {
LOG("gCanCheckForUpdates - unable to check for updates, unknown OS " +
"version");
return false;
@ -1242,58 +1041,6 @@ function cleanupActiveUpdate() {
cleanUpUpdatesDir();
}
/**
* Gets the locale from the update.locale file for replacing %LOCALE% in the
* update url. The update.locale file can be located in the application
* directory or the GRE directory with preference given to it being located in
* the application directory.
*/
function getLocale() {
if (gLocale) {
return gLocale;
}
let channel;
for (let res of ['app', 'gre']) {
channel = Services.io.newChannel2("resource://" + res + "/" + FILE_UPDATE_LOCALE,
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_INTERNAL_XMLHTTPREQUEST);
try {
var inputStream = channel.open();
gLocale = readStringFromInputStream(inputStream);
} catch(e) {}
if (gLocale)
break;
}
if (!gLocale)
throw Components.Exception(FILE_UPDATE_LOCALE + " file doesn't exist in " +
"either the application or GRE directories",
Cr.NS_ERROR_FILE_NOT_FOUND);
LOG("getLocale - getting locale from file: " + channel.originalURI.spec +
", locale: " + gLocale);
return gLocale;
}
/* Get the distribution pref values, from defaults only */
function getDistributionPrefValue(aPrefName) {
var prefValue = "default";
try {
prefValue = Services.prefs.getDefaultBranch(null).getCharPref(aPrefName);
} catch (e) {
// use default when pref not found
}
return prefValue;
}
/**
* An enumeration of items in a JS array.
* @constructor
@ -2527,9 +2274,9 @@ UpdateService.prototype = {
}
// The following checks are done here so they can be differentiated from
// foreground checks.
if (!gOSVersion) {
if (!UpdateUtils.OSVersion) {
AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_NO_OS_VERSION);
} else if (!gABI) {
} else if (!UpdateUtils.ABI) {
AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_NO_OS_ABI);
} else if (!validUpdateURL) {
if (overridePrefHasValue) {
@ -3271,14 +3018,14 @@ UpdateManager.prototype = {
*/
get activeUpdate() {
if (this._activeUpdate &&
this._activeUpdate.channel != UpdateChannel.get()) {
this._activeUpdate.channel != UpdateUtils.UpdateChannel) {
LOG("UpdateManager:get activeUpdate - channel has changed, " +
"reloading default preferences to workaround bug 802022");
// Workaround to get distribution preferences loaded (Bug 774618). This
// can be removed after bug 802022 is fixed.
let prefSvc = Services.prefs.QueryInterface(Ci.nsIObserver);
prefSvc.observe(null, "reload-default-prefs", null);
if (this._activeUpdate.channel != UpdateChannel.get()) {
if (this._activeUpdate.channel != UpdateUtils.UpdateChannel) {
// User switched channels, clear out any old active updates and remove
// partial downloads
this._activeUpdate = null;
@ -3516,40 +3263,7 @@ Checker.prototype = {
return null;
}
url = url.replace(/%PRODUCT%/g, Services.appinfo.name);
url = url.replace(/%VERSION%/g, Services.appinfo.version);
url = url.replace(/%BUILD_ID%/g, Services.appinfo.appBuildID);
url = url.replace(/%BUILD_TARGET%/g, Services.appinfo.OS + "_" + gABI);
url = url.replace(/%OS_VERSION%/g, gOSVersion);
if (/%LOCALE%/.test(url)) {
url = url.replace(/%LOCALE%/g, getLocale());
}
url = url.replace(/%CHANNEL%/g, UpdateChannel.get());
url = url.replace(/%PLATFORM_VERSION%/g, Services.appinfo.platformVersion);
url = url.replace(/%DISTRIBUTION%/g,
getDistributionPrefValue(PREF_APP_DISTRIBUTION));
url = url.replace(/%DISTRIBUTION_VERSION%/g,
getDistributionPrefValue(PREF_APP_DISTRIBUTION_VERSION));
url = url.replace(/%CUSTOM%/g, getPref("getCharPref", PREF_APP_UPDATE_CUSTOM, ""));
url = url.replace(/\+/g, "%2B");
if (AppConstants.platform == "gonk") {
let sysLibs = {};
Cu.import("resource://gre/modules/systemlibs.js", sysLibs);
let productDevice = sysLibs.libcutils.property_get("ro.product.device");
let buildType = sysLibs.libcutils.property_get("ro.build.type");
url = url.replace(/%PRODUCT_MODEL%/g,
sysLibs.libcutils.property_get("ro.product.model"));
if (buildType == "user" || buildType == "userdebug") {
url = url.replace(/%PRODUCT_DEVICE%/g, productDevice);
} else {
url = url.replace(/%PRODUCT_DEVICE%/g, productDevice + "-" + buildType);
}
url = url.replace(/%B2G_VERSION%/g,
getPref("getCharPref", PREF_APP_B2G_VERSION, null));
url = url.replace(/%IMEI%/g,
getPref("getCharPref", PREF_APP_UPDATE_IMEI_HASH, "default"));
}
url = UpdateUtils.formatUpdateURL(url);
if (force) {
url += (url.indexOf("?") != -1 ? "&" : "?") + "force=1";
@ -3641,7 +3355,7 @@ Checker.prototype = {
continue;
}
update.serviceURL = this.getUpdateURL(this._forced);
update.channel = UpdateChannel.get();
update.channel = UpdateUtils.UpdateChannel;
updates.push(update);
}