From ca857b3626b91f3def3caa4076b308b7a141ddce Mon Sep 17 00:00:00 2001 From: "mark%moxienet.com" Date: Fri, 19 May 2006 02:14:55 +0000 Subject: [PATCH] 326668 compreg.dat and xpti.dat still live in Camino.app. Move them into the profile. Add compatibility.ini and profile version checking to remove these files at startup and force reregistration when the app changes. r=hwaara sr=pink a=me git-svn-id: svn://10.0.0.236/branches/MOZILLA_1_8_0_BRANCH@197969 18797224-902f-48f8-a5cc-f745e15eee43 --- .../src/application/AppDirServiceProvider.cpp | 53 ++++-- .../camino/src/application/MainController.mm | 20 -- mozilla/camino/src/application/UserDefaults.h | 1 - .../src/preferences/PreferenceManager.mm | 175 ++++++++++++++++-- 4 files changed, 200 insertions(+), 49 deletions(-) diff --git a/mozilla/camino/src/application/AppDirServiceProvider.cpp b/mozilla/camino/src/application/AppDirServiceProvider.cpp index 6573e29a06c..47707bb958f 100644 --- a/mozilla/camino/src/application/AppDirServiceProvider.cpp +++ b/mozilla/camino/src/application/AppDirServiceProvider.cpp @@ -38,13 +38,16 @@ #include "AppDirServiceProvider.h" #include "nsAppDirectoryServiceDefs.h" +#include "nsDirectoryServiceDefs.h" #include "nsILocalFileMac.h" #include // Defines -#define APP_REGISTRY_NAME NS_LITERAL_CSTRING("Application.regs") +#define APP_REGISTRY_NAME NS_LITERAL_CSTRING("Application.regs") +#define COMPONENT_REGISTRY_NAME NS_LITERAL_CSTRING("compreg.dat") +#define XPTI_REGISTRY_NAME NS_LITERAL_CSTRING("xpti.dat") //***************************************************************************** // AppDirServiceProvider::Constructor/Destructor @@ -89,6 +92,18 @@ AppDirServiceProvider::GetFile(const char *prop, PRBool *persistant, nsIFile **_ if (NS_SUCCEEDED(rv)) rv = localFile->AppendNative(APP_REGISTRY_NAME); } + else if (strcmp(prop, NS_XPCOM_COMPONENT_REGISTRY_FILE) == 0) + { + rv = GetProductDirectory(getter_AddRefs(localFile)); + if (NS_SUCCEEDED(rv)) + rv = localFile->AppendNative(COMPONENT_REGISTRY_NAME); + } + else if (strcmp(prop, NS_XPCOM_XPTI_REGISTRY_FILE) == 0) + { + rv = GetProductDirectory(getter_AddRefs(localFile)); + if (NS_SUCCEEDED(rv)) + rv = localFile->AppendNative(XPTI_REGISTRY_NAME); + } else if (strcmp(prop, NS_APP_USER_PROFILES_ROOT_DIR) == 0) { rv = GetProductDirectory(getter_AddRefs(localFile)); @@ -132,25 +147,29 @@ AppDirServiceProvider::EnsureFolder(OSType inFolderType, nsILocalFile** outFolde OSErr err = ::FSFindFolder(kUserDomain, inFolderType, kCreateFolder, &foundRef); if (err != noErr) return NS_ERROR_FAILURE; - nsCOMPtr localDir(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID)); - if (!localDir) - return NS_ERROR_FAILURE; - rv = localDir->InitWithFSRef(&foundRef); - if (NS_FAILED(rv)) - return rv; - rv = localDir->AppendNative(mProductDirName); - if (NS_FAILED(rv)) - return rv; + + nsCOMPtr localDir; + NS_NewLocalFile(EmptyString(), PR_TRUE, getter_AddRefs(localDir)); + nsCOMPtr localDirMac(do_QueryInterface(localDir)); + NS_ENSURE_STATE(localDirMac); + + rv = localDirMac->InitWithFSRef(&foundRef); + NS_ENSURE_SUCCESS(rv, rv); + + rv = localDirMac->AppendNative(mProductDirName); + NS_ENSURE_SUCCESS(rv, rv); PRBool exists; - rv = localDir->Exists(&exists); - if (NS_SUCCEEDED(rv) && !exists) - rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0775); - if (NS_FAILED(rv)) - return rv; + rv = localDirMac->Exists(&exists); + NS_ENSURE_SUCCESS(rv, rv); + + if (!exists) { + rv = localDirMac->Create(nsIFile::DIRECTORY_TYPE, 0775); + NS_ENSURE_SUCCESS(rv, rv); + } - *outFolder = localDir; + *outFolder = localDirMac; NS_ADDREF(*outFolder); return rv; -} \ No newline at end of file +} diff --git a/mozilla/camino/src/application/MainController.mm b/mozilla/camino/src/application/MainController.mm index 4af1d1c18e1..a9bd089da95 100644 --- a/mozilla/camino/src/application/MainController.mm +++ b/mozilla/camino/src/application/MainController.mm @@ -145,26 +145,6 @@ const int kReuseWindowOnAE = 2; } NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; - if ([defaults boolForKey:USER_DEFAULTS_AUTOREGISTER_KEY]) { - // This option causes us to simply initialize embedding and exit. - NSString *path = [[[NSBundle mainBundle] executablePath] stringByDeletingLastPathComponent]; - setenv("MOZILLA_FIVE_HOME", [path fileSystemRepresentation], 1); - - if (NS_SUCCEEDED(NS_InitEmbedding(nsnull, nsnull, - kPStaticModules, kStaticModuleCount))) { - // Register new chrome - nsCOMPtr chromeReg = - do_GetService("@mozilla.org/chrome/chrome-registry;1"); - if (chromeReg) { - chromeReg->CheckForNewChrome(); - chromeReg = 0; - } - NS_TermEmbedding(); - } - - [NSApp terminate:self]; - return self; - } NSString* url = [defaults stringForKey:USER_DEFAULTS_URL_KEY]; mStartURL = url ? [url retain] : nil; diff --git a/mozilla/camino/src/application/UserDefaults.h b/mozilla/camino/src/application/UserDefaults.h index 84e29447898..4eb2985dd0f 100644 --- a/mozilla/camino/src/application/UserDefaults.h +++ b/mozilla/camino/src/application/UserDefaults.h @@ -44,7 +44,6 @@ */ -#define USER_DEFAULTS_AUTOREGISTER_KEY @"autoRegister" /* Boolean */ #define USER_DEFAULTS_URL_KEY @"url" /* String */ #define USER_DEFAULTS_HIDE_PERS_TOOLBAR_KEY @"Hide Personal Toolbar" /* Integer */ diff --git a/mozilla/camino/src/preferences/PreferenceManager.mm b/mozilla/camino/src/preferences/PreferenceManager.mm index d65b9c430ef..1f4d0e55a94 100644 --- a/mozilla/camino/src/preferences/PreferenceManager.mm +++ b/mozilla/camino/src/preferences/PreferenceManager.mm @@ -62,6 +62,8 @@ #include "nsIStyleSheetService.h" #include "nsNetUtil.h" #include "nsStaticComponents.h" +#include "nsILocalFileMac.h" +#include "nsINIParser.h" #ifndef _BUILD_STATIC_BIN nsStaticModuleInfo const *const kPStaticModules = nsnull; @@ -95,6 +97,109 @@ static NSString* const AdBlockingChangedNotificationName = @"AdBlockingChanged"; // some prefs to be upgraded. static const PRInt32 kCurrentPrefsVersion = 1; +// CheckCompatibility and WriteVersion are based on the versions in +// toolkit/xre/nsAppRunner.cpp. This is done to provide forward +// compatibility in anticipation of Camino-on-XULRunner. + +#define FILE_COMPATIBILITY_INFO NS_LITERAL_CSTRING("compatibility.ini") + +static PRBool +CheckCompatibility(nsIFile* aProfileDir, const nsACString& aVersion, + const nsACString& aOSABI, nsIFile* aAppDir) +{ + nsCOMPtr file; + aProfileDir->Clone(getter_AddRefs(file)); + if (!file) + return PR_FALSE; + file->AppendNative(FILE_COMPATIBILITY_INFO); + + nsINIParser parser; + nsCOMPtr localFile(do_QueryInterface(file)); + nsresult rv = parser.Init(localFile); + if (NS_FAILED(rv)) + return PR_FALSE; + + nsCAutoString buf; + rv = parser.GetString("Compatibility", "LastVersion", buf); + if (NS_FAILED(rv)) + return PR_FALSE; + + if (!aVersion.Equals(buf)) + return PR_FALSE; + + rv = parser.GetString("Compatibility", "LastOSABI", buf); + if (NS_FAILED(rv)) + return PR_FALSE; + + if (!aOSABI.Equals(buf)) + return PR_FALSE; + + if (aAppDir) { + rv = parser.GetString("Compatibility", "LastAppDir", buf); + if (NS_FAILED(rv)) + return PR_FALSE; + + nsCOMPtr lf; + + rv = NS_NewNativeLocalFile(buf, PR_FALSE, + getter_AddRefs(lf)); + if (NS_FAILED(rv)) + return PR_FALSE; + + PRBool eq; + rv = lf->Equals(aAppDir, &eq); + if (NS_FAILED(rv) || !eq) + return PR_FALSE; + } + + return PR_TRUE; +} + +static void +WriteVersion(nsIFile* aProfileDir, const nsACString& aVersion, + const nsACString& aOSABI, nsIFile* aAppDir) +{ + nsCOMPtr file; + aProfileDir->Clone(getter_AddRefs(file)); + if (!file) + return; + file->AppendNative(FILE_COMPATIBILITY_INFO); + + nsCOMPtr lf = do_QueryInterface(file); + + nsCAutoString appDir; + if (aAppDir) + aAppDir->GetNativePath(appDir); + + PRFileDesc *fd = nsnull; + lf->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0600, &fd); + if (!fd) { + NS_ERROR("could not create output stream"); + return; + } + + static const char kHeader[] = "[Compatibility]" NS_LINEBREAK + "LastVersion="; + + PR_Write(fd, kHeader, sizeof(kHeader) - 1); + PR_Write(fd, PromiseFlatCString(aVersion).get(), aVersion.Length()); + + static const char kOSABIHeader[] = NS_LINEBREAK "LastOSABI="; + PR_Write(fd, kOSABIHeader, sizeof(kOSABIHeader) - 1); + PR_Write(fd, PromiseFlatCString(aOSABI).get(), aOSABI.Length()); + + static const char kAppDirHeader[] = NS_LINEBREAK "LastAppDir="; + if (aAppDir) { + PR_Write(fd, kAppDirHeader, sizeof(kAppDirHeader) - 1); + PR_Write(fd, appDir.get(), appDir.Length()); + } + + static const char kNL[] = NS_LINEBREAK; + PR_Write(fd, kNL, sizeof(kNL) - 1); + + PR_Close(fd); +} + @interface PreferenceManager(PreferenceManagerPrivate) - (void)registerNotificationListener; @@ -399,6 +504,62 @@ static BOOL gMadePrefManager; } nsCOMPtr dirProvider = (nsIDirectoryServiceProvider*)provider; + + const char* executablePath = [[[NSBundle mainBundle] executablePath] fileSystemRepresentation]; + nsCOMPtr executable; + NS_NewNativeLocalFile(nsDependentCString(executablePath), + PR_TRUE, getter_AddRefs(executable)); + + nsCOMPtr profileDir; + PRBool bogus = PR_FALSE; + rv = dirProvider->GetFile(NS_APP_USER_PROFILES_ROOT_DIR, &bogus, + getter_AddRefs(profileDir)); + if (NS_FAILED(rv)) { + [self showLaunchFailureAndQuitWithErrorTitle:NSLocalizedString(@"StartupFailureAlert", @"") + errorMessage:NSLocalizedString(@"StartupFailureProfilePathMsg", @"")]; + // not reached + return NO; + } + + const char* appVersion = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"] UTF8String]; + nsCAutoString version; + version.Assign(appVersion); + version.Append('/'); + version.AppendLiteral(GRE_BUILD_ID); + +#ifdef __ppc__ + NS_NAMED_LITERAL_CSTRING(osABI, "Darwin_ppc-gcc3"); +#else +#ifdef __i386__ + NS_NAMED_LITERAL_CSTRING(osABI, "Darwin_x86-gcc3"); +#else + NS_NAMED_LITERAL_CSTRING(osABI, "Darwin_UNKNOWN"); +#endif +#endif + + PRBool versionOK = CheckCompatibility(profileDir, version, osABI, executable); + + if (!versionOK) { + // This isn't the same version that previously used the selected + // profile. Remove some caches from the profile, allowing them to + // be regenerated. NS_InitEmbedding will reregister components, + // producing compreg.dat and xpti.dat. Note that this occurs prior + // to any profile lock check, because it's inconvenient to move the + // profile lock check up. However, doing things this way should be + // harmless. Note that WriteVersion isn't called until after the + // profile lock check. + nsCOMPtr file; + profileDir->Clone(getter_AddRefs(file)); + if (file) { + file->AppendNative(NS_LITERAL_CSTRING("compreg.dat")); + file->Remove(PR_FALSE); + file->SetNativeLeafName(NS_LITERAL_CSTRING("xpti.dat")); + file->Remove(PR_FALSE); + file->SetNativeLeafName(NS_LITERAL_CSTRING("XUL.mfasl")); + file->Remove(PR_FALSE); + } + } + rv = NS_InitEmbedding(binDir, dirProvider, kPStaticModules, kStaticModuleCount); if (NS_FAILED(rv)) { @@ -436,17 +597,6 @@ static BOOL gMadePrefManager; } mProfileProvider->Register(); - nsCOMPtr profileDir; - rv = NS_NewNativeLocalFile(nsDependentCString([profilePath fileSystemRepresentation]), - PR_TRUE, getter_AddRefs(profileDir)); - if (NS_FAILED(rv)) - { - [self showLaunchFailureAndQuitWithErrorTitle:NSLocalizedString(@"StartupFailureAlert", @"") - errorMessage:NSLocalizedString(@"StartupFailureMsg", @"")]; - // not reached - return NO; - } - rv = mProfileProvider->SetProfileDir(profileDir); if (NS_FAILED(rv)) { if (rv == NS_ERROR_FILE_ACCESS_DENIED) { @@ -475,6 +625,9 @@ static BOOL gMadePrefManager; [self syncMozillaPrefs]; + if (!versionOK) + WriteVersion(profileDir, version, osABI, executable); + // send out initted notification [[NSNotificationCenter defaultCenter] postNotificationName:InitEmbeddingNotificationName object:nil];