Pier Angelo Vendrame pushed to branch tor-browser-102.9.0esr-12.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
9eac9235
by Pier Angelo Vendrame at 2023-03-20T14:38:14+01:00
-
cfc8f07d
by Pier Angelo Vendrame at 2023-03-20T14:38:23+01:00
-
648dd29f
by Pier Angelo Vendrame at 2023-03-20T14:38:24+01:00
-
e5e872d6
by Kathy Brade at 2023-03-20T14:38:24+01:00
11 changed files:
- browser/components/BrowserContentHandler.jsm
- build/moz.configure/init.configure
- toolkit/modules/UpdateUtils.jsm
- toolkit/mozapps/extensions/AddonManager.jsm
- toolkit/mozapps/update/UpdateService.jsm
- toolkit/mozapps/update/UpdateServiceStub.jsm
- toolkit/mozapps/update/common/updatehelper.cpp
- toolkit/xre/nsAppRunner.cpp
- toolkit/xre/nsUpdateDriver.cpp
- toolkit/xre/nsXREDirProvider.cpp
- tools/update-packaging/make_incremental_update.sh
Changes:
... | ... | @@ -37,7 +37,7 @@ XPCOMUtils.defineLazyGetter(this, "gSystemPrincipal", () => |
37 | 37 | );
|
38 | 38 | XPCOMUtils.defineLazyGlobalGetters(this, [URL]);
|
39 | 39 | |
40 | -const kTBSavedVersionPref =
|
|
40 | +const FORK_VERSION_PREF =
|
|
41 | 41 | "browser.startup.homepage_override.torbrowser.version";
|
42 | 42 | |
43 | 43 | // One-time startup homepage override configurations
|
... | ... | @@ -103,8 +103,8 @@ const OVERRIDE_NEW_BUILD_ID = 3; |
103 | 103 | * Returns:
|
104 | 104 | * OVERRIDE_NEW_PROFILE if this is the first run with a new profile.
|
105 | 105 | * OVERRIDE_NEW_MSTONE if this is the first run with a build with a different
|
106 | - * Gecko milestone or Tor Browser version (i.e. right
|
|
107 | - * after an upgrade).
|
|
106 | + * Gecko milestone or fork version (i.e. right after an
|
|
107 | + * upgrade).
|
|
108 | 108 | * OVERRIDE_NEW_BUILD_ID if this is the first run with a new build ID of the
|
109 | 109 | * same Gecko milestone (i.e. after a nightly upgrade).
|
110 | 110 | * OVERRIDE_NONE otherwise.
|
... | ... | @@ -121,7 +121,7 @@ function needHomepageOverride(prefb) { |
121 | 121 | |
122 | 122 | var mstone = Services.appinfo.platformVersion;
|
123 | 123 | |
124 | - var savedTBVersion = prefb.getCharPref(kTBSavedVersionPref, null);
|
|
124 | + var savedForkVersion = prefb.getCharPref(FORK_VERSION_PREF, null);
|
|
125 | 125 | |
126 | 126 | var savedBuildID = prefb.getCharPref(
|
127 | 127 | "browser.startup.homepage_override.buildID",
|
... | ... | @@ -144,20 +144,13 @@ function needHomepageOverride(prefb) { |
144 | 144 | |
145 | 145 | prefb.setCharPref("browser.startup.homepage_override.mstone", mstone);
|
146 | 146 | prefb.setCharPref("browser.startup.homepage_override.buildID", buildID);
|
147 | - prefb.setCharPref(kTBSavedVersionPref, AppConstants.BASE_BROWSER_VERSION);
|
|
148 | - |
|
149 | - // After an upgrade from an older release of Tor Browser (<= 5.5a1), the
|
|
150 | - // savedmstone will be undefined because those releases included the
|
|
151 | - // value "ignore" for the browser.startup.homepage_override.mstone pref.
|
|
152 | - // To correctly detect an upgrade vs. a new profile, we check for the
|
|
153 | - // presence of the "app.update.postupdate" pref.
|
|
154 | - let updated = prefb.prefHasUserValue("app.update.postupdate");
|
|
155 | - return savedmstone || updated ? OVERRIDE_NEW_MSTONE : OVERRIDE_NEW_PROFILE;
|
|
147 | + prefb.setCharPref(FORK_VERSION_PREF, AppConstants.BASE_BROWSER_VERSION);
|
|
148 | + return savedmstone ? OVERRIDE_NEW_MSTONE : OVERRIDE_NEW_PROFILE;
|
|
156 | 149 | }
|
157 | 150 | |
158 | - if (AppConstants.BASE_BROWSER_VERSION != savedTBVersion) {
|
|
151 | + if (AppConstants.BASE_BROWSER_VERSION != savedForkVersion) {
|
|
159 | 152 | prefb.setCharPref("browser.startup.homepage_override.buildID", buildID);
|
160 | - prefb.setCharPref(kTBSavedVersionPref, AppConstants.BASE_BROWSER_VERSION);
|
|
153 | + prefb.setCharPref(FORK_VERSION_PREF, AppConstants.BASE_BROWSER_VERSION);
|
|
161 | 154 | return OVERRIDE_NEW_MSTONE;
|
162 | 155 | }
|
163 | 156 | |
... | ... | @@ -689,8 +682,8 @@ nsBrowserContentHandler.prototype = { |
689 | 682 | "unknown"
|
690 | 683 | );
|
691 | 684 | |
692 | - // We do the same for the Tor Browser version.
|
|
693 | - let old_tbversion = prefb.getCharPref(kTBSavedVersionPref, null);
|
|
685 | + // We do the same for the fork version.
|
|
686 | + let old_forkVersion = prefb.getCharPref(FORK_VERSION_PREF, null);
|
|
694 | 687 | |
695 | 688 | override = needHomepageOverride(prefb);
|
696 | 689 | if (override != OVERRIDE_NONE) {
|
... | ... | @@ -728,7 +721,7 @@ nsBrowserContentHandler.prototype = { |
728 | 721 | "startup.homepage_override_url"
|
729 | 722 | );
|
730 | 723 | let update = UpdateManager.readyUpdate;
|
731 | - let old_version = old_tbversion ? old_tbversion : old_mstone;
|
|
724 | + let old_version = old_forkVersion ? old_forkVersion : old_mstone;
|
|
732 | 725 | if (
|
733 | 726 | update &&
|
734 | 727 | Services.vc.compare(update.appVersion, old_version) > 0
|
... | ... | @@ -740,8 +733,8 @@ nsBrowserContentHandler.prototype = { |
740 | 733 | |
741 | 734 | overridePage = overridePage.replace("%OLD_VERSION%", old_mstone);
|
742 | 735 | overridePage = overridePage.replace(
|
743 | - "%OLD_TOR_BROWSER_VERSION%",
|
|
744 | - old_tbversion
|
|
736 | + "%OLD_BASE_BROWSER_VERSION%",
|
|
737 | + old_forkVersion
|
|
745 | 738 | );
|
746 | 739 | if (overridePage && AppConstants.BASE_BROWSER_UPDATE) {
|
747 | 740 | prefb.setCharPref("torbrowser.post_update.url", overridePage);
|
... | ... | @@ -954,10 +954,10 @@ def version_path(path): |
954 | 954 | return path
|
955 | 955 | |
956 | 956 | |
957 | -# set RELEASE_OR_BETA and NIGHTLY_BUILD variables depending on the cycle we're in
|
|
958 | -# The logic works like this:
|
|
959 | -# - if we have "a1" in GRE_MILESTONE, we're building Nightly (define NIGHTLY_BUILD)
|
|
960 | -# - otherwise, we're building Release/Beta (define RELEASE_OR_BETA)
|
|
957 | +# Firefox looks for "a" or "a1" in the milestone to detect whether nightly
|
|
958 | +# features should be enabled. We do not want them, because we want our nightly
|
|
959 | +# builds to be as close as possible to actual releases.
|
|
960 | +# So we set always is_release_or_beta to True.
|
|
961 | 961 | @depends(build_environment, build_project, version_path, "--help")
|
962 | 962 | @imports(_from="__builtin__", _import="open")
|
963 | 963 | @imports("os")
|
... | ... | @@ -1001,10 +1001,8 @@ def milestone(build_env, build_project, version_path, _): |
1001 | 1001 | |
1002 | 1002 | is_nightly = is_release_or_beta = is_early_beta_or_earlier = None
|
1003 | 1003 | |
1004 | - if "a1" in milestone:
|
|
1005 | - is_nightly = True
|
|
1006 | - else:
|
|
1007 | - is_release_or_beta = True
|
|
1004 | + # Do not enable extra nightly features
|
|
1005 | + is_release_or_beta = True
|
|
1008 | 1006 | |
1009 | 1007 | major_version = milestone.split(".")[0]
|
1010 | 1008 | m = re.search(r"([ab]\d+)", milestone)
|
... | ... | @@ -167,8 +167,8 @@ var UpdateUtils = { |
167 | 167 | * downloads and installs updates. This corresponds to whether or not the user
|
168 | 168 | * has selected "Automatically install updates" in about:preferences.
|
169 | 169 | *
|
170 | - * On Windows (except in Tor Browser), this setting is shared across all profiles
|
|
171 | - * for the installation
|
|
170 | + * On Windows (except in Base Browser and derivatives), this setting is shared
|
|
171 | + * across all profiles for the installation
|
|
172 | 172 | * and is read asynchronously from the file. On other operating systems, this
|
173 | 173 | * setting is stored in a pref and is thus a per-profile setting.
|
174 | 174 | *
|
... | ... | @@ -184,8 +184,8 @@ var UpdateUtils = { |
184 | 184 | * updates" and "Check for updates but let you choose to install them" options
|
185 | 185 | * in about:preferences.
|
186 | 186 | *
|
187 | - * On Windows (except in Tor Browser), this setting is shared across all profiles
|
|
188 | - * for the installation
|
|
187 | + * On Windows (except in Base Browser and derivatives), this setting is shared
|
|
188 | + * across all profiles for the installation
|
|
189 | 189 | * and is written asynchronously to the file. On other operating systems, this
|
190 | 190 | * setting is stored in a pref and is thus a per-profile setting.
|
191 | 191 | *
|
... | ... | @@ -40,7 +40,7 @@ const PREF_EM_STRICT_COMPATIBILITY = "extensions.strictCompatibility"; |
40 | 40 | const PREF_EM_CHECK_UPDATE_SECURITY = "extensions.checkUpdateSecurity";
|
41 | 41 | const PREF_SYS_ADDON_UPDATE_ENABLED = "extensions.systemAddon.update.enabled";
|
42 | 42 | const PREF_REMOTESETTINGS_DISABLED = "extensions.remoteSettings.disabled";
|
43 | -const PREF_EM_LAST_TORBROWSER_VERSION = "extensions.lastTorBrowserVersion";
|
|
43 | +const PREF_EM_LAST_FORK_VERSION = "extensions.lastTorBrowserVersion";
|
|
44 | 44 | |
45 | 45 | const PREF_MIN_WEBEXT_PLATFORM_VERSION =
|
46 | 46 | "extensions.webExtensionsMinPlatformVersion";
|
... | ... | @@ -645,26 +645,19 @@ var AddonManagerInternal = { |
645 | 645 | );
|
646 | 646 | }
|
647 | 647 | |
648 | - // To ensure that extension and plugin code gets a chance to run
|
|
649 | - // after each browser update, set appChanged = true when the
|
|
650 | - // Tor Browser version has changed even if the Mozilla app
|
|
651 | - // version has not changed.
|
|
652 | - let tbChanged = undefined;
|
|
653 | - try {
|
|
654 | - tbChanged =
|
|
655 | - AppConstants.BASE_BROWSER_VERSION !==
|
|
656 | - Services.prefs.getCharPref(PREF_EM_LAST_TORBROWSER_VERSION);
|
|
657 | - } catch (e) {}
|
|
658 | - if (tbChanged !== false) {
|
|
659 | - // Because PREF_EM_LAST_TORBROWSER_VERSION was not present in older
|
|
660 | - // versions of Tor Browser, an app change is indicated when tbChanged
|
|
661 | - // is undefined or true.
|
|
648 | + // To ensure that extension and plugin code gets a chance to run after
|
|
649 | + // each browser update, set appChanged = true when BASE_BROWSER_VERSION
|
|
650 | + // has changed even if the Mozilla app version has not changed.
|
|
651 | + const forkChanged = AppConstants.BASE_BROWSER_VERSION !==
|
|
652 | + Services.prefs.getCharPref(PREF_EM_LAST_FORK_VERSION, "");
|
|
653 | + if (forkChanged) {
|
|
654 | + // appChanged could be undefined (in case of a new profile)
|
|
662 | 655 | if (appChanged === false) {
|
663 | 656 | appChanged = true;
|
664 | 657 | }
|
665 | 658 | |
666 | 659 | Services.prefs.setCharPref(
|
667 | - PREF_EM_LAST_TORBROWSER_VERSION,
|
|
660 | + PREF_EM_LAST_FORK_VERSION,
|
|
668 | 661 | AppConstants.BASE_BROWSER_VERSION
|
669 | 662 | );
|
670 | 663 | }
|
... | ... | @@ -1587,33 +1587,32 @@ function handleUpdateFailure(update, errorCode) { |
1587 | 1587 | );
|
1588 | 1588 | cancelations++;
|
1589 | 1589 | Services.prefs.setIntPref(PREF_APP_UPDATE_CANCELATIONS, cancelations);
|
1590 | - if (AppConstants.platform == "macosx") {
|
|
1591 | - if (AppConstants.BASE_BROWSER_UPDATE) {
|
|
1592 | - cleanupActiveUpdates();
|
|
1590 | + if (AppConstants.platform == "macosx" && AppConstants.BASE_BROWSER_UPDATE) {
|
|
1591 | + cleanupActiveUpdates();
|
|
1592 | + update.statusText = gUpdateBundle.GetStringFromName("elevationFailure");
|
|
1593 | + } else if (AppConstants.platform == "macosx") {
|
|
1594 | + let osxCancelations = Services.prefs.getIntPref(
|
|
1595 | + PREF_APP_UPDATE_CANCELATIONS_OSX,
|
|
1596 | + 0
|
|
1597 | + );
|
|
1598 | + osxCancelations++;
|
|
1599 | + Services.prefs.setIntPref(
|
|
1600 | + PREF_APP_UPDATE_CANCELATIONS_OSX,
|
|
1601 | + osxCancelations
|
|
1602 | + );
|
|
1603 | + let maxCancels = Services.prefs.getIntPref(
|
|
1604 | + PREF_APP_UPDATE_CANCELATIONS_OSX_MAX,
|
|
1605 | + DEFAULT_CANCELATIONS_OSX_MAX
|
|
1606 | + );
|
|
1607 | + // Prevent the preference from setting a value greater than 5.
|
|
1608 | + maxCancels = Math.min(maxCancels, 5);
|
|
1609 | + if (osxCancelations >= maxCancels) {
|
|
1610 | + cleanupReadyUpdate();
|
|
1593 | 1611 | } else {
|
1594 | - let osxCancelations = Services.prefs.getIntPref(
|
|
1595 | - PREF_APP_UPDATE_CANCELATIONS_OSX,
|
|
1596 | - 0
|
|
1597 | - );
|
|
1598 | - osxCancelations++;
|
|
1599 | - Services.prefs.setIntPref(
|
|
1600 | - PREF_APP_UPDATE_CANCELATIONS_OSX,
|
|
1601 | - osxCancelations
|
|
1612 | + writeStatusFile(
|
|
1613 | + getReadyUpdateDir(),
|
|
1614 | + (update.state = STATE_PENDING_ELEVATE)
|
|
1602 | 1615 | );
|
1603 | - let maxCancels = Services.prefs.getIntPref(
|
|
1604 | - PREF_APP_UPDATE_CANCELATIONS_OSX_MAX,
|
|
1605 | - DEFAULT_CANCELATIONS_OSX_MAX
|
|
1606 | - );
|
|
1607 | - // Prevent the preference from setting a value greater than 5.
|
|
1608 | - maxCancels = Math.min(maxCancels, 5);
|
|
1609 | - if (osxCancelations >= maxCancels) {
|
|
1610 | - cleanupReadyUpdate();
|
|
1611 | - } else {
|
|
1612 | - writeStatusFile(
|
|
1613 | - getReadyUpdateDir(),
|
|
1614 | - (update.state = STATE_PENDING_ELEVATE)
|
|
1615 | - );
|
|
1616 | - }
|
|
1617 | 1616 | }
|
1618 | 1617 | update.statusText = gUpdateBundle.GetStringFromName("elevationFailure");
|
1619 | 1618 | } else {
|
... | ... | @@ -80,8 +80,9 @@ function UpdateServiceStub() { |
80 | 80 | // contains the status file's path
|
81 | 81 | |
82 | 82 | // We may need to migrate update data
|
83 | - // In Tor Browser we skip this because we do not use an update agent and we
|
|
84 | - // do not want to store any data outside of the browser installation directory.
|
|
83 | + // In Base Browser and derivatives, we skip this because we do not use an
|
|
84 | + // update agent and we do not want to store any data outside of the browser
|
|
85 | + // installation directory.
|
|
85 | 86 | // For more info, see https://bugzilla.mozilla.org/show_bug.cgi?id=1458314
|
86 | 87 | if (
|
87 | 88 | AppConstants.platform == "win" &&
|
... | ... | @@ -68,8 +68,8 @@ BOOL PathGetSiblingFilePath(LPWSTR destinationBuffer, LPCWSTR siblingFilePath, |
68 | 68 | BOOL GetSecureOutputDirectoryPath(LPWSTR outBuf) {
|
69 | 69 | #ifdef BASE_BROWSER_UPDATE
|
70 | 70 | // This function is used to support the maintenance service and elevated
|
71 | - // updates and is therefore not called by Tor Browser's updater. We stub
|
|
72 | - // it out to avoid any chance that the Tor Browser updater will create
|
|
71 | + // updates and is therefore not called by Base Browser's updater. We stub
|
|
72 | + // it out to avoid any chance that the Base Browser updater will create
|
|
73 | 73 | // files under C:\Program Files (x86)\ or a similar location.
|
74 | 74 | return FALSE;
|
75 | 75 | #else
|
... | ... | @@ -3657,9 +3657,9 @@ static bool CheckCompatibility(nsIFile* aProfileDir, const nsCString& aVersion, |
3657 | 3657 | |
3658 | 3658 | nsAutoCString buf;
|
3659 | 3659 | |
3660 | - nsAutoCString tbVersion(BASE_BROWSER_VERSION_QUOTED);
|
|
3660 | + nsAutoCString forkVersion(BASE_BROWSER_VERSION_QUOTED);
|
|
3661 | 3661 | rv = parser.GetString("Compatibility", "LastTorBrowserVersion", buf);
|
3662 | - if (NS_FAILED(rv) || !tbVersion.Equals(buf)) return false;
|
|
3662 | + if (NS_FAILED(rv) || !forkVersion.Equals(buf)) return false;
|
|
3663 | 3663 | |
3664 | 3664 | rv = parser.GetString("Compatibility", "LastOSABI", buf);
|
3665 | 3665 | if (NS_FAILED(rv) || !aOSABI.Equals(buf)) return false;
|
... | ... | @@ -3746,11 +3746,11 @@ static void WriteVersion(nsIFile* aProfileDir, const nsCString& aVersion, |
3746 | 3746 | PR_Write(fd, kHeader, sizeof(kHeader) - 1);
|
3747 | 3747 | PR_Write(fd, aVersion.get(), aVersion.Length());
|
3748 | 3748 | |
3749 | - nsAutoCString tbVersion(BASE_BROWSER_VERSION_QUOTED);
|
|
3750 | - static const char kTorBrowserVersionHeader[] =
|
|
3749 | + nsAutoCString forkVersion(BASE_BROWSER_VERSION_QUOTED);
|
|
3750 | + static const char kForkVersionHeader[] =
|
|
3751 | 3751 | NS_LINEBREAK "LastTorBrowserVersion=";
|
3752 | - PR_Write(fd, kTorBrowserVersionHeader, sizeof(kTorBrowserVersionHeader) - 1);
|
|
3753 | - PR_Write(fd, tbVersion.get(), tbVersion.Length());
|
|
3752 | + PR_Write(fd, kForkVersionHeader, sizeof(kForkVersionHeader) - 1);
|
|
3753 | + PR_Write(fd, forkVersion.get(), forkVersion.Length());
|
|
3754 | 3754 | |
3755 | 3755 | static const char kOSABIHeader[] = NS_LINEBREAK "LastOSABI=";
|
3756 | 3756 | PR_Write(fd, kOSABIHeader, sizeof(kOSABIHeader) - 1);
|
... | ... | @@ -87,7 +87,7 @@ static void UpdateDriverSetupMacCommandLine(int& argc, char**& argv, |
87 | 87 | // result from it, so we can't just dispatch and return, we have to wait
|
88 | 88 | // until the dispatched operation actually completes. So we also set up a
|
89 | 89 | // monitor to signal us when that happens, and block until then.
|
90 | - Monitor monitor("nsUpdateDriver SetupMacCommandLine");
|
|
90 | + Monitor monitor MOZ_UNANNOTATED("nsUpdateDriver SetupMacCommandLine");
|
|
91 | 91 | |
92 | 92 | nsresult rv = NS_DispatchToMainThread(NS_NewRunnableFunction(
|
93 | 93 | "UpdateDriverSetupMacCommandLine",
|
... | ... | @@ -1213,20 +1213,27 @@ nsresult nsXREDirProvider::GetUpdateRootDir(nsIFile** aResult, |
1213 | 1213 | NS_ENSURE_SUCCESS(rv, rv);
|
1214 | 1214 | |
1215 | 1215 | #if defined(BASE_BROWSER_UPDATE)
|
1216 | - // For Tor Browser, we store update history, etc. within the UpdateInfo
|
|
1217 | - // directory under the user data directory.
|
|
1218 | - rv = GetTorBrowserUserDataDir(getter_AddRefs(updRoot));
|
|
1216 | + nsCOMPtr<nsIFile> dataDir;
|
|
1217 | + // For Base Browser and derivatives, we store update history, etc. within the
|
|
1218 | + // UpdateInfo directory under the user data directory.
|
|
1219 | +# if defined(ANDROID)
|
|
1220 | +# error "The Base Browser updater is not supported on Android."
|
|
1221 | +# else
|
|
1222 | + rv = GetUserDataDirectoryHome(getter_AddRefs(dataDir), false);
|
|
1223 | + NS_ENSURE_SUCCESS(rv, rv);
|
|
1224 | + rv = dataDir->GetParent(getter_AddRefs(updRoot));
|
|
1219 | 1225 | NS_ENSURE_SUCCESS(rv, rv);
|
1226 | +# endif
|
|
1220 | 1227 | rv = updRoot->AppendNative("UpdateInfo"_ns);
|
1221 | 1228 | NS_ENSURE_SUCCESS(rv, rv);
|
1229 | + |
|
1222 | 1230 | # if defined(XP_MACOSX)
|
1223 | - // Since the TorBrowser-Data directory may be shared among different
|
|
1224 | - // installations of the application, embed the app path in the update dir
|
|
1225 | - // so that the update history is partitioned. This is much less likely to
|
|
1226 | - // be an issue on Linux or Windows because the Tor Browser packages for
|
|
1227 | - // those platforms include a "container" folder that provides partitioning
|
|
1228 | - // by default, and we do not support use of a shared, OS-recommended area
|
|
1229 | - // for user data on those platforms.
|
|
1231 | + // Since the data directory may be shared among different installations of the
|
|
1232 | + // application, embed the app path in the update dir so that the update
|
|
1233 | + // history is partitioned. This is much less likely to be an issue on Linux or
|
|
1234 | + // Windows, because our packages for those platforms include a "container"
|
|
1235 | + // folder that provides partitioning by default, and we do not support use of
|
|
1236 | + // a shared, OS-recommended area for user data on those platforms.
|
|
1230 | 1237 | nsAutoString appPath;
|
1231 | 1238 | rv = appFile->GetPath(appPath);
|
1232 | 1239 | NS_ENSURE_SUCCESS(rv, rv);
|
... | ... | @@ -79,7 +79,7 @@ if [ $# = 0 ]; then |
79 | 79 | fi
|
80 | 80 | |
81 | 81 | # Firefox uses requested_forced_updates='Contents/MacOS/firefox Contents/Resources/defaults/pref/channel-prefs.js'
|
82 | -# - 'Contents/MacOS/firefox' is required for Bugzilla 770996 but in Tor Browser we do not need that fix.
|
|
82 | +# - 'Contents/MacOS/firefox' is required for Bugzilla 770996 but Base Browser and derivatives do not need that fix.
|
|
83 | 83 | # - 'Contents/Resources/defaults/pref/channel-prefs.js' is required for 1804303 to avoid a failed code signing signature
|
84 | 84 | # check on macOS aarch64; it is unlikely that users will run into this issue but there's no harm in including it
|
85 | 85 | requested_forced_updates="Contents/Resources/defaults/pref/channel-prefs.js"
|