Bug 763890 - Add all the old profiles to the same folder when resetting Firefox multiple times, r=bsmedberg
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Fri, 05 Apr 2013 14:31:28 +0200
changeset 130147 824fccf23d6f56a741c4718e365777fbaa8f903e
parent 130146 7f6765e6e3be80ec54f024c5259beeea262d2ede
child 130148 6553478822f55b678f5071b345370c2093485581
push id24599
push userryanvm@gmail.com
push dateSun, 28 Apr 2013 01:24:06 +0000
treeherdermozilla-central@9d8977cbbfc6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs763890
milestone23.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 763890 - Add all the old profiles to the same folder when resetting Firefox multiple times, r=bsmedberg
toolkit/xre/ProfileReset.cpp
toolkit/xre/ProfileReset.h
--- a/toolkit/xre/ProfileReset.cpp
+++ b/toolkit/xre/ProfileReset.cpp
@@ -80,35 +80,56 @@ ProfileResetCleanup(nsIToolkitProfile* a
 
   nsXPIDLString resetBackupDirectoryName;
 
   static const PRUnichar* kResetBackupDirectory = NS_LITERAL_STRING("resetBackupDirectory").get();
   rv = sb->FormatStringFromName(kResetBackupDirectory, params, 2,
                                 getter_Copies(resetBackupDirectoryName));
 
   // Get info to copy the old root profile dir to the desktop as a backup.
-  nsCOMPtr<nsIFile> backupDest, uniqueDest;
+  nsCOMPtr<nsIFile> backupDest, containerDest, profileDest;
   rv = NS_GetSpecialDirectory(NS_OS_DESKTOP_DIR, getter_AddRefs(backupDest));
   if (NS_FAILED(rv)) {
     // Fall back to the home directory if the desktop is not available.
     rv = NS_GetSpecialDirectory(NS_OS_HOME_DIR, getter_AddRefs(backupDest));
     if (NS_FAILED(rv)) return rv;
   }
 
-  // Try to get a unique backup directory name.
-  backupDest->Clone(getter_AddRefs(uniqueDest));
-  uniqueDest->Append(resetBackupDirectoryName);
-  rv = uniqueDest->CreateUnique(nsIFile::DIRECTORY_TYPE, 0700);
+  // Try to create a directory for all the backups
+  backupDest->Clone(getter_AddRefs(containerDest));
+  containerDest->Append(resetBackupDirectoryName);
+  rv = containerDest->Create(nsIFile::DIRECTORY_TYPE, 0700);
+  // It's OK if it already exists, if and only if it is a directory
+  if (rv == NS_ERROR_FILE_ALREADY_EXISTS) {
+    bool containerIsDir;
+    rv = containerDest->IsDirectory(&containerIsDir);
+    if (NS_FAILED(rv) || !containerIsDir) {
+      return rv;
+    }
+  } else if (NS_FAILED(rv)) {
+    return rv;
+  }
+
+  // Get the name of the profile
+  nsAutoString leafName;
+  rv = profileDir->GetLeafName(leafName);
   if (NS_FAILED(rv)) return rv;
 
-  nsAutoString leafName;
-  rv = uniqueDest->GetLeafName(leafName);
+  // Try to create a unique directory for the profile:
+  containerDest->Clone(getter_AddRefs(profileDest));
+  profileDest->Append(leafName);
+  rv = profileDest->CreateUnique(nsIFile::DIRECTORY_TYPE, 0700);
   if (NS_FAILED(rv)) return rv;
+
+  // Get the unique profile name
+  rv = profileDest->GetLeafName(leafName);
+  if (NS_FAILED(rv)) return rv;
+
   // Delete the empty directory that CreateUnique just created.
-  rv = uniqueDest->Remove(false);
+  rv = profileDest->Remove(false);
   if (NS_FAILED(rv)) return rv;
 
   // Show a progress window while the cleanup happens since the disk I/O can take time.
   nsCOMPtr<nsIWindowWatcher> windowWatcher(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
   if (!windowWatcher) return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIAppStartup> appStartup(do_GetService(NS_APPSTARTUP_CONTRACTID));
   if (!appStartup) return NS_ERROR_FAILURE;
@@ -123,31 +144,31 @@ ProfileResetCleanup(nsIToolkitProfile* a
   if (NS_FAILED(rv)) return rv;
 
   // Create a new thread to do the bulk of profile cleanup to stay responsive.
   nsCOMPtr<nsIThreadManager> tm = do_GetService(NS_THREADMANAGER_CONTRACTID);
   nsCOMPtr<nsIThread> cleanupThread;
   rv = tm->NewThread(0, 0, getter_AddRefs(cleanupThread));
   if (NS_SUCCEEDED(rv)) {
     nsCOMPtr<nsIRunnable> runnable = new ProfileResetCleanupAsyncTask(profileDir, profileLocalDir,
-                                                                      backupDest, leafName);
+                                                                      containerDest, leafName);
     cleanupThread->Dispatch(runnable, nsIThread::DISPATCH_NORMAL);
     // The result callback will shut down the worker thread.
 
     nsIThread *thread = NS_GetCurrentThread();
     // Wait for the cleanup thread to complete.
     while(!gProfileResetCleanupCompleted) {
       NS_ProcessNextEvent(thread);
     }
   } else {
     gProfileResetCleanupCompleted = true;
     NS_WARNING("Cleanup thread creation failed");
     return rv;
   }
   // Close the progress window now that the cleanup thread is done.
   progressWindow->Close();
 
-  // Delete the old profile from profiles.ini. The folder was already deleted above.
+  // Delete the old profile from profiles.ini. The folder was already deleted by the thread above.
   rv = aOldProfile->Remove(false);
   if (NS_FAILED(rv)) NS_WARNING("Could not remove the profile");
 
   return rv;
 }
--- a/toolkit/xre/ProfileReset.h
+++ b/toolkit/xre/ProfileReset.h
@@ -33,30 +33,30 @@ public:
 private:
   nsCOMPtr<nsIThread> mWorkerThread;
 };
 
 class ProfileResetCleanupAsyncTask : public nsRunnable
 {
 public:
   ProfileResetCleanupAsyncTask(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
-                               nsIFile* aDesktop, const nsAString &aLeafName)
+                               nsIFile* aTargetDir, const nsAString &aLeafName)
     : mProfileDir(aProfileDir)
     , mProfileLocalDir(aProfileLocalDir)
