mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 1455707: Detect when running an older version than previously ran with the selected profile. r=froydnj, r=mconley, r=Gijs
Use the information in compatibility.ini to detect that the current running application is an older version than previously ran with the profile and in that case open a UI allowing the user to launch the profile manager, launch the previous instance of the application or quit. Also includes the patch from bug 1523725. --HG-- rename : browser/themes/shared/information.svg => toolkit/themes/shared/profile/information.svg extra : rebase_source : 3bf8b329eb5ea9e71fe2f0ed34a7e44dfdc434fd extra : intermediate-source : 21a801ca5f6d435509f93e1dee187cb6ca868c8f extra : source : c9d89812bc226ca593119bf440cb4f5e50ac2ace
This commit is contained in:
parent
5d41d30a08
commit
1e3b008bd7
@ -56,7 +56,6 @@
|
||||
skin/classic/browser/identity-icon.svg (../shared/identity-block/identity-icon.svg)
|
||||
skin/classic/browser/identity-icon-notice.svg (../shared/identity-block/identity-icon-notice.svg)
|
||||
skin/classic/browser/info.svg (../shared/info.svg)
|
||||
skin/classic/browser/information.svg (../shared/information.svg)
|
||||
skin/classic/browser/newInstall.css (../shared/newInstall.css)
|
||||
skin/classic/browser/newInstallPage.css (../shared/newInstallPage.css)
|
||||
|
||||
|
@ -10,7 +10,7 @@ window {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-inline-end: 8px;
|
||||
list-style-image: url("chrome://browser/skin/information.svg");
|
||||
list-style-image: url("chrome://mozapps/skin/profile/information.svg");
|
||||
}
|
||||
|
||||
description {
|
||||
|
@ -0,0 +1,20 @@
|
||||
<!-- 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/. -->
|
||||
|
||||
<!-- LOCALIZATION NOTE:
|
||||
This UI can be most easily shown by modifying the version in compatibility.ini
|
||||
to a newer version and then starting Firefox.
|
||||
For this feature, "installation" is used to mean "this discrete download of
|
||||
Firefox" and "version" is used to mean "the specific revision number of a
|
||||
given Firefox channel". These terms are not synonymous.
|
||||
-->
|
||||
<!ENTITY window.title "You’ve launched an older version of Firefox">
|
||||
<!ENTITY window.style "width: 490px;">
|
||||
|
||||
<!ENTITY window.nosync "Using an older version of Firefox can corrupt bookmarks and browsing history already saved to an existing Firefox profile. To protect your information, create a new profile for this installation of &brandShortName;.">
|
||||
<!ENTITY window.sync "Using an older version of Firefox can corrupt bookmarks and browsing history already saved to an existing Firefox profile. To protect your information, create a new profile for this installation of &brandShortName;. You can always sign in with a &syncBrand.fxAccount.label; to sync your bookmarks and browsing history between profiles.">
|
||||
|
||||
<!ENTITY window.create "Create New Profile">
|
||||
<!ENTITY window.quit-win "Exit">
|
||||
<!ENTITY window.quit-nonwin "Quit">
|
@ -83,6 +83,9 @@
|
||||
locale/@AB_CD@/mozapps/profile/createProfileWizard.dtd (%chrome/mozapps/profile/createProfileWizard.dtd)
|
||||
locale/@AB_CD@/mozapps/profile/profileSelection.properties (%chrome/mozapps/profile/profileSelection.properties)
|
||||
locale/@AB_CD@/mozapps/profile/profileSelection.dtd (%chrome/mozapps/profile/profileSelection.dtd)
|
||||
#ifdef MOZ_BLOCK_PROFILE_DOWNGRADE
|
||||
locale/@AB_CD@/mozapps/profile/profileDowngrade.dtd (%chrome/mozapps/profile/profileDowngrade.dtd)
|
||||
#endif
|
||||
#ifndef MOZ_FENNEC
|
||||
locale/@AB_CD@/mozapps/update/updates.dtd (%chrome/mozapps/update/updates.dtd)
|
||||
locale/@AB_CD@/mozapps/update/updates.properties (%chrome/mozapps/update/updates.properties)
|
||||
|
29
toolkit/profile/content/profileDowngrade.js
Normal file
29
toolkit/profile/content/profileDowngrade.js
Normal file
@ -0,0 +1,29 @@
|
||||
/* 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/. */
|
||||
|
||||
let gParams;
|
||||
|
||||
function init() {
|
||||
/*
|
||||
* The C++ code passes a dialog param block using its integers as in and out
|
||||
* arguments for this UI. The following are the uses of the integers:
|
||||
*
|
||||
* 0: A set of flags from nsIToolkitProfileService.downgradeUIFlags.
|
||||
* 1: A return argument, one of nsIToolkitProfileService.downgradeUIChoice.
|
||||
*/
|
||||
gParams = window.arguments[0].QueryInterface(Ci.nsIDialogParamBlock);
|
||||
let hasSync = gParams.GetInt(0) & Ci.nsIToolkitProfileService.hasSync;
|
||||
|
||||
document.getElementById("sync").hidden = !hasSync;
|
||||
document.getElementById("nosync").hidden = hasSync;
|
||||
}
|
||||
|
||||
function quit() {
|
||||
gParams.SetInt(1, Ci.nsIToolkitProfileService.quit);
|
||||
}
|
||||
|
||||
function createProfile() {
|
||||
gParams.SetInt(1, Ci.nsIToolkitProfileService.createNewProfile);
|
||||
window.close();
|
||||
}
|
39
toolkit/profile/content/profileDowngrade.xul
Normal file
39
toolkit/profile/content/profileDowngrade.xul
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.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/. -->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mozapps/skin/profile/profileDowngrade.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE dialog [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
%brandDTD;
|
||||
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
|
||||
%syncBrandDTD;
|
||||
<!ENTITY % profileDTD SYSTEM "chrome://mozapps/locale/profile/profileDowngrade.dtd">
|
||||
%profileDTD;
|
||||
]>
|
||||
|
||||
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="&window.title;" onload="init()" style="&window.style;"
|
||||
buttonlabelextra1="&window.create;" ondialogextra1="createProfile()"
|
||||
#ifdef XP_WIN
|
||||
buttonlabelaccept="&window.quit-win;"
|
||||
#else
|
||||
buttonlabelaccept="&window.quit-nonwin;"
|
||||
#endif
|
||||
ondialogaccept="quit()" ondialogcancel="quit()"
|
||||
buttons="accept,extra1" buttonpack="end">
|
||||
|
||||
<script type="application/javascript" src="profileDowngrade.js"/>
|
||||
|
||||
<hbox flex="1" align="start">
|
||||
<image id="info" role="presentation"/>
|
||||
<vbox flex="1">
|
||||
<description id="nosync">&window.nosync;</description>
|
||||
<description id="sync">&window.sync;</description>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</dialog>
|
@ -7,3 +7,7 @@ toolkit.jar:
|
||||
* content/mozapps/profile/createProfileWizard.xul (content/createProfileWizard.xul)
|
||||
content/mozapps/profile/profileSelection.js (content/profileSelection.js)
|
||||
content/mozapps/profile/profileSelection.xul (content/profileSelection.xul)
|
||||
#ifdef MOZ_BLOCK_PROFILE_DOWNGRADE
|
||||
content/mozapps/profile/profileDowngrade.js (content/profileDowngrade.js)
|
||||
* content/mozapps/profile/profileDowngrade.xul (content/profileDowngrade.xul)
|
||||
#endif
|
||||
|
@ -13,6 +13,23 @@ interface nsIProfileLock;
|
||||
[scriptable, builtinclass, uuid(1947899b-f369-48fa-89da-f7c37bb1e6bc)]
|
||||
interface nsIToolkitProfileService : nsISupports
|
||||
{
|
||||
/**
|
||||
* When a downgrade is detected UI is presented to the user to ask how to
|
||||
* proceed. These flags are used to pass some information to the UI.
|
||||
*/
|
||||
cenum downgradeUIFlags: 8 {
|
||||
hasSync = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* When a downgrade is detected UI is presented to the user to ask how to
|
||||
* proceed. These are the possible options the user can choose.
|
||||
*/
|
||||
cenum downgradeUIChoice: 8 {
|
||||
quit = 0,
|
||||
createNewProfile = 1,
|
||||
};
|
||||
|
||||
attribute boolean startWithLastProfile;
|
||||
|
||||
readonly attribute nsISimpleEnumerator /*nsIToolkitProfile*/ profiles;
|
||||
@ -74,7 +91,10 @@ interface nsIToolkitProfileService : nsISupports
|
||||
*
|
||||
* The profile temporary directory will be chosen based on where the
|
||||
* profile directory is located.
|
||||
*
|
||||
*
|
||||
* If a profile with the given name already exists it will be returned
|
||||
* instead of creating a new profile.
|
||||
*
|
||||
* @param aRootDir
|
||||
* The profile directory. May be null, in which case a suitable
|
||||
* default will be chosen based on the profile name.
|
||||
@ -84,6 +104,23 @@ interface nsIToolkitProfileService : nsISupports
|
||||
nsIToolkitProfile createProfile(in nsIFile aRootDir,
|
||||
in AUTF8String aName);
|
||||
|
||||
/**
|
||||
* Create a new profile with a unique name.
|
||||
*
|
||||
* As above however the name given will be altered to make it a unique
|
||||
* profile name.
|
||||
*
|
||||
* @param aRootDir
|
||||
* The profile directory. May be null, in which case a suitable
|
||||
* default will be chosen based on the profile name.
|
||||
* @param aNamePrefix
|
||||
* The prefix to use for the profile name. If unused this will be
|
||||
* used as the profile name otherwise additional characters will be
|
||||
* added to make the name unique.
|
||||
*/
|
||||
nsIToolkitProfile createUniqueProfile(in nsIFile aRootDir,
|
||||
in AUTF8String aNamePrefix);
|
||||
|
||||
/**
|
||||
* Returns the number of profiles.
|
||||
* @return the number of profiles.
|
||||
|
@ -1066,7 +1066,7 @@ nsresult nsToolkitProfileService::SelectStartupProfile(
|
||||
name.AssignLiteral(DEFAULT_NAME);
|
||||
}
|
||||
|
||||
rv = CreateProfile(nullptr, name, getter_AddRefs(mCurrent));
|
||||
rv = CreateUniqueProfile(nullptr, name, getter_AddRefs(mCurrent));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (mUseDedicatedProfile) {
|
||||
SetDefaultProfile(mCurrent);
|
||||
@ -1261,6 +1261,28 @@ static void SaltProfileName(nsACString& aName) {
|
||||
aName.Insert(salt, 0, 9);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::CreateUniqueProfile(nsIFile* aRootDir,
|
||||
const nsACString& aNamePrefix,
|
||||
nsIToolkitProfile** aResult) {
|
||||
nsCOMPtr<nsIToolkitProfile> profile;
|
||||
nsresult rv = GetProfileByName(aNamePrefix, getter_AddRefs(profile));
|
||||
if (NS_FAILED(rv)) {
|
||||
return CreateProfile(aRootDir, aNamePrefix, aResult);
|
||||
}
|
||||
|
||||
uint32_t suffix = 1;
|
||||
while (true) {
|
||||
nsPrintfCString name("%s-%d", PromiseFlatCString(aNamePrefix).get(),
|
||||
suffix);
|
||||
rv = GetProfileByName(name, getter_AddRefs(profile));
|
||||
if (NS_FAILED(rv)) {
|
||||
return CreateProfile(aRootDir, name, aResult);
|
||||
}
|
||||
suffix++;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsToolkitProfileService::CreateProfile(nsIFile* aRootDir,
|
||||
const nsACString& aName,
|
||||
|
@ -28,6 +28,8 @@
|
||||
skin/classic/mozapps/aboutProfiles.css (../../shared/aboutProfiles.css)
|
||||
#endif
|
||||
skin/classic/mozapps/aboutServiceWorkers.css (../../shared/aboutServiceWorkers.css)
|
||||
skin/classic/mozapps/profile/profileDowngrade.css (../../shared/profile/profileDowngrade.css)
|
||||
skin/classic/mozapps/profile/information.svg (../../shared/profile/information.svg)
|
||||
|
||||
% override chrome://mozapps/skin/extensions/category-plugins.svg chrome://global/skin/plugins/pluginGeneric.svg
|
||||
% override chrome://mozapps/skin/extensions/category-extensions.svg chrome://mozapps/skin/extensions/extensionGeneric.svg
|
||||
|
Before Width: | Height: | Size: 552 B After Width: | Height: | Size: 552 B |
13
toolkit/themes/shared/profile/profileDowngrade.css
Normal file
13
toolkit/themes/shared/profile/profileDowngrade.css
Normal file
@ -0,0 +1,13 @@
|
||||
/* 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/. */
|
||||
|
||||
spacer[anonid="spacer"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#info {
|
||||
list-style-image: url("chrome://mozapps/skin/profile/information.svg");
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
@ -1494,6 +1494,9 @@ static void DumpHelp() {
|
||||
"instance.\n"
|
||||
" --UILocale <locale> Start with <locale> resources as UI Locale.\n"
|
||||
" --safe-mode Disables extensions and themes for this session.\n"
|
||||
#ifdef MOZ_BLOCK_PROFILE_DOWNGRADE
|
||||
" --allow-downgrade Allows downgrading a profile.\n"
|
||||
#endif
|
||||
" -MOZ_LOG=<modules> Treated as MOZ_LOG=<modules> environment variable, "
|
||||
"overrides it.\n"
|
||||
" -MOZ_LOG_FILE=<file> Treated as MOZ_LOG_FILE=<file> environment "
|
||||
@ -2230,18 +2233,188 @@ static nsresult SelectProfile(nsIProfileLock** aResult,
|
||||
return ProfileLockedDialog(rootDir, localDir, unlocker, aNative, aResult);
|
||||
}
|
||||
|
||||
#ifdef MOZ_BLOCK_PROFILE_DOWNGRADE
|
||||
static const char kProfileDowngradeURL[] =
|
||||
"chrome://mozapps/content/profile/profileDowngrade.xul";
|
||||
|
||||
static ReturnAbortOnError CheckDowngrade(
|
||||
nsIFile* aProfileDir, nsIFile* aProfileLocalDir, nsACString& aProfileName,
|
||||
nsINativeAppSupport* aNative, nsIToolkitProfileService* aProfileSvc) {
|
||||
int32_t result = 0;
|
||||
nsresult rv;
|
||||
|
||||
{
|
||||
if (gfxPlatform::IsHeadless()) {
|
||||
// TODO: make a way to turn off all dialogs when headless.
|
||||
Output(true,
|
||||
"This profile was last used with a newer version of this "
|
||||
"application. Please create a new profile.\n");
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
ScopedXPCOMStartup xpcom;
|
||||
rv = xpcom.Initialize();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = xpcom.SetWindowCreator(aNative);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
{ // extra scoping is needed so we release these components before xpcom
|
||||
// shutdown
|
||||
bool hasSync = false;
|
||||
nsCOMPtr<nsIPrefService> prefSvc =
|
||||
do_GetService("@mozilla.org/preferences-service;1");
|
||||
NS_ENSURE_TRUE(prefSvc, rv);
|
||||
|
||||
nsCOMPtr<nsIFile> prefsFile;
|
||||
rv = aProfileDir->Clone(getter_AddRefs(prefsFile));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = prefsFile->Append(NS_LITERAL_STRING("prefs.js"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = prefSvc->ReadUserPrefsFromFile(prefsFile);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch = do_QueryInterface(prefSvc);
|
||||
|
||||
rv = prefBranch->PrefHasUserValue("services.sync.username", &hasSync);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWindowWatcher> windowWatcher =
|
||||
do_GetService(NS_WINDOWWATCHER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(windowWatcher, NS_ERROR_ABORT);
|
||||
|
||||
nsCOMPtr<nsIAppStartup> appStartup(components::AppStartup::Service());
|
||||
NS_ENSURE_TRUE(appStartup, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDialogParamBlock> paramBlock =
|
||||
do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID);
|
||||
NS_ENSURE_TRUE(paramBlock, NS_ERROR_ABORT);
|
||||
|
||||
uint8_t flags = 0;
|
||||
if (hasSync) {
|
||||
flags |= nsIToolkitProfileService::hasSync;
|
||||
}
|
||||
|
||||
paramBlock->SetInt(0, flags);
|
||||
|
||||
nsCOMPtr<mozIDOMWindowProxy> newWindow;
|
||||
rv = windowWatcher->OpenWindow(nullptr, kProfileDowngradeURL, "_blank",
|
||||
"centerscreen,chrome,modal,titlebar",
|
||||
paramBlock, getter_AddRefs(newWindow));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
paramBlock->GetInt(1, &result);
|
||||
}
|
||||
}
|
||||
|
||||
if (result == nsIToolkitProfileService::createNewProfile) {
|
||||
// Create a new profile and start it.
|
||||
nsCString profileName;
|
||||
profileName.AssignLiteral("default");
|
||||
# ifdef MOZ_DEDICATED_PROFILES
|
||||
profileName.Append("-" NS_STRINGIFY(MOZ_UPDATE_CHANNEL));
|
||||
# endif
|
||||
nsCOMPtr<nsIToolkitProfile> newProfile;
|
||||
rv = aProfileSvc->CreateUniqueProfile(nullptr, profileName,
|
||||
getter_AddRefs(newProfile));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aProfileSvc->SetDefaultProfile(newProfile);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aProfileSvc->Flush();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIFile> profD, profLD;
|
||||
rv = newProfile->GetRootDir(getter_AddRefs(profD));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = newProfile->GetLocalDir(getter_AddRefs(profLD));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
SaveFileToEnv("XRE_PROFILE_PATH", profD);
|
||||
SaveFileToEnv("XRE_PROFILE_LOCAL_PATH", profLD);
|
||||
|
||||
return LaunchChild(aNative);
|
||||
}
|
||||
|
||||
// Cancel
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The version string used in compatibility.ini is in the form
|
||||
* <appversion>_<appbuildid>/<aplatformbuildidid>. The build IDs are in the form
|
||||
* <year><month><day><hour><minute><second>. We need to be able to turn this
|
||||
* into something that can be compared by the version comparator. Build IDs are
|
||||
* numeric so normally we could just use those as part of the version but they
|
||||
* are larger than 32-bit integers so we must split them into two parts.
|
||||
* So we generate a version string of the format:
|
||||
* <appversion>.<appbuilddate>.<appbuildtime>.<platformbuilddate>.<platformbuildtime>
|
||||
* This doesn't compare correctly so
|
||||
* we have to make the build ids separate version parts instead. We also have
|
||||
* to split up the build ids as they are too large for the version comparator's
|
||||
* brain.
|
||||
*/
|
||||
|
||||
// Build ID dates are 8 digits, build ID times are 6 digits.
|
||||
#define BUILDID_DATE_LENGTH 8
|
||||
#define BUILDID_TIME_LENGTH 6
|
||||
#define BUILDID_LENGTH BUILDID_DATE_LENGTH + BUILDID_TIME_LENGTH
|
||||
|
||||
static void GetBuildIDVersions(const nsACString& aFullVersion, int32_t aPos,
|
||||
nsACString& aBuildVersions) {
|
||||
// Extract the date part then the time part.
|
||||
aBuildVersions.Assign(Substring(aFullVersion, aPos, BUILDID_DATE_LENGTH) +
|
||||
NS_LITERAL_CSTRING(".") +
|
||||
Substring(aFullVersion, aPos + BUILDID_DATE_LENGTH, BUILDID_TIME_LENGTH));
|
||||
}
|
||||
|
||||
static Version GetComparableVersion(const nsCString& aVersionStr) {
|
||||
// We'll find the position of the '_' and '/' characters. The length from the
|
||||
// '_' character to the '/' character will be the length of a build ID plus
|
||||
// one for the '_' character. Similarly the length from the '/' character to
|
||||
// the end of the string will be the same.
|
||||
const uint32_t kExpectedLength = BUILDID_LENGTH + 1;
|
||||
|
||||
int32_t underscorePos = aVersionStr.FindChar('_');
|
||||
int32_t slashPos = aVersionStr.FindChar('/');
|
||||
if (underscorePos == kNotFound || slashPos == kNotFound ||
|
||||
(slashPos - underscorePos) != kExpectedLength ||
|
||||
(aVersionStr.Length() - slashPos) != kExpectedLength) {
|
||||
NS_WARNING("compatibility.ini Version string does not match the expected format.");
|
||||
return Version(aVersionStr.get());
|
||||
}
|
||||
|
||||
nsCString appBuild, platBuild;
|
||||
NS_NAMED_LITERAL_CSTRING(dot, ".");
|
||||
|
||||
const nsACString& version = Substring(aVersionStr, 0, underscorePos);
|
||||
|
||||
GetBuildIDVersions(aVersionStr, underscorePos + 1, /* outparam */ appBuild);
|
||||
GetBuildIDVersions(aVersionStr, slashPos + 1, /* outparam */ platBuild);
|
||||
|
||||
const nsACString& fullVersion = version + dot + appBuild + dot + platBuild;
|
||||
|
||||
return Version(PromiseFlatCString(fullVersion).get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the compatibility.ini file to see if we have updated our application
|
||||
* or otherwise invalidated our caches. If the application has been updated,
|
||||
* we return false; otherwise, we return true. We also write the status
|
||||
* of the caches (valid/invalid) into the return param aCachesOK. The aCachesOK
|
||||
* is always invalid if the application has been updated.
|
||||
* is always invalid if the application has been updated. aIsDowngrade is set to
|
||||
* true if the current application is older than that previously used by the
|
||||
* profile.
|
||||
*/
|
||||
static bool CheckCompatibility(nsIFile* aProfileDir, const nsCString& aVersion,
|
||||
const nsCString& aOSABI, nsIFile* aXULRunnerDir,
|
||||
nsIFile* aAppDir, nsIFile* aFlagFile,
|
||||
bool* aCachesOK) {
|
||||
bool* aCachesOK, bool* aIsDowngrade) {
|
||||
*aCachesOK = false;
|
||||
*aIsDowngrade = false;
|
||||
|
||||
nsCOMPtr<nsIFile> file;
|
||||
aProfileDir->Clone(getter_AddRefs(file));
|
||||
if (!file) return false;
|
||||
@ -2253,7 +2426,16 @@ static bool CheckCompatibility(nsIFile* aProfileDir, const nsCString& aVersion,
|
||||
|
||||
nsAutoCString buf;
|
||||
rv = parser.GetString("Compatibility", "LastVersion", buf);
|
||||
if (NS_FAILED(rv) || !aVersion.Equals(buf)) return false;
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aVersion.Equals(buf)) {
|
||||
Version current = GetComparableVersion(aVersion);
|
||||
Version last = GetComparableVersion(buf);
|
||||
*aIsDowngrade = last > current;
|
||||
return false;
|
||||
}
|
||||
|
||||
rv = parser.GetString("Compatibility", "LastOSABI", buf);
|
||||
if (NS_FAILED(rv) || !aOSABI.Equals(buf)) return false;
|
||||
@ -3840,30 +4022,6 @@ int XREMain::XRE_mainStartup(bool* aExitFlag) {
|
||||
rv = mProfileLock->GetLocalDirectory(getter_AddRefs(mProfLD));
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
rv = mDirProvider.SetProfile(mProfD, mProfLD);
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
//////////////////////// NOW WE HAVE A PROFILE ////////////////////////
|
||||
|
||||
mozilla::Telemetry::SetProfileDir(mProfD);
|
||||
|
||||
if (mAppData->flags & NS_XRE_ENABLE_CRASH_REPORTER)
|
||||
MakeOrSetMinidumpPath(mProfD);
|
||||
|
||||
CrashReporter::SetProfileDirectory(mProfD);
|
||||
|
||||
#ifdef MOZ_ASAN_REPORTER
|
||||
// In ASan reporter builds, we need to set ASan's log_path as early as
|
||||
// possible, so it dumps its errors into files there instead of using
|
||||
// the default stderr location. Since this is crucial for ASan reporter
|
||||
// to work at all (and we don't want people to use a non-functional
|
||||
// ASan reporter build), all failures while setting log_path are fatal.
|
||||
setASanReporterPath(mProfD);
|
||||
|
||||
// Export to env for child processes
|
||||
SaveFileToEnv("ASAN_REPORTER_PATH", mProfD);
|
||||
#endif
|
||||
|
||||
nsAutoCString version;
|
||||
BuildVersion(version);
|
||||
|
||||
@ -3891,9 +4049,45 @@ int XREMain::XRE_mainStartup(bool* aExitFlag) {
|
||||
}
|
||||
|
||||
bool cachesOK;
|
||||
bool versionOK =
|
||||
CheckCompatibility(mProfD, version, osABI, mDirProvider.GetGREDir(),
|
||||
mAppData->directory, flagFile, &cachesOK);
|
||||
bool isDowngrade;
|
||||
bool versionOK = CheckCompatibility(
|
||||
mProfD, version, osABI, mDirProvider.GetGREDir(), mAppData->directory,
|
||||
flagFile, &cachesOK, &isDowngrade);
|
||||
|
||||
#ifdef MOZ_BLOCK_PROFILE_DOWNGRADE
|
||||
if (isDowngrade && !CheckArg("allow-downgrade")) {
|
||||
rv = CheckDowngrade(mProfD, mProfLD, mProfileName, mNativeApp, mProfileSvc);
|
||||
if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS || rv == NS_ERROR_ABORT) {
|
||||
*aExitFlag = true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = mDirProvider.SetProfile(mProfD, mProfLD);
|
||||
NS_ENSURE_SUCCESS(rv, 1);
|
||||
|
||||
//////////////////////// NOW WE HAVE A PROFILE ////////////////////////
|
||||
|
||||
mozilla::Telemetry::SetProfileDir(mProfD);
|
||||
|
||||
if (mAppData->flags & NS_XRE_ENABLE_CRASH_REPORTER) {
|
||||
MakeOrSetMinidumpPath(mProfD);
|
||||
}
|
||||
|
||||
CrashReporter::SetProfileDirectory(mProfD);
|
||||
|
||||
#ifdef MOZ_ASAN_REPORTER
|
||||
// In ASan reporter builds, we need to set ASan's log_path as early as
|
||||
// possible, so it dumps its errors into files there instead of using
|
||||
// the default stderr location. Since this is crucial for ASan reporter
|
||||
// to work at all (and we don't want people to use a non-functional
|
||||
// ASan reporter build), all failures while setting log_path are fatal.
|
||||
setASanReporterPath(mProfD);
|
||||
|
||||
// Export to env for child processes
|
||||
SaveFileToEnv("ASAN_REPORTER_PATH", mProfD);
|
||||
#endif
|
||||
|
||||
bool lastStartupWasCrash = CheckLastStartupWasCrash().unwrapOr(false);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user