Skip to content
This repository has been archived by the owner on Aug 1, 2024. It is now read-only.

Commit

Permalink
RELNOTES[NEW]: Add browser.loadFullVersions. Additionally, remove an …
Browse files Browse the repository at this point in the history
…assumption that fullVersionList will be available in a particular future version of Chrome.

Adding loadFullVersions allows browser full versions to be loaded separately from when they are retrieved, which notably makes it possible to load full versions without having to first identify the browser.

Removing the Chrome version check effectively disables getting a full version from userAgentData, which also makes loadFullVersions a no-op. However, it is still useful because users can integrate loadFullVersions into their codebase today, and get the benefits of fullVersionList in the future.

PiperOrigin-RevId: 408933626
Change-Id: I56fac1fb5b7afc326b5f739fca643c112e608d63
  • Loading branch information
kjin authored and copybara-github committed Nov 10, 2021
1 parent 2870103 commit 57beea4
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 10 deletions.
31 changes: 21 additions & 10 deletions closure/goog/labs/useragent/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const googAsserts = goog.require('goog.asserts');
const util = goog.require('goog.labs.userAgent.util');
const {AsyncValue, Version} = goog.require('goog.labs.userAgent.highEntropy.highEntropyValue');
const {compareVersions} = goog.require('goog.string.internal');
const {fullVersionList} = goog.require('goog.labs.userAgent.highEntropy.highEntropyData');
const {fullVersionList, hasFullVersionList} = goog.require('goog.labs.userAgent.highEntropy.highEntropyData');

// TODO(nnaze): Refactor to remove excessive exclusion logic in matching
// functions.
Expand Down Expand Up @@ -624,6 +624,23 @@ class UserAgentStringFallbackBrandVersion {
}
}

/**
* Requests all full browser versions to be cached. When the returned promise
* resolves, subsequent calls to `fullVersionOf(...).getIfLoaded()` will return
* a value.
*
* This method should be avoided in favor of directly awaiting
* `fullVersionOf(...).load()` where it is used.
*
* @return {!Promise<void>}
*/
async function loadFullVersions() {
if (useUserAgentBrand() && hasFullVersionList()) {
await fullVersionList.load();
}
}
exports.loadFullVersions = loadFullVersions;

