зеркало из https://github.com/mozilla/gecko-dev.git
Fixing bug 13850. Profile Manager now handles out of disk space errors passed by prefmigrator. r=dbragg
This commit is contained in:
Родитель
db8ee85410
Коммит
ce0f90fd78
Двоичные данные
profile/macbuild/profile.mcp
Двоичные данные
profile/macbuild/profile.mcp
Двоичный файл не отображается.
|
@ -37,6 +37,7 @@ CPPSRCS = nsProfile.cpp \
|
||||||
EXTRA_DSO_LDOPTS = \
|
EXTRA_DSO_LDOPTS = \
|
||||||
-L$(DIST)/bin \
|
-L$(DIST)/bin \
|
||||||
$(XPCOM_LIBS) \
|
$(XPCOM_LIBS) \
|
||||||
|
$(MOZ_JS_LIBS) \
|
||||||
$(NSPR_LIBS) \
|
$(NSPR_LIBS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,9 @@ BINREL_DIST=$(XPDIST)\WIN954.0_DBG.OBJD
|
||||||
LLIBS = \
|
LLIBS = \
|
||||||
$(LIBNSPR) \
|
$(LIBNSPR) \
|
||||||
$(DIST)\lib\xpcom.lib \
|
$(DIST)\lib\xpcom.lib \
|
||||||
|
$(DIST)\lib\js3250.lib \
|
||||||
|
$(DIST)\lib\jsdombase_s.lib \
|
||||||
|
$(DIST)\lib\jsdomevents_s.lib \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
#//------------------------------------------------------------------------
|
#//------------------------------------------------------------------------
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
|
|
||||||
#include "nsIIOService.h"
|
#include "nsIIOService.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
|
#include "nsPrefMigration.h"
|
||||||
#include "nsIPrefMigration.h"
|
#include "nsIPrefMigration.h"
|
||||||
#include "nsPrefMigrationCIDs.h"
|
#include "nsPrefMigrationCIDs.h"
|
||||||
#include "nsFileStream.h"
|
#include "nsFileStream.h"
|
||||||
|
@ -66,6 +67,12 @@
|
||||||
#include "nsIWebShell.h"
|
#include "nsIWebShell.h"
|
||||||
#include "nsIWebBrowserChrome.h"
|
#include "nsIWebBrowserChrome.h"
|
||||||
|
|
||||||
|
#include "nsIScriptGlobalObject.h"
|
||||||
|
#include "nsIBaseWindow.h"
|
||||||
|
#include "nsICommonDialogs.h"
|
||||||
|
#include "nsIDOMWindow.h"
|
||||||
|
#include "nsIWindowMediator.h"
|
||||||
|
|
||||||
#if defined (XP_UNIX)
|
#if defined (XP_UNIX)
|
||||||
#elif defined (XP_MAC)
|
#elif defined (XP_MAC)
|
||||||
#define OLD_REGISTRY_FILE_NAME "Netscape Registry"
|
#define OLD_REGISTRY_FILE_NAME "Netscape Registry"
|
||||||
|
@ -130,6 +137,8 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||||
static NS_DEFINE_CID(kPrefMigrationCID, NS_PREFMIGRATION_CID);
|
static NS_DEFINE_CID(kPrefMigrationCID, NS_PREFMIGRATION_CID);
|
||||||
static NS_DEFINE_CID(kPrefConverterCID, NS_PREFCONVERTER_CID);
|
static NS_DEFINE_CID(kPrefConverterCID, NS_PREFCONVERTER_CID);
|
||||||
static NS_DEFINE_IID(kCookieServiceCID, NS_COOKIESERVICE_CID);
|
static NS_DEFINE_IID(kCookieServiceCID, NS_COOKIESERVICE_CID);
|
||||||
|
static NS_DEFINE_CID(kDialogParamBlockCID, NS_DialogParamBlock_CID);
|
||||||
|
static NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID);
|
||||||
|
|
||||||
static NS_DEFINE_CID(kChromeRegistryCID, NS_CHROMEREGISTRY_CID);
|
static NS_DEFINE_CID(kChromeRegistryCID, NS_CHROMEREGISTRY_CID);
|
||||||
|
|
||||||
|
@ -162,6 +171,8 @@ nsresult GetStringFromSpec(nsFileSpec inSpec, char **string)
|
||||||
nsProfile::nsProfile()
|
nsProfile::nsProfile()
|
||||||
{
|
{
|
||||||
mAutomigrate = PR_FALSE;
|
mAutomigrate = PR_FALSE;
|
||||||
|
mOutofDiskSpace = PR_FALSE;
|
||||||
|
mDiskSpaceErrorQuitCalled = PR_FALSE;
|
||||||
|
|
||||||
if(!gProfileDataAccess)
|
if(!gProfileDataAccess)
|
||||||
gProfileDataAccess = new nsProfileAccess();
|
gProfileDataAccess = new nsProfileAccess();
|
||||||
|
@ -236,6 +247,11 @@ nsProfile::StartupWithArgs(nsICmdLineService *cmdLineArgs)
|
||||||
if (cmdLineArgs)
|
if (cmdLineArgs)
|
||||||
rv = ProcessArgs(cmdLineArgs, &profileDirSet, profileURLStr);
|
rv = ProcessArgs(cmdLineArgs, &profileDirSet, profileURLStr);
|
||||||
|
|
||||||
|
// This boolean is set only when an automigrated user runs out of disk space
|
||||||
|
// and chooses to cancel further operations from the dialogs presented...
|
||||||
|
if (mDiskSpaceErrorQuitCalled)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
if (!profileDirSet) {
|
if (!profileDirSet) {
|
||||||
rv = LoadDefaultProfileDir(profileURLStr);
|
rv = LoadDefaultProfileDir(profileURLStr);
|
||||||
|
|
||||||
|
@ -400,7 +416,9 @@ nsProfile::AutoMigrate()
|
||||||
// automatically migrate the one 4.x profile
|
// automatically migrate the one 4.x profile
|
||||||
rv = MigrateAllProfiles();
|
rv = MigrateAllProfiles();
|
||||||
|
|
||||||
if (NS_FAILED(rv))
|
// Create a default profile if automigration failed for reasons
|
||||||
|
// other than out of disk space case...
|
||||||
|
if (NS_FAILED(rv) && !mOutofDiskSpace)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_profile
|
#ifdef DEBUG_profile
|
||||||
printf("AutoMigration failed. Let's create a default 5.0 profile.\n");
|
printf("AutoMigration failed. Let's create a default 5.0 profile.\n");
|
||||||
|
@ -408,7 +426,7 @@ nsProfile::AutoMigrate()
|
||||||
|
|
||||||
rv = CreateDefaultProfile();
|
rv = CreateDefaultProfile();
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
gProfileDataAccess->mProfileDataChanged = PR_TRUE;
|
gProfileDataAccess->mProfileDataChanged = PR_TRUE;
|
||||||
gProfileDataAccess->UpdateRegistry();
|
gProfileDataAccess->UpdateRegistry();
|
||||||
|
@ -1374,12 +1392,12 @@ nsProfile::MigrateProfile(const PRUnichar* profileName, PRBool showProgressAsMod
|
||||||
|
|
||||||
newSpec->GetFileSpec(&newProfDir);
|
newSpec->GetFileSpec(&newProfDir);
|
||||||
newProfDir += profileName;
|
newProfDir += profileName;
|
||||||
newProfDir.MakeUnique();
|
newProfDir.MakeUnique();
|
||||||
if (newProfDir.Exists()) {
|
if (newProfDir.Exists()) {
|
||||||
#ifdef DEBUG_profile
|
#ifdef DEBUG_profile
|
||||||
printf("directory already exists\n");
|
printf("directory already exists\n");
|
||||||
#endif
|
#endif
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call migration service to do the work.
|
// Call migration service to do the work.
|
||||||
|
@ -1395,10 +1413,11 @@ nsProfile::MigrateProfile(const PRUnichar* profileName, PRBool showProgressAsMod
|
||||||
|
|
||||||
nsXPIDLCString oldProfDirStr;
|
nsXPIDLCString oldProfDirStr;
|
||||||
nsXPIDLCString newProfDirStr;
|
nsXPIDLCString newProfDirStr;
|
||||||
|
|
||||||
if (!newProfDir.Exists()) {
|
if (!newProfDir.Exists()) {
|
||||||
newProfDir.CreateDirectory();
|
newProfDir.CreateDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = GetStringFromSpec(newProfDir, getter_Copies(newProfDirStr));
|
rv = GetStringFromSpec(newProfDir, getter_Copies(newProfDirStr));
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
@ -1414,6 +1433,58 @@ nsProfile::MigrateProfile(const PRUnichar* profileName, PRBool showProgressAsMod
|
||||||
rv = pPrefMigrator->ProcessPrefs(showProgressAsModalWindow);
|
rv = pPrefMigrator->ProcessPrefs(showProgressAsModalWindow);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
// check for diskspace errors
|
||||||
|
nsresult errorCode;
|
||||||
|
errorCode = pPrefMigrator->GetError();
|
||||||
|
|
||||||
|
// In either of the cases below we have to return error to make
|
||||||
|
// app understand that migration has failed.
|
||||||
|
if (errorCode == CREATE_NEW)
|
||||||
|
{
|
||||||
|
PRInt32 numProfiles = 0;
|
||||||
|
ShowProfileWizard();
|
||||||
|
|
||||||
|
// When the automigration process fails because of disk space error,
|
||||||
|
// we present user a create profile wizard if the user chooses to create a
|
||||||
|
// a profile then. But then the user may click on cancel on that dialog...
|
||||||
|
// So, if the user clicks on cancel, the number of profiles should be
|
||||||
|
// ZERO at the point for the user who failed to automigrate single 4x profile.
|
||||||
|
// On such condition, set mDiskSpaceErrorQuitCalled to allow user to quit the app.
|
||||||
|
// If the user is presented with profilemanager dialog with multiple 4x profiles
|
||||||
|
// to migrate, value of mDiskSpaceErrorQuitCalled does not matter as it gets ignored..
|
||||||
|
// If a single profile needs automigration and no confirmation
|
||||||
|
// is needed for that operation mAutomigrate is set to false.
|
||||||
|
if (!mAutomigrate)
|
||||||
|
{
|
||||||
|
GetProfileCount(&numProfiles);
|
||||||
|
if (numProfiles == 0)
|
||||||
|
mDiskSpaceErrorQuitCalled = PR_TRUE;
|
||||||
|
}
|
||||||
|
mOutofDiskSpace = PR_TRUE;
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
else if (errorCode == CANCEL)
|
||||||
|
{
|
||||||
|
// When the automigration process fails because of disk space error,
|
||||||
|
// user may choose to simply quit the app from the dialog presented
|
||||||
|
// by pref-migrator. So, set mDiskSpaceErrorQuitCalled to allow user
|
||||||
|
// to quit the app in such a case.
|
||||||
|
// If the user is presented with profilemanager dialog with multiple 4x profiles
|
||||||
|
// to migrate, value of mDiskSpaceErrorQuitCalled does not matter as it gets ignored..
|
||||||
|
// If a single profile needs automigration and no confirmation
|
||||||
|
// is needed for that operation mAutomigrate is set to false.
|
||||||
|
if (!mAutomigrate)
|
||||||
|
mDiskSpaceErrorQuitCalled = PR_TRUE;
|
||||||
|
|
||||||
|
ForgetCurrentProfile();
|
||||||
|
mOutofDiskSpace = PR_TRUE;
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
else if (errorCode != SUCCESS)
|
||||||
|
{
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy the default 5.0 profile files into the migrated profile
|
// Copy the default 5.0 profile files into the migrated profile
|
||||||
// Get profile defaults folder..
|
// Get profile defaults folder..
|
||||||
nsCOMPtr <nsIFileSpec> profDefaultsDir;
|
nsCOMPtr <nsIFileSpec> profDefaultsDir;
|
||||||
|
@ -1445,6 +1516,133 @@ nsProfile::MigrateProfile(const PRUnichar* profileName, PRBool showProgressAsMod
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsProfile::ShowProfileWizard(void)
|
||||||
|
{
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
PRBool hasParentWindow = PR_FALSE;
|
||||||
|
nsCOMPtr<nsIDOMWindow> PMDOMWindow;
|
||||||
|
|
||||||
|
// Get the window mediator
|
||||||
|
NS_WITH_SERVICE(nsIWindowMediator, windowMediator, kWindowMediatorCID, &rv);
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(windowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator))))
|
||||||
|
{
|
||||||
|
// Get each dom window
|
||||||
|
PRBool more;
|
||||||
|
windowEnumerator->HasMoreElements(&more);
|
||||||
|
while (more)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsISupports> protoWindow;
|
||||||
|
rv = windowEnumerator->GetNext(getter_AddRefs(protoWindow));
|
||||||
|
if (NS_SUCCEEDED(rv) && protoWindow)
|
||||||
|
{
|
||||||
|
PMDOMWindow = do_QueryInterface(protoWindow);
|
||||||
|
if (PMDOMWindow)
|
||||||
|
{
|
||||||
|
hasParentWindow = PR_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
windowEnumerator->HasMoreElements(&more);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasParentWindow)
|
||||||
|
{
|
||||||
|
// Get the script global object for the window
|
||||||
|
nsCOMPtr<nsIScriptGlobalObject> sgo;
|
||||||
|
sgo = do_QueryInterface(PMDOMWindow);
|
||||||
|
if (!sgo) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// Get the script context from the global context
|
||||||
|
nsCOMPtr<nsIScriptContext> scriptContext;
|
||||||
|
sgo->GetContext( getter_AddRefs(scriptContext));
|
||||||
|
if (!scriptContext) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
// Get the JSContext from the script context
|
||||||
|
JSContext* jsContext = (JSContext*)scriptContext->GetNativeContext();
|
||||||
|
if (!jsContext) return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// Create the nsIDialogParamBlock to pass the trigger
|
||||||
|
// list to the dialog
|
||||||
|
//-----------------------------------------------------
|
||||||
|
nsCOMPtr<nsIDialogParamBlock> ioParamBlock;
|
||||||
|
rv = nsComponentManager::CreateInstance(kDialogParamBlockCID,
|
||||||
|
nsnull,
|
||||||
|
NS_GET_IID(nsIDialogParamBlock),
|
||||||
|
getter_AddRefs(ioParamBlock));
|
||||||
|
|
||||||
|
|
||||||
|
if ( NS_SUCCEEDED( rv ) )
|
||||||
|
ioParamBlock->SetInt(0,4); // standard wizard buttons
|
||||||
|
|
||||||
|
|
||||||
|
void* stackPtr;
|
||||||
|
jsval *argv = JS_PushArguments( jsContext,
|
||||||
|
&stackPtr,
|
||||||
|
"sss%ip",
|
||||||
|
PROFILE_WIZARD_URL,
|
||||||
|
"_blank",
|
||||||
|
"chrome,modal",
|
||||||
|
(const nsIID*)(&NS_GET_IID(nsIDialogParamBlock)),
|
||||||
|
(nsISupports*)ioParamBlock);
|
||||||
|
|
||||||
|
if (argv)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIDOMWindow> newWindow;
|
||||||
|
rv = PMDOMWindow->OpenDialog(jsContext,
|
||||||
|
argv,
|
||||||
|
4,
|
||||||
|
getter_AddRefs(newWindow));
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
{
|
||||||
|
JS_PopArguments( jsContext, stackPtr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No parent window is available.
|
||||||
|
// So, Create top level window with create profile wizard
|
||||||
|
NS_WITH_SERVICE(nsIAppShellService, wizAppShell,
|
||||||
|
kAppShellServiceCID, &rv);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
nsCString profURLStr = PROFILE_WIZARD_URL;
|
||||||
|
nsCOMPtr<nsIURI> profURI;
|
||||||
|
rv = NS_NewURI(getter_AddRefs(profURI), (const char *)profURLStr);
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXULWindow> newWindow;
|
||||||
|
rv = wizAppShell->CreateTopLevelWindow(nsnull, profURI,
|
||||||
|
PR_TRUE, PR_TRUE, CHROME_STYLE,
|
||||||
|
NS_SIZETOCONTENT, // width
|
||||||
|
NS_SIZETOCONTENT, // height
|
||||||
|
getter_AddRefs(newWindow));
|
||||||
|
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bring up the wizard...
|
||||||
|
*/
|
||||||
|
rv = wizAppShell->Run();
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsProfile::ProfileExists(const PRUnichar *profileName, PRBool *exists)
|
NS_IMETHODIMP nsProfile::ProfileExists(const PRUnichar *profileName, PRBool *exists)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(profileName);
|
NS_ENSURE_ARG_POINTER(profileName);
|
||||||
|
|
|
@ -69,6 +69,8 @@ private:
|
||||||
nsFileSpec& newProfDir,
|
nsFileSpec& newProfDir,
|
||||||
const char *fileName);
|
const char *fileName);
|
||||||
PRBool mAutomigrate;
|
PRBool mAutomigrate;
|
||||||
|
PRBool mOutofDiskSpace;
|
||||||
|
PRBool mDiskSpaceErrorQuitCalled;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
nsProfile();
|
nsProfile();
|
||||||
|
@ -88,5 +90,6 @@ public:
|
||||||
nsresult AutoMigrate();
|
nsresult AutoMigrate();
|
||||||
|
|
||||||
nsresult CreateDefaultProfile(void);
|
nsresult CreateDefaultProfile(void);
|
||||||
|
nsresult ShowProfileWizard(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче