Bug 35559 - dynamic profile switching support

This commit is contained in:
ccarlen%netscape.com 2000-12-18 07:33:08 +00:00
Родитель 12d46e3f6a
Коммит dd47086547
3 изменённых файлов: 120 добавлений и 45 удалений

Просмотреть файл

@ -48,7 +48,7 @@ interface nsIProfile : nsISupports {
void getProfileList(out unsigned long length, [retval, array, size_is(length)] out wstring profileNames);
boolean profileExists(in wstring profileName);
readonly attribute wstring currentProfile;
attribute wstring currentProfile;
void createNewProfile(in wstring profileName,
in wstring nativeProfileDir,

Просмотреть файл

@ -62,6 +62,7 @@
#include "nsAppDirectoryServiceDefs.h"
#include "nsIChromeRegistry.h" // chromeReg
#include "nsIStringBundle.h"
#include "nsIObserverService.h"
// Interfaces Needed
#include "nsIDocShell.h"
@ -318,6 +319,7 @@ NS_INTERFACE_MAP_BEGIN(nsProfile)
NS_INTERFACE_MAP_ENTRY(nsIProfile)
NS_INTERFACE_MAP_ENTRY(nsIProfileInternal)
NS_INTERFACE_MAP_ENTRY(nsIDirectoryServiceProvider)
NS_INTERFACE_MAP_ENTRY(nsIProfileChangeStatus)
NS_INTERFACE_MAP_END
/*
@ -861,6 +863,10 @@ NS_IMETHODIMP nsProfile::GetProfileDir(const PRUnichar *profileName, nsIFile **p
rv = AddLevelOfIndirection(aProfileDir);
if (NS_FAILED(rv)) return rv;
// create the sub directories
rv = CreateUserDirectories(aProfileDir);
if (NS_FAILED(rv)) return rv;
// since we might be changing the location of
// profile dir, reset it in the registry.
// see bug #56002 for details
@ -942,6 +948,94 @@ nsProfile::GetCurrentProfile(PRUnichar **profileName)
return NS_OK;
}
NS_IMETHODIMP
nsProfile::SetCurrentProfile(const PRUnichar * aCurrentProfile)
{
NS_ENSURE_ARG(aCurrentProfile);
nsresult rv;
PRBool exists;
rv = ProfileExists(aCurrentProfile, &exists);
if (NS_FAILED(rv)) return rv;
if (!exists) return NS_ERROR_FAILURE;
PRBool isSwitch;
if (mCurrentProfileAvailable)
{
nsXPIDLString currProfileName;
rv = GetCurrentProfile(getter_Copies(currProfileName));
if (NS_FAILED(rv)) return rv;
if (nsCRT::strcmp(aCurrentProfile, currProfileName.get()) == 0)
return NS_OK;
else
isSwitch = PR_TRUE;
}
else
isSwitch = PR_FALSE;
NS_WITH_SERVICE(nsIProperties, directoryService, NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
NS_ENSURE_TRUE(directoryService, NS_ERROR_FAILURE);
NS_WITH_SERVICE(nsIObserverService, observerService, NS_OBSERVERSERVICE_CONTRACTID, &rv);
NS_ENSURE_TRUE(observerService, NS_ERROR_FAILURE);
nsISupports *subject = (nsISupports *)((nsIProfile *)this);
if (isSwitch)
{
// Phase 1: See if anybody objects to the profile being changed.
mProfileChangeVetoed = PR_FALSE;
observerService->Notify(subject, PROFILE_APPROVE_CHANGE_TOPIC, nsnull);
if (mProfileChangeVetoed)
return NS_OK;
// Phase 2: Send the "teardown" notification
observerService->Notify(subject, PROFILE_CHANGE_TEARDOWN_TOPIC, nsnull);
// Phase 3: Notify observers of a profile change
observerService->Notify(subject, PROFILE_BEFORE_CHANGE_TOPIC, nsnull);
}
// Do the profile switch
gProfileDataAccess->SetCurrentProfile(aCurrentProfile);
gProfileDataAccess->mProfileDataChanged = PR_TRUE;
gProfileDataAccess->UpdateRegistry(nsnull);
if (NS_FAILED(rv)) return rv;
mCurrentProfileAvailable = PR_TRUE;
if (isSwitch)
{
(void) directoryService->Undefine(NS_APP_PREFS_50_DIR);
(void) directoryService->Undefine(NS_APP_PREFS_50_FILE);
(void) directoryService->Undefine(NS_APP_USER_PROFILE_50_DIR);
(void) directoryService->Undefine(NS_APP_USER_CHROME_DIR);
(void) directoryService->Undefine(NS_APP_LOCALSTORE_50_FILE);
(void) directoryService->Undefine(NS_APP_HISTORY_50_FILE);
(void) directoryService->Undefine(NS_APP_USER_PANELS_50_FILE);
(void) directoryService->Undefine(NS_APP_USER_MIMETYPES_50_FILE);
(void) directoryService->Undefine(NS_APP_BOOKMARKS_50_FILE);
(void) directoryService->Undefine(NS_APP_SEARCH_50_FILE);
(void) directoryService->Undefine(NS_APP_MAIL_50_DIR);
(void) directoryService->Undefine(NS_APP_IMAP_MAIL_50_DIR);
(void) directoryService->Undefine(NS_APP_NEWS_50_DIR);
(void) directoryService->Undefine(NS_APP_MESSENGER_FOLDER_CACHE_50_DIR);
// Phase 4: Notify observers that the profile has changed - Here they respond to new profile
observerService->Notify(subject, PROFILE_DO_CHANGE_TOPIC, nsnull);
// Phase 5: Now observers can respond to something another observer did in phase 4
observerService->Notify(subject, PROFILE_AFTER_CHANGE_TOPIC, nsnull);
}
else
rv = LoadNewProfilePrefs();
return NS_OK;
}
// Returns the name of the current profile directory
NS_IMETHODIMP nsProfile::GetCurrentProfileDir(nsIFile **profileDir)
{
@ -1096,15 +1190,7 @@ nsresult nsProfile::SetProfileDir(const PRUnichar *profileName, nsIFile *profile
aProfile->SetResolvedProfileDir(localFile);
aProfile->isMigrated = PR_TRUE;
rv = CreateUserDirectories(localFile);
if (NS_FAILED(rv)) {
delete aProfile;
return rv;
}
gProfileDataAccess->SetValue(aProfile);
gProfileDataAccess->SetCurrentProfile(profileName);
delete aProfile;
@ -1191,8 +1277,9 @@ nsProfile::CreateNewProfile(const PRUnichar* profileName,
rv = AddLevelOfIndirection(profileDir);
if (NS_FAILED(rv)) return rv;
// Create the sub directories
rv = CreateUserDirectories(profileDir);
// Set the directory value and add the entry to the registry tree.
// Creates required user directories.
rv = SetProfileDir(profileName, profileDir);
#if defined(DEBUG_profile_verbose)
@ -1244,7 +1331,7 @@ nsProfile::CreateNewProfile(const PRUnichar* profileName,
// Create required user directories like ImapMail, Mail, News, Cache etc.
nsresult nsProfile::CreateUserDirectories(nsILocalFile *profileDir)
nsresult nsProfile::CreateUserDirectories(nsIFile *profileDir)
{
nsresult rv = NS_OK;
@ -1280,7 +1367,7 @@ nsresult nsProfile::CreateUserDirectories(nsILocalFile *profileDir)
// Delete all user directories associated with the a profile
// A FileSpec of the profile's directory is taken as input param
nsresult nsProfile::DeleteUserDirectories(nsILocalFile *profileDir)
nsresult nsProfile::DeleteUserDirectories(nsIFile *profileDir)
{
NS_ENSURE_ARG(profileDir);
nsresult rv;
@ -1482,7 +1569,7 @@ NS_IMETHODIMP nsProfile::StartApprunner(const PRUnichar* profileName)
printf("ProfileManager : StartApprunner\n");
nsCAutoString temp; temp.AssignWithConversion(profileName);
printf("profileName passed in: %s", NS_STATIC_CAST(const char*, temp));
printf("profileName passed in: %s\n", NS_STATIC_CAST(const char*, temp));
}
#endif
@ -1757,6 +1844,8 @@ nsProfile::MigrateProfile(const PRUnichar* profileName, PRBool showProgressAsMod
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to copy default mimeTypes.rdf file");
// hack finish.
rv = CreateUserDirectories(newProfDir);
if (NS_FAILED(rv)) return rv;
rv = SetProfileDir(profileName, newProfDir);
if (NS_FAILED(rv)) return rv;
@ -1942,33 +2031,6 @@ NS_IMETHODIMP nsProfile::MigrateAllProfiles()
}
nsresult nsProfile::RenameProfileDir(const PRUnichar* newProfileName)
{
NS_ASSERTION(newProfileName, "Invalid new profile name");
nsresult rv;
nsCOMPtr<nsIFile> aFile;
nsCOMPtr<nsILocalFile> profileDir;
rv = GetProfileDir(newProfileName, getter_AddRefs(aFile));
if (NS_FAILED(rv)) return rv;
profileDir = do_QueryInterface(aFile, &rv);
if (NS_FAILED(rv)) return rv;
nsCAutoString newName; newName.AssignWithConversion(newProfileName);
// rename the directory
rv = profileDir->MoveTo(nsnull, newName);
if (NS_FAILED(rv)) return rv;
// update the registry
rv = SetProfileDir(newProfileName, profileDir);
if (NS_FAILED(rv)) return rv;
return NS_OK;
}
NS_IMETHODIMP nsProfile::CloneProfile(const PRUnichar* newProfile)
{
NS_ENSURE_ARG_POINTER(newProfile);
@ -2233,6 +2295,17 @@ nsProfile::GetFile(const char *prop, PRBool *persistant, nsIFile **_retval)
return rv;
}
/*
* nsIProfileChangeStatus Implementation
*/
NS_IMETHODIMP nsProfile::VetoChange()
{
mProfileChangeVetoed = PR_TRUE;
return NS_OK;
}
nsresult nsProfile::CloneProfileDirectorySpec(nsILocalFile **aLocalFile)
{
NS_ENSURE_ARG_POINTER(aLocalFile);

Просмотреть файл

@ -23,6 +23,7 @@
#include "nsIProfile.h"
#include "nsIProfileInternal.h"
#include "nsIProfileStartupListener.h"
#include "nsIProfileChangeStatus.h"
#include "nsCOMPtr.h"
#include "nsISupports.h"
#include "nsIRegistry.h"
@ -40,12 +41,14 @@
#define _MAX_LENGTH 256
class nsProfile: public nsIProfileInternal,
public nsIDirectoryServiceProvider
public nsIDirectoryServiceProvider,
public nsIProfileChangeStatus
{
NS_DECL_ISUPPORTS
NS_DECL_NSIPROFILE
NS_DECL_NSIPROFILEINTERNAL
NS_DECL_NSIDIRECTORYSERVICEPROVIDER
NS_DECL_NSIPROFILECHANGESTATUS
private:
nsresult ProcessArgs(nsICmdLineService *service,
@ -65,18 +68,17 @@ private:
PRBool mAutomigrate;
PRBool mOutofDiskSpace;
PRBool mDiskSpaceErrorQuitCalled;
PRBool mProfileChangeVetoed;
public:
nsProfile();
virtual ~nsProfile();
nsresult RenameProfileDir(const PRUnichar *newProfileName);
// Creates associated user directories on the creation of a new profile
nsresult CreateUserDirectories(nsILocalFile *profileDir);
nsresult CreateUserDirectories(nsIFile *profileDir);
// Deletes associated user directories
nsresult DeleteUserDirectories(nsILocalFile *profileDir);
nsresult DeleteUserDirectories(nsIFile *profileDir);
// Copies all the registry keys from old profile to new profile
nsresult CopyRegKey(const PRUnichar *oldProfile, const PRUnichar *newProfile);