Bug 1893666 Part 3 - Add a flag to nsIToolkitProfile to decide whether to show the profile selector at startup. r=mossop

Differential Revision: https://phabricator.services.mozilla.com/D216491
This commit is contained in:
Jared Hirsch 2024-07-31 21:13:31 +00:00
parent 825108a3ec
commit a0b4e6168e
5 changed files with 145 additions and 6 deletions

View File

@ -71,6 +71,14 @@ interface nsIToolkitProfile : nsISupports
*/
attribute AUTF8String storeID;
/**
* Whether to show the selectable profile selector window at startup for
* the profile group associated to the nsIToolkitProfile instance.
*
* @throws NS_ERROR_FAILURE on set if storeID is null.
*/
attribute boolean showProfileSelector;
/**
* Removes the profile from the registry of profiles.
*

View File

@ -235,11 +235,13 @@ void RemoveProfileFiles(nsIToolkitProfile* aProfile, bool aInBackground) {
nsToolkitProfile::nsToolkitProfile(const nsACString& aName, nsIFile* aRootDir,
nsIFile* aLocalDir, bool aFromDB,
const nsACString& aStoreID = VoidCString())
const nsACString& aStoreID = VoidCString(),
bool aShowProfileSelector = false)
: mName(aName),
mRootDir(aRootDir),
mLocalDir(aLocalDir),
mStoreID(aStoreID),
mShowProfileSelector(aShowProfileSelector),
mLock(nullptr),
mIndex(0),
mSection("Profile") {
@ -269,6 +271,8 @@ nsToolkitProfile::nsToolkitProfile(const nsACString& aName, nsIFile* aRootDir,
if (!mStoreID.IsVoid()) {
db->SetString(mSection.get(), "StoreID",
PromiseFlatCString(mStoreID).get());
db->SetString(mSection.get(), "ShowSelector",
aShowProfileSelector ? "1" : "0");
}
}
}
@ -364,10 +368,18 @@ nsToolkitProfile::SetStoreID(const nsACString& aStoreID) {
if (rv == NS_ERROR_FAILURE) {
rv = NS_OK;
}
// We need a StoreID to show the profile selector, so if StoreID has been
// removed, then remove ShowSelector also.
mShowProfileSelector = false;
rv = nsToolkitProfileService::gService->mProfileDB.DeleteString(
mSection.get(), "ShowSelector");
if (rv == NS_ERROR_FAILURE) {
rv = NS_OK;
}
}
NS_ENSURE_SUCCESS(rv, rv);
// Finally, update the local object.
mStoreID = aStoreID;
return NS_OK;
@ -419,6 +431,41 @@ nsToolkitProfile::SetName(const nsACString& aName) {
return NS_OK;
}
NS_IMETHODIMP
nsToolkitProfile::GetShowProfileSelector(bool* aShowProfileSelector) {
#ifdef MOZ_SELECTABLE_PROFILES
*aShowProfileSelector = mShowProfileSelector;
#else
*aShowProfileSelector = false;
#endif
return NS_OK;
}
NS_IMETHODIMP
nsToolkitProfile::SetShowProfileSelector(bool aShowProfileSelector) {
#ifdef MOZ_SELECTABLE_PROFILES
NS_ASSERTION(nsToolkitProfileService::gService, "Where did my service go?");
// We need a StoreID to show the profile selector; bail out if it's missing.
if (mStoreID.IsVoid()) {
return NS_ERROR_FAILURE;
}
if (mShowProfileSelector == aShowProfileSelector) {
return NS_OK;
}
nsresult rv = nsToolkitProfileService::gService->mProfileDB.SetString(
mSection.get(), "ShowSelector", aShowProfileSelector ? "1" : "0");
NS_ENSURE_SUCCESS(rv, rv);
mShowProfileSelector = aShowProfileSelector;
return NS_OK;
#else
return NS_ERROR_FAILURE;
#endif
}
nsresult nsToolkitProfile::RemoveInternal(bool aRemoveFiles,
bool aInBackground) {
NS_ASSERTION(nsToolkitProfileService::gService, "Whoa, my service is gone.");
@ -1094,6 +1141,7 @@ nsresult nsToolkitProfileService::Init() {
}
nsCString storeID;
bool showProfileSelector = false;
rv = mProfileDB.GetString(profileID.get(), "StoreID", storeID);
@ -1102,8 +1150,16 @@ nsresult nsToolkitProfileService::Init() {
storeID = VoidCString();
}
currentProfile =
new nsToolkitProfile(name, rootDir, localDir, true, storeID);
// Only get the ShowSelector value if StoreID is nonempty.
if (!storeID.IsVoid()) {
rv = mProfileDB.GetString(profileID.get(), "ShowSelector", buffer);
if (NS_SUCCEEDED(rv)) {
showProfileSelector = buffer.EqualsLiteral("1");
}
}
currentProfile = new nsToolkitProfile(name, rootDir, localDir, true,
storeID, showProfileSelector);
// If a user has modified the ini file path it may make for a valid profile
// path but not match what we would have serialised and so may not match

View File

@ -30,8 +30,8 @@ class nsToolkitProfile final
~nsToolkitProfile() = default;
nsToolkitProfile(const nsACString& aName, nsIFile* aRootDir,
nsIFile* aLocalDir, bool aFromDB,
const nsACString& aStoreID);
nsIFile* aLocalDir, bool aFromDB, const nsACString& aStoreID,
bool aShowProfileSelector);
nsresult RemoveInternal(bool aRemoveFiles, bool aInBackground);
@ -41,6 +41,7 @@ class nsToolkitProfile final
nsCOMPtr<nsIFile> mRootDir;
nsCOMPtr<nsIFile> mLocalDir;
nsCString mStoreID;
bool mShowProfileSelector;
nsIProfileLock* mLock;
uint32_t mIndex;
nsCString mSection;

View File

@ -0,0 +1,72 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* Tests that the boolean ShowSelector attribute can be set in profiles.ini
* by setting the corresponding `showProfileSelector` attribute on a toolkit
* profile object. Also tests that StoreID must be nonempty to set
* ShowSelector, and deleting StoreID also deletes ShowSelector.
*/
add_task(
{
skip_if: () => !AppConstants.MOZ_SELECTABLE_PROFILES,
},
async () => {
let hash = xreDirProvider.getInstallHash();
let defaultProfile = makeRandomProfileDir("default");
let profilesIni = {
profiles: [
{
name: "default",
path: defaultProfile.leafName,
default: true,
},
],
installs: {
[hash]: {
default: defaultProfile.leafName,
},
},
};
writeProfilesIni(profilesIni);
let service = getProfileService();
// Before testing, verify the service is consistent with the input.
checkProfileService(profilesIni);
// Test that an error is thrown if we try to set ShowSelector when there is
// no StoreID.
let { profile } = selectStartupProfile();
Assert.throws(
() => (profile.showProfileSelector = true),
e => e.result == Cr.NS_ERROR_FAILURE,
"Cannot set ShowSelector if StoreID is missing"
);
// Now, set a StoreID and test that we can set ShowSelector.
profile.storeID = "12345678";
profile.showProfileSelector = true;
service.flush();
// Expected value of the database.
profilesIni.profiles[0].storeID = "12345678";
profilesIni.profiles[0].showSelector = "1";
// Check expected against actual database state.
checkProfileService(profilesIni);
// Next, flip the value to false, and verify again.
profile.showProfileSelector = false;
service.flush();
profilesIni.profiles[0].showSelector = "0";
checkProfileService(profilesIni);
// Finally, verify that clearing storeID also clears ShowSelector.
profile.showProfileSelector = true;
profile.storeID = null;
service.flush();
delete profilesIni.profiles[0].storeID;
delete profilesIni.profiles[0].showSelector;
checkProfileService(profilesIni);
}
);

View File

@ -62,6 +62,8 @@ skip-if = ["os == 'android'"]
["test_select_profilemanager.js"]
["test_showselector.js"]
["test_single_profile_selected.js"]
skip-if = ["devedition"]