зеркало из https://github.com/mozilla/gecko-dev.git
155 строки
5.9 KiB
JavaScript
155 строки
5.9 KiB
JavaScript
/* 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/. */
|
|
|
|
"use strict";
|
|
|
|
const { AppConstants } = ChromeUtils.importESModule(
|
|
"resource://gre/modules/AppConstants.sys.mjs"
|
|
);
|
|
|
|
const MS_PER_DAY = 1000 * 60 * 60 * 24;
|
|
|
|
const COMPATIBILITY_STATUS = {
|
|
COMPATIBLE: "compatible",
|
|
TOO_OLD: "too-old",
|
|
TOO_OLD_FENNEC: "too-old-fennec",
|
|
TOO_RECENT: "too-recent",
|
|
};
|
|
exports.COMPATIBILITY_STATUS = COMPATIBILITY_STATUS;
|
|
|
|
function getDateFromBuildID(buildID) {
|
|
// Build IDs are a timestamp in the yyyyMMddHHmmss format.
|
|
// Extract the year, month and day information.
|
|
const fields = buildID.match(/(\d{4})(\d{2})(\d{2})/);
|
|
// Date expects 0 - 11 for months
|
|
const month = Number.parseInt(fields[2], 10) - 1;
|
|
return new Date(fields[1], month, fields[3]);
|
|
}
|
|
|
|
function getMajorVersion(platformVersion) {
|
|
// Retrieve the major platform version, i.e. if we are on Firefox 64.0a1, it will be 64.
|
|
return Number.parseInt(platformVersion.match(/\d+/)[0], 10);
|
|
}
|
|
|
|
/**
|
|
* Compute the minimum and maximum supported version for remote debugging for the provided
|
|
* version of Firefox. Backward compatibility policy for devtools supports at most 2
|
|
* versions older than the current version.
|
|
*
|
|
* @param {String} localVersion
|
|
* The version of the local Firefox instance, eg "67.0"
|
|
* @return {Object}
|
|
* - minVersion {String} the minimum supported version, eg "65.0a1"
|
|
* - maxVersion {String} the first unsupported version, eg "68.0a1"
|
|
*/
|
|
function computeMinMaxVersion(localVersion) {
|
|
// Retrieve the major platform version, i.e. if we are on Firefox 64.0a1, it will be 64.
|
|
const localMajorVersion = getMajorVersion(localVersion);
|
|
|
|
return {
|
|
// Define the minimum officially supported version of Firefox when connecting to a
|
|
// remote runtime. (Use ".0a1" to support the very first nightly version)
|
|
// This matches the release channel's version when we are on nightly,
|
|
// or 2 versions before when we are on other channels.
|
|
minVersion: localMajorVersion - 2 + ".0a1",
|
|
// The maximum version is the first excluded from the support range. That's why we
|
|
// increase the current version by 1 and use ".0a1" to point to the first Nightly.
|
|
// We do not support forward compatibility at all.
|
|
maxVersion: localMajorVersion + 1 + ".0a1",
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Tells if the remote device is using a supported version of Firefox.
|
|
*
|
|
* @param {DevToolsClient} devToolsClient
|
|
* DevToolsClient instance connected to the target remote Firefox.
|
|
* @return Object with the following attributes:
|
|
* * String status, one of COMPATIBILITY_STATUS
|
|
* COMPATIBLE if the runtime is compatible,
|
|
* TOO_RECENT if the runtime uses a too recent version,
|
|
* TOO_OLD if the runtime uses a too old version.
|
|
* * String minVersion
|
|
* The minimum supported version.
|
|
* * String runtimeVersion
|
|
* The remote runtime version.
|
|
* * String localID
|
|
* Build ID of local runtime. A date with like this: YYYYMMDD.
|
|
* * String deviceID
|
|
* Build ID of remote runtime. A date with like this: YYYYMMDD.
|
|
*/
|
|
async function checkVersionCompatibility(devToolsClient) {
|
|
const localDescription = {
|
|
appbuildid: Services.appinfo.appBuildID,
|
|
platformversion: AppConstants.MOZ_APP_VERSION,
|
|
};
|
|
|
|
try {
|
|
const deviceFront = await devToolsClient.mainRoot.getFront("device");
|
|
const description = await deviceFront.getDescription();
|
|
return _compareVersionCompatibility(localDescription, description);
|
|
} catch (e) {
|
|
// If we failed to retrieve the device description, assume we are trying to connect to
|
|
// a really old version of Firefox.
|
|
const localVersion = localDescription.platformversion;
|
|
const { minVersion } = computeMinMaxVersion(localVersion);
|
|
return {
|
|
minVersion,
|
|
runtimeVersion: "<55",
|
|
status: COMPATIBILITY_STATUS.TOO_OLD,
|
|
};
|
|
}
|
|
}
|
|
exports.checkVersionCompatibility = checkVersionCompatibility;
|
|
|
|
function _compareVersionCompatibility(localDescription, deviceDescription) {
|
|
const runtimeID = deviceDescription.appbuildid.substr(0, 8);
|
|
const localID = localDescription.appbuildid.substr(0, 8);
|
|
|
|
const runtimeDate = getDateFromBuildID(runtimeID);
|
|
const localDate = getDateFromBuildID(localID);
|
|
|
|
const runtimeVersion = deviceDescription.platformversion;
|
|
const localVersion = localDescription.platformversion;
|
|
|
|
const { minVersion, maxVersion } = computeMinMaxVersion(localVersion);
|
|
const isTooOld = Services.vc.compare(runtimeVersion, minVersion) < 0;
|
|
const isTooRecent = Services.vc.compare(runtimeVersion, maxVersion) >= 0;
|
|
|
|
const runtimeMajorVersion = getMajorVersion(runtimeVersion);
|
|
const localMajorVersion = getMajorVersion(localVersion);
|
|
const isSameMajorVersion = runtimeMajorVersion === localMajorVersion;
|
|
|
|
let status;
|
|
if (isTooOld) {
|
|
if (runtimeMajorVersion === 68 && deviceDescription.os === "Android") {
|
|
status = COMPATIBILITY_STATUS.TOO_OLD_FENNEC;
|
|
} else {
|
|
status = COMPATIBILITY_STATUS.TOO_OLD;
|
|
}
|
|
} else if (isTooRecent) {
|
|
status = COMPATIBILITY_STATUS.TOO_RECENT;
|
|
} else if (isSameMajorVersion && runtimeDate - localDate > 7 * MS_PER_DAY) {
|
|
// If both local and remote runtimes have the same major version, compare build dates.
|
|
// This check is useful for Gecko developers as we might introduce breaking changes
|
|
// within a Nightly cycle.
|
|
// Still allow devices to be newer by up to a week. This accommodates those with local
|
|
// device builds, since their devices will almost always be newer than the client.
|
|
status = COMPATIBILITY_STATUS.TOO_RECENT;
|
|
} else {
|
|
status = COMPATIBILITY_STATUS.COMPATIBLE;
|
|
}
|
|
|
|
return {
|
|
localID,
|
|
localVersion,
|
|
minVersion,
|
|
runtimeID,
|
|
runtimeVersion,
|
|
status,
|
|
};
|
|
}
|
|
// Exported for tests.
|
|
exports._compareVersionCompatibility = _compareVersionCompatibility;
|