/**
* Returns an object that provides access to the full version string of the
* current browser -- or undefined, based on whether the current browser matches
Expand All @@ -636,15 +653,9 @@ class UserAgentStringFallbackBrandVersion {
* undefined if the current browser doesn't match the given brand.
*/
function fullVersionOf(browser) {
// fullVersionList is currently not implemented in Chromium. Therefore, don't
// check fullVersionList until Chromium 101. We choose 101 as a reasonable
// upper bound for when fullVersionList is estimated to have been implemented.
// TODO(user): If fullVersionList is implemented in an earlier version
// of Chromium, lower this value to compare against that major version.
// Additionally, Silk currently does not identify itself in its
// userAgentData.brands array, so if checking its version, always fall back to
// the user agent string.
if (useUserAgentBrand() && !(versionOf(Brand.CHROMIUM) < 101)) {
// Silk currently does not identify itself in its userAgentData.brands array,
// so if checking its version, always fall back to the user agent string.
if (useUserAgentBrand() && hasFullVersionList()) {
const data = util.getUserAgentData();
// Operate under the assumption that the low-entropy and high-entropy lists
// of brand/version pairs contain an identical set of brands. Therefore, if
Expand Down
46 changes: 46 additions & 0 deletions closure/goog/labs/useragent/browser_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ testSuite({
util.setUserAgent('');
util.setUserAgentData(null);
highEntropyData.resetAllForTesting();
highEntropyData.setHasFullVersionListForTesting(false);
},

async testOpera10() {
Expand Down Expand Up @@ -947,6 +948,7 @@ testSuite({
]
});
util.setUserAgentData(userAgentDataWithVersion);
highEntropyData.setHasFullVersionListForTesting(true);

assertBrowser(Browser.CHROME);
assertNonChromeChromiumBrowser(NonChromeChromiumBrowser.OPERA_CHROMIUM);
Expand Down Expand Up @@ -984,6 +986,7 @@ testSuite({
]
});
util.setUserAgentData(userAgentDataWithVersion);
highEntropyData.setHasFullVersionListForTesting(true);

assertBrowser(Browser.CHROME);
assertNonChromeChromiumBrowser(NonChromeChromiumBrowser.EDGE_CHROMIUM);
Expand Down Expand Up @@ -1055,6 +1058,7 @@ testSuite({
testAgentData.CHROME_USERAGENT_DATA,
{fullVersionList: [{brand: 'Chromium', version: '101.0.4472.77'}]});
util.setUserAgentData(userAgentDataWithVersion);
highEntropyData.setHasFullVersionListForTesting(true);

assertBrowser(Browser.CHROME);
assertTrue(userAgentBrowser.isChrome());
Expand Down Expand Up @@ -1105,6 +1109,7 @@ testSuite({

async testChromeUserAgentDataWithRejectedHighEntropyValues() {
util.setUserAgentData(testAgentData.CHROME_USERAGENT_DATA);
highEntropyData.setHasFullVersionListForTesting(true);

const fullChromeVersion =
userAgentBrowser.fullVersionOf(userAgentBrowser.Brand.CHROMIUM);
Expand All @@ -1118,4 +1123,45 @@ testSuite({
userAgentBrowser.Brand.CHROMIUM, '101', '101');
await assertGetVersionStringForLogging(DEFINITELY_NOT_A_BROWSER, '', '');
},

async testChromeUserAgentDataPreloadedFullVersion() {
// Note: The full versions listed here are fictional, made up by bumping
// a legitimate version's major version number by 10 (e.g. 91.* -> 101.*).
const userAgentDataWithVersion = testAgentData.withHighEntropyData(
testAgentData.CHROME_USERAGENT_DATA,
{fullVersionList: [{brand: 'Chromium', version: '101.0.4472.77'}]});
util.setUserAgentData(userAgentDataWithVersion);
highEntropyData.setHasFullVersionListForTesting(true);

const fullChromeVersion =
userAgentBrowser.fullVersionOf(userAgentBrowser.Brand.CHROMIUM);
assertNotNullNorUndefined(fullChromeVersion);
assertEquals(undefined, fullChromeVersion.getIfLoaded());

// Preload the full version list.
await userAgentBrowser.loadFullVersions();
assertEquals(
'101.0.4472.77',
fullChromeVersion.getIfLoaded().toVersionStringForLogging());
},

async testChromeNoFullVersionUserAgentDataPreloadedFullVersion() {
util.setUserAgent(testAgents.CHROME_LINUX_91);
util.setUserAgentData(
testAgentData.CHROME_NO_FULLVERSIONLIST_USERAGENT_DATA);

const fullChromeVersion =
userAgentBrowser.fullVersionOf(userAgentBrowser.Brand.CHROMIUM);
assertNotNullNorUndefined(fullChromeVersion);
assertEquals(
'91.0.4472.77',
fullChromeVersion.getIfLoaded().toVersionStringForLogging());

// Preload the full version list.
await userAgentBrowser.loadFullVersions();
// This should have no effect.
assertEquals(
'91.0.4472.77',
fullChromeVersion.getIfLoaded().toVersionStringForLogging());
},
});
33 changes: 33 additions & 0 deletions closure/goog/labs/useragent/highentropy/highentropydata.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,39 @@ goog.module('goog.labs.userAgent.highEntropy.highEntropyData');

const {HighEntropyValue} = goog.require('goog.labs.userAgent.highEntropy.highEntropyValue');

/**
* fullVersionList is currently not implemented in Chromium.
* TODO(user): When fullVersionList is added, remove this value.
*/
let fullVersionListAvailable = false;

/**
* A helper function to check whether fullVersionList is available in the
* current browser.
* TODO(user): When fullVersionList is added, move hasFullVersionList()
* to browser.js, and inline the browser version check. For example, if it is
* implemented in Chromium 101, have hasFullVersionList simply return
* `browser.versionOf(CHROMIUM) >= 101`.
* @return {boolean}
*/
function hasFullVersionList() {
return fullVersionListAvailable;
}
exports.hasFullVersionList = hasFullVersionList;

/**
* A test-only function to set whether it should be assumed fullVersionList is
* available in the browser.
* TODO(user): When fullVersionList is added, remove this function, as
* behavior when fullVersionList is either present or absent would be testable
* by setting the user agent and user agent data accordingly.
* @param {boolean} value
*/
function setHasFullVersionListForTesting(value) {
fullVersionListAvailable = value;
}
exports.setHasFullVersionListForTesting = setHasFullVersionListForTesting;

/**
* @type {!HighEntropyValue<!Array<!NavigatorUABrandVersion>>}
*/
Expand Down

0 comments on commit 57beea4

Please # to comment.