-    , mDesktop(aDesktop)
+    , mTargetDir(aTargetDir)
     , mLeafName(aLeafName)
   { }
 
 /**
  * Copy a root profile to a backup folder before deleting it.  Then delete the local profile dir.
  */
   NS_IMETHOD Run()
   {
     // Copy to the destination then delete the profile. A move doesn't follow links.
-    nsresult rv = mProfileDir->CopyToFollowingLinks(mDesktop, mLeafName);
+    nsresult rv = mProfileDir->CopyToFollowingLinks(mTargetDir, mLeafName);
     if (NS_SUCCEEDED(rv))
       rv = mProfileDir->Remove(true);
     else
       NS_WARNING("Could not backup the root profile directory");
 
     // If we have a separate local cache profile directory, just delete it.
     // Don't return an error if this fails so that reset can proceed if it can't be deleted.
     bool sameDir;
@@ -70,11 +70,11 @@ public:
     nsCOMPtr<nsIRunnable> resultRunnable = new ProfileResetCleanupResultTask();
     NS_DispatchToMainThread(resultRunnable);
     return NS_OK;
   }
 
 private:
   nsCOMPtr<nsIFile> mProfileDir;
   nsCOMPtr<nsIFile> mProfileLocalDir;
-  nsCOMPtr<nsIFile> mDesktop;
+  nsCOMPtr<nsIFile> mTargetDir;
   nsAutoString mLeafName;
 };