Backed out changeset e1c9790cd3be (bug 1527704) for failures in test_refresh_firefox.py

This commit is contained in:
Noemi Erli 2019-03-15 19:32:35 +02:00
parent dd77c51ff5
commit f02b516553
27 changed files with 289 additions and 572 deletions

View File

@ -46,7 +46,7 @@ interface nsIProfileLock : nsISupports
* @note THIS INTERFACE SHOULD BE IMPLEMENTED BY THE TOOLKIT CODE ONLY! DON'T
* EVEN THINK ABOUT IMPLEMENTING THIS IN JAVASCRIPT!
*/
[scriptable, builtinclass, uuid(7422b090-4a86-4407-972e-75468a625388)]
[scriptable, uuid(7422b090-4a86-4407-972e-75468a625388)]
interface nsIToolkitProfile : nsISupports
{
/**

View File

@ -52,72 +52,21 @@ using namespace mozilla;
#define DEV_EDITION_NAME "dev-edition-default"
#define DEFAULT_NAME "default"
#define COMPAT_FILE NS_LITERAL_STRING("compatibility.ini")
#define PROFILE_DB_VERSION "2"
#define INSTALL_PREFIX "Install"
#define INSTALL_PREFIX_LENGTH 7
struct KeyValue {
KeyValue(const char* aKey, const char* aValue) :
key(aKey),
value(aValue) { }
nsCString key;
nsCString value;
};
static bool GetStrings(const char* aString, const char* aValue,
void* aClosure) {
nsTArray<UniquePtr<KeyValue>>* array =
static_cast<nsTArray<UniquePtr<KeyValue>>*>(aClosure);
array->AppendElement(MakeUnique<KeyValue>(aString, aValue));
return true;
}
/**
* Returns an array of the strings inside a section of an ini file.
*/
nsTArray<UniquePtr<KeyValue>>
GetSectionStrings(nsINIParser* aParser, const char* aSection) {
nsTArray<UniquePtr<KeyValue>> result;
aParser->GetStrings(aSection, &GetStrings, &result);
return result;
}
nsToolkitProfile::nsToolkitProfile(const nsACString& aName, nsIFile* aRootDir,
nsIFile* aLocalDir, nsToolkitProfile* aPrev,
bool aFromDB)
nsIFile* aLocalDir, nsToolkitProfile* aPrev)
: mPrev(aPrev),
mName(aName),
mRootDir(aRootDir),
mLocalDir(aLocalDir),
mLock(nullptr),
mIndex(0),
mSection("Profile") {
mLock(nullptr) {
NS_ASSERTION(aRootDir, "No file!");
if (aPrev) {
aPrev->mNext = this;
mIndex = aPrev->mIndex + 1;
} else {
nsToolkitProfileService::gService->mFirst = this;
}
mSection.AppendInt(mIndex);
// If this profile isn't in the database already add it.
if (!aFromDB) {
nsINIParser* db = &nsToolkitProfileService::gService->mProfileDB;
db->SetString(mSection.get(), "Name", mName.get());
bool isRelative = false;
nsCString descriptor;
nsToolkitProfileService::gService->GetProfileDescriptor(this, descriptor,
&isRelative);
db->SetString(mSection.get(), "IsRelative", isRelative ? "1" : "0");
db->SetString(mSection.get(), "Path", descriptor.get());
}
}
NS_IMPL_ISUPPORTS(nsToolkitProfile, nsIToolkitProfile)
@ -155,10 +104,6 @@ nsToolkitProfile::SetName(const nsACString& aName) {
nsToolkitProfileService::gService->mDevEditionDefault = nullptr;
}
nsresult rv = nsToolkitProfileService::gService->
mProfileDB.SetString(mSection.get(), "Name", mName.get());
NS_ENSURE_SUCCESS(rv, rv);
mName = aName;
// Setting the name to the dev-edition default profile name will cause this
@ -215,37 +160,12 @@ nsresult nsToolkitProfile::RemoveInternal(bool aRemoveFiles,
}
}
nsINIParser* db = &nsToolkitProfileService::gService->mProfileDB;
db->DeleteSection(mSection.get());
if (mPrev)
mPrev->mNext = mNext;
else
nsToolkitProfileService::gService->mFirst = mNext;
if (mNext) {
// Find the last profile in the list.
nsToolkitProfile* current = mNext;
while (current->mNext) {
current = current->mNext;
}
// Swap it into the current position
current->mIndex = mIndex;
db->RenameSection(current->mSection.get(), mSection.get());
current->mSection = mSection;
if (mNext != current) {
mNext->mPrev = current;
current->mNext = mNext;
}
current->mPrev = mPrev;
if (mPrev) {
mPrev->mNext = current;
} else {
nsToolkitProfileService::gService->mFirst = current;
}
} else if (mPrev) {
mPrev->mNext = nullptr;
} else {
nsToolkitProfileService::gService->mFirst = nullptr;
}
if (mNext) mNext->mPrev = mPrev;
mPrev = nullptr;
mNext = nullptr;
@ -415,7 +335,7 @@ void nsToolkitProfileService::CompleteStartup() {
NS_ENSURE_SUCCESS_VOID(rv);
if (isDefaultApp) {
mProfileDB.SetString(mInstallSection.get(), "Locked", "1");
mInstallData.SetString(mInstallHash.get(), "Locked", "1");
Flush();
}
}
@ -520,7 +440,7 @@ bool nsToolkitProfileService::MaybeMakeDefaultDedicatedProfile(
const nsCString& install = installs[i];
nsCString path;
rv = mProfileDB.GetString(install.get(), "Default", path);
rv = mInstallData.GetString(install.get(), "Default", path);
if (NS_FAILED(rv)) {
continue;
}
@ -532,7 +452,7 @@ bool nsToolkitProfileService::MaybeMakeDefaultDedicatedProfile(
// Is this profile locked to this other install?
nsCString isLocked;
rv = mProfileDB.GetString(install.get(), "Locked", isLocked);
rv = mInstallData.GetString(install.get(), "Locked", isLocked);
if (NS_SUCCEEDED(rv) && isLocked.Equals("1")) {
return false;
}
@ -545,7 +465,7 @@ bool nsToolkitProfileService::MaybeMakeDefaultDedicatedProfile(
for (uint32_t i = 0; i < inUseInstalls.Length(); i++) {
// Removing the default setting entirely will make the install go through
// the first run process again at startup and create itself a new profile.
mProfileDB.DeleteString(inUseInstalls[i].get(), "Default");
mInstallData.DeleteString(inUseInstalls[i].get(), "Default");
}
// Set this as the default profile for this install.
@ -554,7 +474,7 @@ bool nsToolkitProfileService::MaybeMakeDefaultDedicatedProfile(
// SetDefaultProfile will have locked this profile to this install so no
// other installs will steal it, but this was auto-selected so we want to
// unlock it so that other installs can potentially take it.
mProfileDB.DeleteString(mInstallSection.get(), "Locked");
mInstallData.DeleteString(mInstallHash.get(), "Locked");
// Persist the changes.
Flush();
@ -566,33 +486,6 @@ bool nsToolkitProfileService::MaybeMakeDefaultDedicatedProfile(
return true;
}
struct ImportInstallsClosure {
nsINIParser* backupData;
nsINIParser* profileDB;
};
static bool ImportInstalls(const char* aSection, void* aClosure) {
ImportInstallsClosure* closure =
static_cast<ImportInstallsClosure*>(aClosure);
nsTArray<UniquePtr<KeyValue>> strings =
GetSectionStrings(closure->backupData, aSection);
if (strings.IsEmpty()) {
return true;
}
nsCString newSection(INSTALL_PREFIX);
newSection.Append(aSection);
nsCString buffer;
for (uint32_t i = 0; i < strings.Length(); i++) {
closure->profileDB->SetString(newSection.get(), strings[i]->key.get(),
strings[i]->value.get());
}
return true;
}
nsresult nsToolkitProfileService::Init() {
NS_ASSERTION(gDirServiceProvider, "No dirserviceprovider!");
nsresult rv;
@ -603,76 +496,54 @@ nsresult nsToolkitProfileService::Init() {
rv = nsXREDirProvider::GetUserLocalDataDirectory(getter_AddRefs(mTempData));
NS_ENSURE_SUCCESS(rv, rv);
rv = mAppData->Clone(getter_AddRefs(mProfileDBFile));
nsCString installProfilePath;
if (mUseDedicatedProfile) {
// Load the dedicated profiles database.
rv = mAppData->Clone(getter_AddRefs(mInstallFile));
NS_ENSURE_SUCCESS(rv, rv);
rv = mInstallFile->AppendNative(NS_LITERAL_CSTRING("installs.ini"));
NS_ENSURE_SUCCESS(rv, rv);
nsString installHash;
rv = gDirServiceProvider->GetInstallHash(installHash);
NS_ENSURE_SUCCESS(rv, rv);
CopyUTF16toUTF8(installHash, mInstallHash);
rv = mInstallData.Init(mInstallFile);
if (NS_SUCCEEDED(rv)) {
// Try to find the descriptor for the default profile for this install.
rv = mInstallData.GetString(mInstallHash.get(), "Default",
installProfilePath);
// Not having a value means this install doesn't appear in installs.ini so
// this is the first run for this install.
mIsFirstRun = NS_FAILED(rv);
}
}
rv = mAppData->Clone(getter_AddRefs(mListFile));
NS_ENSURE_SUCCESS(rv, rv);
rv = mProfileDBFile->AppendNative(NS_LITERAL_CSTRING("profiles.ini"));
rv = mListFile->AppendNative(NS_LITERAL_CSTRING("profiles.ini"));
NS_ENSURE_SUCCESS(rv, rv);
rv = mAppData->Clone(getter_AddRefs(mInstallDBFile));
NS_ENSURE_SUCCESS(rv, rv);
rv = mInstallDBFile->AppendNative(NS_LITERAL_CSTRING("installs.ini"));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString buffer;
nsINIParser parser;
bool exists;
rv = mProfileDBFile->IsFile(&exists);
rv = mListFile->IsFile(&exists);
if (NS_SUCCEEDED(rv) && exists) {
rv = mProfileDB.Init(mProfileDBFile);
rv = parser.Init(mListFile);
// Init does not fail on parsing errors, only on OOM/really unexpected
// conditions.
if (NS_FAILED(rv)) {
return rv;
}
rv = mProfileDB.GetString("General", "StartWithLastProfile", buffer);
if (NS_SUCCEEDED(rv)) {
mStartWithLast = !buffer.EqualsLiteral("0");
}
rv = mProfileDB.GetString("General", "Version", buffer);
if (NS_FAILED(rv)) {
// This is a profiles.ini written by an older version. We must restore
// any install data from the backup.
nsINIParser installDB;
rv = mInstallDBFile->IsFile(&exists);
if (NS_SUCCEEDED(rv) && exists &&
NS_SUCCEEDED(installDB.Init(mInstallDBFile))) {
// There is install data to import.
ImportInstallsClosure closure = {&installDB, &mProfileDB};
installDB.GetSections(&ImportInstalls, &closure);
}
rv = mProfileDB.SetString("General", "Version", PROFILE_DB_VERSION);
NS_ENSURE_SUCCESS(rv, rv);
}
} else {
rv = mProfileDB.SetString("General", "StartWithLastProfile",
mStartWithLast ? "1" : "0");
NS_ENSURE_SUCCESS(rv, rv);
rv = mProfileDB.SetString("General", "Version", PROFILE_DB_VERSION);
NS_ENSURE_SUCCESS(rv, rv);
}
nsCString installProfilePath;
if (mUseDedicatedProfile) {
nsString installHash;
rv = gDirServiceProvider->GetInstallHash(installHash);
NS_ENSURE_SUCCESS(rv, rv);
CopyUTF16toUTF8(installHash, mInstallSection);
mInstallSection.Insert(INSTALL_PREFIX, 0);
// Try to find the descriptor for the default profile for this install.
rv = mProfileDB.GetString(mInstallSection.get(), "Default",
installProfilePath);
// Not having a value means this install doesn't appear in installs.ini so
// this is the first run for this install.
mIsFirstRun = NS_FAILED(rv);
}
nsAutoCString buffer;
rv = parser.GetString("General", "StartWithLastProfile", buffer);
if (NS_SUCCEEDED(rv) && buffer.EqualsLiteral("0")) mStartWithLast = false;
nsToolkitProfile* currentProfile = nullptr;
@ -704,14 +575,14 @@ nsresult nsToolkitProfileService::Init() {
nsAutoCString profileID("Profile");
profileID.AppendInt(c);
rv = mProfileDB.GetString(profileID.get(), "IsRelative", buffer);
rv = parser.GetString(profileID.get(), "IsRelative", buffer);
if (NS_FAILED(rv)) break;
bool isRelative = buffer.EqualsLiteral("1");
nsAutoCString filePath;
rv = mProfileDB.GetString(profileID.get(), "Path", filePath);
rv = parser.GetString(profileID.get(), "Path", filePath);
if (NS_FAILED(rv)) {
NS_ERROR("Malformed profiles.ini: Path= not found");
continue;
@ -719,7 +590,7 @@ nsresult nsToolkitProfileService::Init() {
nsAutoCString name;
rv = mProfileDB.GetString(profileID.get(), "Name", name);
rv = parser.GetString(profileID.get(), "Name", name);
if (NS_FAILED(rv)) {
NS_ERROR("Malformed profiles.ini: Name= not found");
continue;
@ -748,10 +619,10 @@ nsresult nsToolkitProfileService::Init() {
}
currentProfile =
new nsToolkitProfile(name, rootDir, localDir, currentProfile, true);
new nsToolkitProfile(name, rootDir, localDir, currentProfile);
NS_ENSURE_TRUE(currentProfile, NS_ERROR_OUT_OF_MEMORY);
rv = mProfileDB.GetString(profileID.get(), "Default", buffer);
rv = parser.GetString(profileID.get(), "Default", buffer);
if (NS_SUCCEEDED(rv) && buffer.EqualsLiteral("1")) {
mNormalDefault = currentProfile;
}
@ -773,7 +644,7 @@ nsresult nsToolkitProfileService::Init() {
// If there is only one non-dev-edition profile then mark it as the default.
if (!mNormalDefault && nonDevEditionProfiles == 1) {
SetNormalDefault(autoSelectProfile);
mNormalDefault = autoSelectProfile;
}
if (!mUseDedicatedProfile) {
@ -793,9 +664,6 @@ nsresult nsToolkitProfileService::Init() {
NS_IMETHODIMP
nsToolkitProfileService::SetStartWithLastProfile(bool aValue) {
if (mStartWithLast != aValue) {
nsresult rv = mProfileDB.SetString("General", "StartWithLastProfile",
mStartWithLast ? "1" : "0");
NS_ENSURE_SUCCESS(rv, rv);
mStartWithLast = aValue;
}
return NS_OK;
@ -854,27 +722,6 @@ nsToolkitProfileService::GetDefaultProfile(nsIToolkitProfile** aResult) {
return NS_OK;
}
void
nsToolkitProfileService::SetNormalDefault(nsIToolkitProfile* aProfile) {
if (mNormalDefault == aProfile) {
return;
}
if (mNormalDefault) {
nsToolkitProfile* profile =
static_cast<nsToolkitProfile*>(mNormalDefault.get());
mProfileDB.DeleteString(profile->mSection.get(), "Default");
}
mNormalDefault = aProfile;
if (mNormalDefault) {
nsToolkitProfile* profile =
static_cast<nsToolkitProfile*>(mNormalDefault.get());
mProfileDB.SetString(profile->mSection.get(), "Default", "1");
}
}
NS_IMETHODIMP
nsToolkitProfileService::SetDefaultProfile(nsIToolkitProfile* aProfile) {
if (mUseDedicatedProfile) {
@ -883,20 +730,20 @@ nsToolkitProfileService::SetDefaultProfile(nsIToolkitProfile* aProfile) {
// Setting this to the empty string means no profile will be found on
// startup but we'll recognise that this install has been used
// previously.
mProfileDB.SetString(mInstallSection.get(), "Default", "");
mInstallData.SetString(mInstallHash.get(), "Default", "");
} else {
nsCString profilePath;
nsresult rv = GetProfileDescriptor(aProfile, profilePath, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
mProfileDB.SetString(mInstallSection.get(), "Default",
profilePath.get());
mInstallData.SetString(mInstallHash.get(), "Default",
profilePath.get());
}
mDedicatedProfile = aProfile;
// Some kind of choice has happened here, lock this profile to this
// install.
mProfileDB.SetString(mInstallSection.get(), "Locked", "1");
mInstallData.SetString(mInstallHash.get(), "Locked", "1");
}
return NS_OK;
}
@ -906,8 +753,7 @@ nsToolkitProfileService::SetDefaultProfile(nsIToolkitProfile* aProfile) {
return NS_ERROR_FAILURE;
}
SetNormalDefault(aProfile);
mNormalDefault = aProfile;
return NS_OK;
}
@ -948,7 +794,7 @@ nsresult nsToolkitProfileService::GetProfileDescriptor(
}
nsresult nsToolkitProfileService::CreateDefaultProfile(
nsIToolkitProfile** aResult) {
nsIToolkitProfile** aResult) {
// Create a new default profile
nsAutoCString name;
if (mUseDevEditionProfile) {
@ -967,7 +813,7 @@ nsresult nsToolkitProfileService::CreateDefaultProfile(
} else if (mUseDevEditionProfile) {
mDevEditionDefault = mCurrent;
} else {
SetNormalDefault(mCurrent);
mNormalDefault = mCurrent;
}
return NS_OK;
@ -1319,10 +1165,8 @@ nsresult nsToolkitProfileService::SelectStartupProfile(
// auto-selected.
if ((mUseDedicatedProfile || mUseDevEditionProfile) && mFirst &&
!mFirst->mNext) {
nsCOMPtr<nsIToolkitProfile> newProfile;
CreateProfile(nullptr, NS_LITERAL_CSTRING(DEFAULT_NAME),
getter_AddRefs(newProfile));
SetNormalDefault(newProfile);
getter_AddRefs(mNormalDefault));
}
Flush();
@ -1405,13 +1249,14 @@ nsresult nsToolkitProfileService::ApplyResetProfile(
// If the old profile would have been the default for old installs then mark
// the new profile as such.
if (mNormalDefault == aOldProfile) {
SetNormalDefault(mCurrent);
mNormalDefault = mCurrent;
}
if (mUseDedicatedProfile && mDedicatedProfile == aOldProfile) {
bool wasLocked = false;
nsCString val;
if (NS_SUCCEEDED(mProfileDB.GetString(mInstallSection.get(), "Locked", val))) {
if (NS_SUCCEEDED(
mInstallData.GetString(mInstallHash.get(), "Locked", val))) {
wasLocked = val.Equals("1");
}
@ -1419,7 +1264,7 @@ nsresult nsToolkitProfileService::ApplyResetProfile(
// Make the locked state match if necessary.
if (!wasLocked) {
mProfileDB.DeleteString(mInstallSection.get(), "Locked");
mInstallData.DeleteString(mInstallHash.get(), "Locked");
}
}
@ -1612,7 +1457,7 @@ nsToolkitProfileService::CreateProfile(nsIFile* aRootDir,
}
nsCOMPtr<nsIToolkitProfile> profile =
new nsToolkitProfile(aName, rootDir, localDir, last, false);
new nsToolkitProfile(aName, rootDir, localDir, last);
if (!profile) return NS_ERROR_OUT_OF_MEMORY;
if (aName.Equals(DEV_EDITION_NAME)) {
@ -1651,11 +1496,6 @@ struct FindInstallsClosure {
static bool FindInstalls(const char* aSection, void* aClosure) {
FindInstallsClosure* closure = static_cast<FindInstallsClosure*>(aClosure);
// Check if the section starts with "Install"
if (strncmp(aSection, INSTALL_PREFIX, INSTALL_PREFIX_LENGTH) != 0) {
return true;
}
nsCString install(aSection);
closure->installs->AppendElement(install);
@ -1664,9 +1504,9 @@ static bool FindInstalls(const char* aSection, void* aClosure) {
nsTArray<nsCString> nsToolkitProfileService::GetKnownInstalls() {
nsTArray<nsCString> result;
FindInstallsClosure closure = {&mProfileDB, &result};
FindInstallsClosure closure = {&mInstallData, &result};
mProfileDB.GetSections(&FindInstalls, &closure);
mInstallData.GetSections(&FindInstalls, &closure);
return result;
}
@ -1718,59 +1558,71 @@ NS_IMETHODIMP
nsToolkitProfileService::Flush() {
nsresult rv;
// If we aren't using dedicated profiles then nothing about the list of
// installs can have changed, so no need to update the backup.
if (mUseDedicatedProfile) {
// Export the installs to the backup.
nsTArray<nsCString> installs = GetKnownInstalls();
if (!installs.IsEmpty()) {
nsCString data;
nsCString buffer;
for (uint32_t i = 0; i < installs.Length(); i++) {
nsTArray<UniquePtr<KeyValue>> strings =
GetSectionStrings(&mProfileDB, installs[i].get());
if (strings.IsEmpty()) {
continue;
}
// Strip "Install" from the start.
const nsDependentCSubstring& install = Substring(installs[i],
INSTALL_PREFIX_LENGTH);
data.AppendPrintf("[%s]\n", PromiseFlatCString(install).get());
for (uint32_t j = 0; j < strings.Length(); j++) {
data.AppendPrintf("%s=%s\n",
strings[j]->key.get(), strings[j]->value.get());
}
data.Append("\n");
}
FILE* writeFile;
rv = mInstallDBFile->OpenANSIFileDesc("w", &writeFile);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t length = data.Length();
if (fwrite(data.get(), sizeof(char), length, writeFile) != length) {
fclose(writeFile);
return NS_ERROR_UNEXPECTED;
}
fclose(writeFile);
} else {
rv = mInstallDBFile->Remove(false);
if (NS_FAILED(rv) && rv != NS_ERROR_FILE_TARGET_DOES_NOT_EXIST &&
rv != NS_ERROR_FILE_NOT_FOUND) {
return rv;
}
}
rv = mInstallData.WriteToFile(mInstallFile);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = mProfileDB.WriteToFile(mProfileDBFile);
// Errors during writing might cause unhappy semi-written files.
// To avoid this, write the entire thing to a buffer, then write
// that buffer to disk.
uint32_t pCount = 0;
nsToolkitProfile* cur;
for (cur = mFirst; cur != nullptr; cur = cur->mNext) ++pCount;
uint32_t length;
const int bufsize = 100 + MAXPATHLEN * pCount;
auto buffer = MakeUnique<char[]>(bufsize);
char* pos = buffer.get();
char* end = pos + bufsize;
pos += snprintf(pos, end - pos,
"[General]\n"
"StartWithLastProfile=%s\n\n",
mStartWithLast ? "1" : "0");
nsAutoCString path;
cur = mFirst;
pCount = 0;
while (cur) {
bool isRelative;
nsresult rv = GetProfileDescriptor(cur, path, &isRelative);
NS_ENSURE_SUCCESS(rv, rv);
pos +=
snprintf(pos, end - pos,
"[Profile%u]\n"
"Name=%s\n"
"IsRelative=%s\n"
"Path=%s\n",
pCount, cur->mName.get(), isRelative ? "1" : "0", path.get());
if (cur == mNormalDefault) {
pos += snprintf(pos, end - pos, "Default=1\n");
}
pos += snprintf(pos, end - pos, "\n");
cur = cur->mNext;
++pCount;
}
FILE* writeFile;
rv = mListFile->OpenANSIFileDesc("w", &writeFile);
NS_ENSURE_SUCCESS(rv, rv);
length = pos - buffer.get();
if (fwrite(buffer.get(), sizeof(char), length, writeFile) != length) {
fclose(writeFile);
return NS_ERROR_UNEXPECTED;
}
fclose(writeFile);
return NS_OK;
}

View File

@ -28,7 +28,7 @@ class nsToolkitProfile final : public nsIToolkitProfile {
~nsToolkitProfile() = default;
nsToolkitProfile(const nsACString& aName, nsIFile* aRootDir,
nsIFile* aLocalDir, nsToolkitProfile* aPrev, bool aFromDB);
nsIFile* aLocalDir, nsToolkitProfile* aPrev);
nsresult RemoveInternal(bool aRemoveFiles, bool aInBackground);
@ -38,8 +38,6 @@ class nsToolkitProfile final : public nsIToolkitProfile {
nsCOMPtr<nsIFile> mRootDir;
nsCOMPtr<nsIFile> mLocalDir;
nsIProfileLock* mLock;
uint32_t mIndex;
nsCString mSection;
};
class nsToolkitProfileLock final : public nsIProfileLock {
@ -105,7 +103,6 @@ class nsToolkitProfileService final : public nsIToolkitProfileService {
bool MaybeMakeDefaultDedicatedProfile(nsIToolkitProfile* aProfile);
bool IsSnapEnvironment();
nsresult CreateDefaultProfile(nsIToolkitProfile** aResult);
void SetNormalDefault(nsIToolkitProfile* aProfile);
// Returns the known install hashes from the installs database. Modifying the
// installs database is safe while iterating the returned array.
@ -129,13 +126,13 @@ class nsToolkitProfileService final : public nsIToolkitProfileService {
// The directory that holds the cache files for profiles.
nsCOMPtr<nsIFile> mTempData;
// The location of profiles.ini.
nsCOMPtr<nsIFile> mProfileDBFile;
nsCOMPtr<nsIFile> mListFile;
// The location of installs.ini.
nsCOMPtr<nsIFile> mInstallDBFile;
// The data loaded from profiles.ini.
nsINIParser mProfileDB;
// The section in the profiles db for the current install.
nsCString mInstallSection;
nsCOMPtr<nsIFile> mInstallFile;
// The data loaded from installs.ini.
nsINIParser mInstallData;
// The install hash for the currently running install.
nsCString mInstallHash;
// Whether to start with the selected profile by default.
bool mStartWithLast;
// True if during startup it appeared that this is the first run.

View File

@ -169,7 +169,7 @@ function writeProfilesIni(profileData) {
getService(Ci.nsIINIParserFactory);
let ini = factory.createINIParser().QueryInterface(Ci.nsIINIParserWriter);
const { options = {}, profiles = [], installs = null } = profileData;
const { options = {}, profiles = [] } = profileData;
let { startWithLastProfile = true } = options;
ini.setString("General", "StartWithLastProfile", startWithLastProfile ? "1" : "0");
@ -187,21 +187,6 @@ function writeProfilesIni(profileData) {
}
}
if (installs) {
ini.setString("General", "Version", "2");
for (let hash of Object.keys(installs)) {
ini.setString(`Install${hash}`, "Default", installs[hash].default);
if ("locked" in installs[hash]) {
ini.setString(`Install${hash}`, "Locked", installs[hash].locked ? "1" : "0");
}
}
writeInstallsIni({ installs });
} else {
writeInstallsIni(null);
}
ini.writeFile(target);
}
@ -220,7 +205,6 @@ function readProfilesIni() {
startWithLastProfile: true,
},
profiles: [],
installs: null,
};
if (!target.exists()) {
@ -232,52 +216,29 @@ function readProfilesIni() {
let ini = factory.createINIParser(target);
profileData.options.startWithLastProfile = safeGet(ini, "General", "StartWithLastProfile") == "1";
if (safeGet(ini, "General", "Version") == "2") {
profileData.installs = {};
}
let sections = ini.getSections();
while (sections.hasMore()) {
let section = sections.getNext();
for (let i = 0; true; i++) {
let section = `Profile${i}`;
if (section == "General") {
continue;
let isRelative = safeGet(ini, section, "IsRelative");
if (isRelative === null) {
break;
}
Assert.equal(isRelative, "1", "Paths should always be relative in these tests.");
let profile = {
name: safeGet(ini, section, "Name"),
path: safeGet(ini, section, "Path"),
};
try {
profile.default = ini.getString(section, "Default") == "1";
Assert.ok(profile.default, "The Default value is only written when true.");
} catch (e) {
profile.default = false;
}
if (section.startsWith("Profile")) {
let isRelative = safeGet(ini, section, "IsRelative");
if (isRelative === null) {
break;
}
Assert.equal(isRelative, "1", "Paths should always be relative in these tests.");
let profile = {
name: safeGet(ini, section, "Name"),
path: safeGet(ini, section, "Path"),
};
try {
profile.default = ini.getString(section, "Default") == "1";
Assert.ok(profile.default, "The Default value is only written when true.");
} catch (e) {
profile.default = false;
}
profileData.profiles.push(profile);
}
if (section.startsWith("Install")) {
Assert.ok(profileData.installs, "Should only see an install section if the ini version was correct.");
profileData.installs[section.substring(7)] = {
default: safeGet(ini, section, "Default"),
};
let locked = safeGet(ini, section, "Locked");
if (locked !== null) {
profileData.installs[section.substring(7)].locked = locked;
}
}
profileData.profiles.push(profile);
}
profileData.profiles.sort((a, b) => a.name.localeCompare(b.name));
@ -294,14 +255,6 @@ function writeInstallsIni(installData) {
let target = gDataHome.clone();
target.append("installs.ini");
if (!installData) {
try {
target.remove(false);
} catch (e) {
}
return;
}
const { installs = {} } = installData;
let factory = Cc["@mozilla.org/xpcom/ini-parser-factory;1"].
@ -330,7 +283,6 @@ function readInstallsIni() {
};
if (!target.exists()) {
dump("Missing installs.ini\n");
return installData;
}
@ -344,37 +296,19 @@ function readInstallsIni() {
if (hash != "General") {
installData.installs[hash] = {
default: safeGet(ini, hash, "Default"),
locked: safeGet(ini, hash, "Locked") == 1,
};
let locked = safeGet(ini, hash, "Locked");
if (locked !== null) {
installData.installs[hash].locked = locked;
}
}
}
return installData;
}
/**
* Check that the backup data in installs.ini matches the install data in
* profiles.ini.
*/
function checkBackup(profileData = readProfilesIni(), installData = readInstallsIni()) {
if (!profileData.installs) {
// If the profiles db isn't of the right version we wouldn't expect the
// backup to be accurate.
return;
}
Assert.deepEqual(profileData.installs, installData.installs, "Backup installs.ini should match installs in profiles.ini");
}
/**
* Checks that the profile service seems to have the right data in it compared
* to profile and install data structured as in the above functions.
*/
function checkProfileService(profileData = readProfilesIni(), verifyBackup = true) {
function checkProfileService(profileData = readProfilesIni(), installData = readInstallsIni()) {
let service = getProfileService();
let serviceProfiles = Array.from(service.profiles);
@ -386,8 +320,7 @@ function checkProfileService(profileData = readProfilesIni(), verifyBackup = tru
profileData.profiles.sort((a, b) => a.name.localeCompare(b.name));
let hash = xreDirProvider.getInstallHash();
let defaultPath = (profileData.installs && hash in profileData.installs) ?
profileData.installs[hash].default : null;
let defaultPath = hash in installData.installs ? installData.installs[hash].default : null;
let dedicatedProfile = null;
let snapProfile = null;
@ -419,10 +352,6 @@ function checkProfileService(profileData = readProfilesIni(), verifyBackup = tru
} else {
Assert.equal(service.defaultProfile, dedicatedProfile, "Should have seen the right profile selected.");
}
if (verifyBackup) {
checkBackup(profileData);
}
}
/**

View File

@ -1,41 +0,0 @@
/*
* Tests that when the profiles DB is missing the install data we reload it.
*/
add_task(async () => {
let hash = xreDirProvider.getInstallHash();
let profileData = {
options: {
startWithLastProfile: true,
},
profiles: [{
name: "Profile1",
path: "Path1",
}, {
name: "Profile2",
path: "Path2",
}],
};
let installs = {
[hash]: {
default: "Path2",
},
};
writeProfilesIni(profileData);
writeInstallsIni({ installs });
let { profile, didCreate } = selectStartupProfile();
checkStartupReason("default");
let service = getProfileService();
// Should have added the backup data to the service, check that is true.
profileData.installs = installs;
checkProfileService(profileData);
Assert.ok(!didCreate, "Should not have created a new profile.");
Assert.equal(profile.name, "Profile2", "Should have selected the right profile");
Assert.ok(!service.createdAlternateProfile, "Should not have created an alternate profile.");
});

View File

@ -14,6 +14,10 @@ add_task(async () => {
path: defaultProfile.leafName,
default: true,
}],
});
let hash = xreDirProvider.getInstallHash();
writeProfilesIni({
installs: {
other: {
default: defaultProfile.leafName,
@ -25,16 +29,16 @@ add_task(async () => {
let { profile: selectedProfile, didCreate } = selectStartupProfile();
let profileData = readProfilesIni();
let installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 2, "Should have the right number of profiles.");
let hash = xreDirProvider.getInstallHash();
Assert.equal(Object.keys(profileData.installs).length, 2, "Should be two known installs.");
Assert.notEqual(profileData.installs[hash].default, defaultProfile.leafName, "Should not have marked the original default profile as the default for this install.");
Assert.ok(profileData.installs[hash].locked, "Should have locked as we created this profile for this install.");
Assert.equal(Object.keys(installData.installs).length, 1, "Should be two known installs.");
Assert.notEqual(installData.installs[hash].default, defaultProfile.leafName, "Should not have marked the original default profile as the default for this install.");
Assert.ok(installData.installs[hash].locked, "Should have locked as we created this profile for this install.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
Assert.ok(didCreate, "Should have created a new profile.");
Assert.ok(!selectedProfile.rootDir.equals(defaultProfile), "Should be using a different directory.");

View File

@ -18,6 +18,7 @@ add_task(async () => {
service.flush();
let profileData = readProfilesIni();
let installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 1, "Should have the right number of profiles.");
@ -27,14 +28,15 @@ add_task(async () => {
Assert.ok(!profile.default, "Should not be marked as the old-style default.");
// The new profile hasn't been marked as the default yet!
Assert.equal(Object.keys(profileData.installs).length, 0, "Should be no defaults for installs yet.");
Assert.equal(Object.keys(installData.installs).length, 0, "Should be no defaults for installs yet.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
service.defaultProfile = newProfile;
service.flush();
profileData = readProfilesIni();
installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 1, "Should have the right number of profiles.");
@ -44,10 +46,10 @@ add_task(async () => {
Assert.ok(!profile.default, "Should not be marked as the old-style default.");
let hash = xreDirProvider.getInstallHash();
Assert.equal(Object.keys(profileData.installs).length, 1, "Should be only one known install.");
Assert.equal(profileData.installs[hash].default, profileData.profiles[0].path, "Should have marked the new profile as the default for this install.");
Assert.equal(Object.keys(installData.installs).length, 1, "Should be only one known install.");
Assert.equal(installData.installs[hash].default, profileData.profiles[0].path, "Should have marked the new profile as the default for this install.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
let otherProfile = service.createProfile(null, "another");
service.defaultProfile = otherProfile;
@ -55,6 +57,7 @@ add_task(async () => {
service.flush();
profileData = readProfilesIni();
installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 2, "Should have the right number of profiles.");
@ -67,15 +70,16 @@ add_task(async () => {
Assert.equal(profile.name, "dedicated", "Should have the right name.");
Assert.ok(!profile.default, "Should not be marked as the old-style default.");
Assert.equal(Object.keys(profileData.installs).length, 1, "Should be only one known install.");
Assert.equal(profileData.installs[hash].default, profileData.profiles[0].path, "Should have marked the new profile as the default for this install.");
Assert.equal(Object.keys(installData.installs).length, 1, "Should be only one known install.");
Assert.equal(installData.installs[hash].default, profileData.profiles[0].path, "Should have marked the new profile as the default for this install.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
newProfile.remove(true);
service.flush();
profileData = readProfilesIni();
installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 1, "Should have the right number of profiles.");
@ -84,22 +88,23 @@ add_task(async () => {
Assert.equal(profile.name, "another", "Should have the right name.");
Assert.ok(!profile.default, "Should not be marked as the old-style default.");
Assert.equal(Object.keys(profileData.installs).length, 1, "Should be only one known install.");
Assert.equal(profileData.installs[hash].default, profileData.profiles[0].path, "Should have marked the new profile as the default for this install.");
Assert.equal(Object.keys(installData.installs).length, 1, "Should be only one known install.");
Assert.equal(installData.installs[hash].default, profileData.profiles[0].path, "Should have marked the new profile as the default for this install.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
otherProfile.remove(true);
service.flush();
profileData = readProfilesIni();
installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 0, "Should have the right number of profiles.");
// We leave a reference to the missing profile to stop us trying to steal the
// old-style default profile on next startup.
Assert.equal(Object.keys(profileData.installs).length, 1, "Should be only one known install.");
Assert.equal(Object.keys(installData.installs).length, 1, "Should be only one known install.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
});

View File

@ -9,7 +9,8 @@ add_task(async () => {
checkStartupReason("firstrun-created-default");
let profileData = readProfilesIni();
checkProfileService(profileData);
let installData = readInstallsIni();
checkProfileService(profileData, installData);
Assert.ok(didCreate, "Should have created a new profile.");
Assert.equal(profile, service.defaultProfile, "Should now be the default profile.");
@ -28,5 +29,5 @@ add_task(async () => {
Assert.ok(!profile.default, "Should not be marked as the old-style default.");
let hash = xreDirProvider.getInstallHash();
Assert.ok(profileData.installs[hash].locked, "Should have locked the profile");
Assert.ok(installData.installs[hash].locked, "Should have locked the profile");
});

View File

@ -21,6 +21,7 @@ add_task(async () => {
let hash = xreDirProvider.getInstallHash();
let profileData = readProfilesIni();
let installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 1, "Should have the right number of profiles.");
@ -30,11 +31,11 @@ add_task(async () => {
Assert.equal(profile.path, defaultProfile.leafName, "Should be the original default profile.");
Assert.ok(profile.default, "Should be marked as the old-style default.");
Assert.equal(Object.keys(profileData.installs).length, 1, "Should be only one known install.");
Assert.equal(profileData.installs[hash].default, defaultProfile.leafName, "Should have marked the original default profile as the default for this install.");
Assert.ok(profileData.installs[hash].locked, "Should have locked as we're the default app.");
Assert.equal(Object.keys(installData.installs).length, 1, "Should be only one known install.");
Assert.equal(installData.installs[hash].default, defaultProfile.leafName, "Should have marked the original default profile as the default for this install.");
Assert.ok(installData.installs[hash].locked, "Should have locked as we're the default app.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
Assert.ok(!didCreate, "Should not have created a new profile.");
Assert.ok(selectedProfile.rootDir.equals(defaultProfile), "Should be using the right directory.");

View File

@ -1,37 +0,0 @@
/**
* When profiles.ini is missing there isn't any point in restoring from any
* installs.ini, the profiles it refers to are gone anyway.
*/
add_task(async () => {
let hash = xreDirProvider.getInstallHash();
let installs = {
[hash]: {
default: "Path2",
},
otherhash: {
default: "foo",
},
anotherhash: {
default: "bar",
},
};
writeInstallsIni({ installs });
let { profile, didCreate } = selectStartupProfile();
checkStartupReason("firstrun-created-default");
let service = getProfileService();
Assert.ok(didCreate, "Should have created a new profile.");
Assert.equal(profile.name, DEDICATED_NAME, "Should have created the right profile");
Assert.ok(!service.createdAlternateProfile, "Should not have created an alternate profile.");
let profilesData = readProfilesIni();
Assert.equal(Object.keys(profilesData.installs).length, 1, "Should be only one known install");
Assert.ok(hash in profilesData.installs, "Should be the expected install.");
Assert.notEqual(profilesData.installs[hash].default, "Path2", "Didn't import the previous data.");
checkProfileService(profilesData);
});

View File

@ -31,6 +31,7 @@ add_task(async () => {
let hash = xreDirProvider.getInstallHash();
let profileData = readProfilesIni();
let installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 3, "Should have the right number of profiles.");
@ -50,16 +51,16 @@ add_task(async () => {
Assert.equal(profile.path, mydefaultProfile.leafName, "Should be the original default profile.");
Assert.ok(profile.default, "Should be marked as the old-style default.");
Assert.equal(Object.keys(profileData.installs).length, 1, "Should be only one known install.");
Assert.equal(Object.keys(installData.installs).length, 1, "Should be only one known install.");
if (AppConstants.MOZ_DEV_EDITION) {
Assert.equal(profileData.installs[hash].default, devDefaultProfile.leafName, "Should have marked the original dev default profile as the default for this install.");
Assert.equal(installData.installs[hash].default, devDefaultProfile.leafName, "Should have marked the original dev default profile as the default for this install.");
} else {
Assert.equal(profileData.installs[hash].default, mydefaultProfile.leafName, "Should have marked the original default profile as the default for this install.");
Assert.equal(installData.installs[hash].default, mydefaultProfile.leafName, "Should have marked the original default profile as the default for this install.");
}
Assert.ok(!profileData.installs[hash].locked, "Should not be locked as we're not the default app.");
Assert.ok(!installData.installs[hash].locked, "Should not be locked as we're not the default app.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
Assert.ok(!didCreate, "Should not have created a new profile.");
if (AppConstants.MOZ_DEV_EDITION) {

View File

@ -16,6 +16,9 @@ add_task(async () => {
path: defaultProfile.leafName,
default: true,
}],
});
writeInstallsIni({
installs: {
[hash]: {
default: "foobar",
@ -27,6 +30,7 @@ add_task(async () => {
testStartsProfileManager();
let profileData = readProfilesIni();
let installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 1, "Should have the right number of profiles.");
@ -38,7 +42,7 @@ add_task(async () => {
Assert.ok(profile.default, "Should be marked as the old-style default.");
// We keep the data here so we don't steal on the next reboot...
Assert.equal(Object.keys(profileData.installs).length, 1, "Still list the broken reference.");
Assert.equal(Object.keys(installData.installs).length, 1, "Still list the broken reference.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
});

View File

@ -13,23 +13,27 @@ add_task(async () => {
path: defaultProfile.leafName,
default: true,
}],
};
writeProfilesIni(profilesIni);
let installsIni = {
installs: {
[hash]: {
default: defaultProfile.leafName,
},
},
};
writeProfilesIni(profilesIni);
writeInstallsIni(installsIni);
let service = getProfileService();
checkProfileService(profilesIni);
checkProfileService(profilesIni, installsIni);
let { profile, didCreate } = selectStartupProfile();
Assert.ok(!didCreate, "Should have not created a new profile.");
Assert.equal(profile.name, "default", "Should have selected the default profile.");
Assert.equal(profile, service.defaultProfile, "Should have selected the default profile.");
checkProfileService(profilesIni);
checkProfileService(profilesIni, installsIni);
// In an actual run of Firefox we wouldn't be able to delete the profile in
// use because it would be locked. But we don't actually lock the profile in
@ -41,10 +45,9 @@ add_task(async () => {
// These are the modifications that should have been made.
profilesIni.profiles.pop();
profilesIni.installs[hash].default = "";
installsIni.installs[hash].default = "";
// The data isn't flushed to disk so don't check the backup here.
checkProfileService(profilesIni, false);
checkProfileService(profilesIni, installsIni);
service.flush();
@ -53,6 +56,6 @@ add_task(async () => {
// checkProfileService doesn't differentiate between a blank default profile
// for the install and a missing install.
profilesIni = readProfilesIni();
Assert.equal(profilesIni.installs[hash].default, "", "Should be a blank default profile.");
let installs = readInstallsIni();
Assert.equal(installs.installs[hash].default, "", "Should be a blank default profile.");
});

View File

@ -16,6 +16,8 @@ add_task(async () => {
name: "Profile3",
path: "Path3",
}],
};
let installData = {
installs: {
[hash]: {
default: "Path2",
@ -41,6 +43,7 @@ add_task(async () => {
}
writeProfilesIni(profileData);
writeInstallsIni(installData);
let { profile, didCreate } = selectStartupProfile();
checkStartupReason("default");

View File

@ -22,6 +22,7 @@ add_task(async () => {
let hash = xreDirProvider.getInstallHash();
let profileData = readProfilesIni();
let installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 1, "Should have the right number of profiles.");
@ -31,11 +32,11 @@ add_task(async () => {
Assert.equal(profile.path, defaultProfile.leafName, "Should be the original default profile.");
Assert.ok(profile.default, "Should be marked as the old-style default.");
Assert.equal(Object.keys(profileData.installs).length, 1, "Should be only one known install.");
Assert.equal(profileData.installs[hash].default, defaultProfile.leafName, "Should have marked the original default profile as the default for this install.");
Assert.ok(!profileData.installs[hash].locked, "Should not have locked as we're not the default app.");
Assert.equal(Object.keys(installData.installs).length, 1, "Should be only one known install.");
Assert.equal(installData.installs[hash].default, defaultProfile.leafName, "Should have marked the original default profile as the default for this install.");
Assert.ok(!installData.installs[hash].locked, "Should not have locked as we're not the default app.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
Assert.ok(!didCreate, "Should not have created a new profile.");
let service = getProfileService();

View File

@ -23,6 +23,7 @@ add_task(async () => {
let service = getProfileService();
let profileData = readProfilesIni();
let installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 1, "Should have the right number of profiles.");
@ -32,9 +33,9 @@ add_task(async () => {
Assert.equal(profile.path, defaultProfile.leafName, "Should be the original default profile.");
Assert.ok(!profile.default, "Should not be marked as the old-style default.");
Assert.ok(!profileData.installs, "Should be no defaults for installs yet.");
Assert.equal(Object.keys(installData.installs).length, 0, "Should be no defaults for installs yet.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
let { profile: selectedProfile, didCreate } = selectStartupProfile();
checkStartupReason("firstrun-skipped-default");

View File

@ -26,7 +26,10 @@ add_task(async () => {
name: "Profile3",
path: "Path3",
}],
// Another install is using the profile and it is locked.
};
// Another install is using the profile and it is locked.
let installData = {
installs: {
otherinstall: {
default: root.leafName,
@ -36,7 +39,8 @@ add_task(async () => {
};
writeProfilesIni(profileData);
checkProfileService(profileData);
writeInstallsIni(installData);
checkProfileService(profileData, installData);
let env = Cc["@mozilla.org/process/environment;1"].
getService(Ci.nsIEnvironment);
@ -69,9 +73,10 @@ add_task(async () => {
Assert.ok(!profileData.profiles[1].default, "Should not be the old default profile.");
let hash = xreDirProvider.getInstallHash();
Assert.equal(Object.keys(profileData.installs).length, 2, "Should be one known install.");
Assert.notEqual(profileData.installs[hash].default, root.leafName, "Should have marked the original default profile as the default for this install.");
Assert.ok(profileData.installs[hash].locked, "Should have locked as we created the profile for this install.");
Assert.equal(profileData.installs.otherinstall.default, root.leafName, "Should have left the other profile as the default for the other install.");
Assert.ok(profileData.installs[hash].locked, "Should still be locked to the other install.");
installData = readInstallsIni();
Assert.equal(Object.keys(installData.installs).length, 2, "Should be one known install.");
Assert.notEqual(installData.installs[hash].default, root.leafName, "Should have marked the original default profile as the default for this install.");
Assert.ok(installData.installs[hash].locked, "Should have locked as we created the profile for this install.");
Assert.equal(installData.installs.otherinstall.default, root.leafName, "Should have left the other profile as the default for the other install.");
Assert.ok(installData.installs[hash].locked, "Should still be locked to the other install.");
});

View File

@ -26,7 +26,10 @@ add_task(async () => {
name: "Profile3",
path: "Path3",
}],
// Another install is using the profile but it isn't locked.
};
// Another install is using the profile but it isn't locked.
let installData = {
installs: {
otherinstall: {
default: root.leafName,
@ -35,7 +38,8 @@ add_task(async () => {
};
writeProfilesIni(profileData);
checkProfileService(profileData);
writeInstallsIni(installData);
checkProfileService(profileData, installData);
let env = Cc["@mozilla.org/process/environment;1"].
getService(Ci.nsIEnvironment);
@ -60,8 +64,9 @@ add_task(async () => {
Assert.ok(profileData.profiles[0].default, "Should still be the old default profile.");
let hash = xreDirProvider.getInstallHash();
installData = readInstallsIni();
// The info about the other install will have been removed so it goes through first run on next startup.
Assert.equal(Object.keys(profileData.installs).length, 1, "Should be one known install.");
Assert.equal(profileData.installs[hash].default, root.leafName, "Should have marked the original default profile as the default for this install.");
Assert.ok(!profileData.installs[hash].locked, "Should not have locked as we're not the default app.");
Assert.equal(Object.keys(installData.installs).length, 1, "Should be one known install.");
Assert.equal(installData.installs[hash].default, root.leafName, "Should have marked the original default profile as the default for this install.");
Assert.ok(!installData.installs[hash].locked, "Should not have locked as we're not the default app.");
});

View File

@ -28,7 +28,10 @@ add_task(async () => {
name: "Profile3",
path: "Path3",
}],
// Another install is using the profile but it isn't locked.
};
// Another install is using the profile but it isn't locked.
let installData = {
installs: {
otherinstall: {
default: root.leafName,
@ -37,7 +40,8 @@ add_task(async () => {
};
writeProfilesIni(profileData);
checkProfileService(profileData);
writeInstallsIni(installData);
checkProfileService(profileData, installData);
let env = Cc["@mozilla.org/process/environment;1"].
getService(Ci.nsIEnvironment);
@ -62,8 +66,9 @@ add_task(async () => {
Assert.ok(profileData.profiles[0].default, "Should still be the old default profile.");
let hash = xreDirProvider.getInstallHash();
installData = readInstallsIni();
// The info about the other install will have been removed so it goes through first run on next startup.
Assert.equal(Object.keys(profileData.installs).length, 1, "Should be one known install.");
Assert.equal(profileData.installs[hash].default, root.leafName, "Should have marked the original default profile as the default for this install.");
Assert.ok(profileData.installs[hash].locked, "Should have locked as we're the default app.");
Assert.equal(Object.keys(installData.installs).length, 1, "Should be one known install.");
Assert.equal(installData.installs[hash].default, root.leafName, "Should have marked the original default profile as the default for this install.");
Assert.ok(installData.installs[hash].locked, "Should have locked as we're the default app.");
});

View File

@ -14,6 +14,8 @@ add_task(async () => {
path: defaultProfile.leafName,
default: true,
}],
});
writeInstallsIni({
installs: {
otherhash: {
default: defaultProfile.leafName,
@ -27,6 +29,7 @@ add_task(async () => {
let hash = xreDirProvider.getInstallHash();
let profileData = readProfilesIni();
let installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 1, "Should have the right number of profiles.");
@ -36,11 +39,11 @@ add_task(async () => {
Assert.equal(profile.path, defaultProfile.leafName, "Should be the original default profile.");
Assert.ok(profile.default, "Should be marked as the old-style default.");
Assert.equal(Object.keys(profileData.installs).length, 1, "Should only be one known installs.");
Assert.equal(profileData.installs[hash].default, defaultProfile.leafName, "Should have taken the original default profile as the default for the current install.");
Assert.ok(!profileData.installs[hash].locked, "Should not have locked as we're not the default app.");
Assert.equal(Object.keys(installData.installs).length, 1, "Should only be one known installs.");
Assert.equal(installData.installs[hash].default, defaultProfile.leafName, "Should have taken the original default profile as the default for the current install.");
Assert.ok(!installData.installs[hash].locked, "Should not have locked as we're not the default app.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
Assert.ok(!didCreate, "Should not have created a new profile.");
Assert.ok(!service.createdAlternateProfile, "Should not have created an alternate profile.");

View File

@ -22,6 +22,7 @@ add_task(async () => {
let hash = xreDirProvider.getInstallHash();
let profileData = readProfilesIni();
let installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 1, "Should have the right number of profiles.");
@ -31,11 +32,11 @@ add_task(async () => {
Assert.equal(profile.path, defaultProfile.leafName, "Should be the original default profile.");
Assert.ok(profile.default, "Should be marked as the old-style default.");
Assert.equal(Object.keys(profileData.installs).length, 1, "Should be only one known install.");
Assert.equal(profileData.installs[hash].default, defaultProfile.leafName, "Should have marked the original default profile as the default for this install.");
Assert.ok(!profileData.installs[hash].locked, "Should not have locked as we're not the default app.");
Assert.equal(Object.keys(installData.installs).length, 1, "Should be only one known install.");
Assert.equal(installData.installs[hash].default, defaultProfile.leafName, "Should have marked the original default profile as the default for this install.");
Assert.ok(!installData.installs[hash].locked, "Should not have locked as we're not the default app.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
Assert.ok(!didCreate, "Should not have created a new profile.");
Assert.ok(!service.createdAlternateProfile, "Should not have created an alternate profile.");

View File

@ -21,6 +21,7 @@ add_task(async () => {
checkStartupReason("firstrun-created-default");
let profileData = readProfilesIni();
let installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 2, "Should have the right number of profiles.");
@ -38,11 +39,11 @@ add_task(async () => {
Assert.notEqual(profile.path, defaultProfile.leafName, "Should not be the original default profile.");
Assert.ok(!profile.default, "Should not be marked as the old-style default.");
Assert.equal(Object.keys(profileData.installs).length, 1, "Should be a default for installs.");
Assert.equal(profileData.installs[hash].default, profile.path, "Should have the right default profile.");
Assert.ok(profileData.installs[hash].locked, "Should have locked as we created this profile for this install.");
Assert.equal(Object.keys(installData.installs).length, 1, "Should be a default for installs.");
Assert.equal(installData.installs[hash].default, profile.path, "Should have the right default profile.");
Assert.ok(installData.installs[hash].locked, "Should have locked as we created this profile for this install.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
Assert.ok(didCreate, "Should have created a new profile.");
Assert.ok(!service.createdAlternateProfile, "Should not have created an alternate profile.");

View File

@ -25,6 +25,7 @@ add_task(async () => {
checkStartupReason("firstrun-skipped-default");
let profileData = readProfilesIni();
let installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 2, "Should have the right number of profiles.");
@ -42,11 +43,11 @@ add_task(async () => {
Assert.notEqual(profile.path, defaultProfile.leafName, "Should not be the original default profile.");
Assert.ok(!profile.default, "Should not be marked as the old-style default.");
Assert.equal(Object.keys(profileData.installs).length, 1, "Should be a default for this install.");
Assert.equal(profileData.installs[hash].default, profile.path, "Should have marked the new profile as the default for this install.");
Assert.ok(profileData.installs[hash].locked, "Should have locked as we created this profile for this install.");
Assert.equal(Object.keys(installData.installs).length, 1, "Should be a default for this install.");
Assert.equal(installData.installs[hash].default, profile.path, "Should have marked the new profile as the default for this install.");
Assert.ok(installData.installs[hash].locked, "Should have locked as we created this profile for this install.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
Assert.ok(didCreate, "Should have created a new profile.");
Assert.ok(service.createdAlternateProfile, "Should have created an alternate profile.");

View File

@ -23,6 +23,9 @@ add_task(async () => {
name: "dev-edition-default",
path: devProfile.leafName,
}],
});
writeInstallsIni({
installs: {
[hash]: {
default: dedicatedProfile.leafName,
@ -37,6 +40,7 @@ add_task(async () => {
checkStartupReason("default");
let profileData = readProfilesIni();
let installData = readInstallsIni();
Assert.ok(profileData.options.startWithLastProfile, "Should be set to start with the last profile.");
Assert.equal(profileData.profiles.length, 3, "Should have the right number of profiles.");
@ -51,11 +55,11 @@ add_task(async () => {
Assert.equal(profile.path, defaultProfile.leafName, "Should be the original default profile.");
Assert.ok(profile.default, "Should be marked as the old-style default.");
Assert.equal(Object.keys(profileData.installs).length, 2, "Should be two known installs.");
Assert.equal(profileData.installs[hash].default, dedicatedProfile.leafName, "Should have kept the default for this install.");
Assert.equal(profileData.installs.otherhash.default, "foobar", "Should have kept the default for the other install.");
Assert.equal(Object.keys(installData.installs).length, 2, "Should be two known installs.");
Assert.equal(installData.installs[hash].default, dedicatedProfile.leafName, "Should have kept the default for this install.");
Assert.equal(installData.installs.otherhash.default, "foobar", "Should have kept the default for the other install.");
checkProfileService(profileData);
checkProfileService(profileData, installData);
Assert.ok(!didCreate, "Should not have created a new profile.");
Assert.ok(selectedProfile.rootDir.equals(dedicatedProfile), "Should be using the right directory.");

View File

@ -32,5 +32,3 @@ skip-if = devedition
[test_snatch_environment.js]
[test_skip_locked_environment.js]
[test_snatch_environment_default.js]
[test_check_backup.js]
[test_missing_profilesini.js]

View File

@ -270,25 +270,6 @@ nsresult nsINIParser::DeleteSection(const char* aSection) {
return NS_OK;
}
nsresult nsINIParser::RenameSection(const char* aSection, const char* aNewName) {
if (!IsValidSection(aSection) || !IsValidSection(aNewName)) {
return NS_ERROR_INVALID_ARG;
}
if (mSections.Get(aNewName, nullptr)) {
return NS_ERROR_ILLEGAL_VALUE;
}
nsAutoPtr<INIValue> val;
if (mSections.Remove(aSection, &val)) {
mSections.Put(aNewName, val.forget());
} else {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult nsINIParser::WriteToFile(nsIFile* aFile) {
nsCString buffer;

View File

@ -116,17 +116,6 @@ class nsINIParser {
*/
nsresult DeleteSection(const char* aSection);
/**
* Renames the specified section.
*
* @param aSection section name
* @param aNewName new section name
*
* @throws NS_ERROR_FAILURE if the section did not exist.
* @throws NS_ERROR_ILLEGAL_VALUE if the new section name already exists.
*/
nsresult RenameSection(const char* aSection, const char* aNewName);
/**
* Writes the ini data to disk.
* @param aFile the file to write to