gecko-dev/toolkit/xre/ProfileReset.cpp
Ehsan Akhgari 1b83407ce9 Bug 927728 - Part 1: Replace PRUnichar with char16_t; r=roc
This patch was automatically generated by the following script:

#!/bin/bash
# Command to convert PRUnichar to char16_t

function convert() {
echo "Converting $1 to $2..."
find . ! -wholename "*nsprpub*" \
       ! -wholename "*security/nss*" \
       ! -wholename "*modules/libmar*" \
       ! -wholename "*/.hg*" \
       ! -wholename "obj-ff-dbg*" \
       ! -name prtypes.h \
       ! -name Char16.h \
         -type f \
      \( -iname "*.cpp" \
         -o -iname "*.h" \
         -o -iname "*.c" \
         -o -iname "*.cc" \
         -o -iname "*.idl" \
         -o -iname "*.ipdl" \
         -o -iname "*.ipdlh" \
         -o -iname "*.mm" \) | \
    xargs -n 1 sed -i -e "s/\b$1\b/$2/g"
}

convert PRUnichar char16_t
2014-01-04 10:02:17 -05:00

175 lines
6.2 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIAppStartup.h"
#include "nsIDOMWindow.h"
#include "nsIFile.h"
#include "nsIStringBundle.h"
#include "nsIToolkitProfile.h"
#include "nsIWindowWatcher.h"
#include "ProfileReset.h"
#include "nsDirectoryServiceDefs.h"
#include "nsDirectoryServiceUtils.h"
#include "nsPrintfCString.h"
#include "nsToolkitCompsCID.h"
#include "nsXPCOMCIDInternal.h"
#include "nsXREAppData.h"
#include "mozilla/Services.h"
#include "prtime.h"
extern const nsXREAppData* gAppData;
static const char kProfileProperties[] =
"chrome://mozapps/locale/profile/profileSelection.properties";
/**
* Creates a new profile with a timestamp in the name to use for profile reset.
*/
nsresult
CreateResetProfile(nsIToolkitProfileService* aProfileSvc, nsIToolkitProfile* *aNewProfile)
{
NS_ABORT_IF_FALSE(aProfileSvc, "NULL profile service");
nsCOMPtr<nsIToolkitProfile> newProfile;
// Make the new profile "default-" + the time in seconds since epoch for uniqueness.
nsAutoCString newProfileName("default-");
newProfileName.Append(nsPrintfCString("%lld", PR_Now() / 1000));
nsresult rv = aProfileSvc->CreateProfile(nullptr, // choose a default dir for us
newProfileName,
getter_AddRefs(newProfile));
if (NS_FAILED(rv)) return rv;
rv = aProfileSvc->Flush();
if (NS_FAILED(rv)) return rv;
newProfile.swap(*aNewProfile);
return NS_OK;
}
/**
* Delete the profile directory being reset after a backup and delete the local profile directory.
*/
nsresult
ProfileResetCleanup(nsIToolkitProfile* aOldProfile)
{
nsresult rv;
nsCOMPtr<nsIFile> profileDir;
rv = aOldProfile->GetRootDir(getter_AddRefs(profileDir));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIFile> profileLocalDir;
rv = aOldProfile->GetLocalDir(getter_AddRefs(profileLocalDir));
if (NS_FAILED(rv)) return rv;
// Get the friendly name for the backup directory.
nsCOMPtr<nsIStringBundleService> sbs = mozilla::services::GetStringBundleService();
if (!sbs) return NS_ERROR_FAILURE;
nsCOMPtr<nsIStringBundle> sb;
rv = sbs->CreateBundle(kProfileProperties, getter_AddRefs(sb));
if (!sb) return NS_ERROR_FAILURE;
NS_ConvertUTF8toUTF16 appName(gAppData->name);
const char16_t* params[] = {appName.get(), appName.get()};
nsXPIDLString resetBackupDirectoryName;
static const char16_t* kResetBackupDirectory = MOZ_UTF16("resetBackupDirectory");
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, 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 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;
// 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 = 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;
nsCOMPtr<nsIDOMWindow> progressWindow;
rv = windowWatcher->OpenWindow(nullptr,
kResetProgressURL,
"_blank",
"centerscreen,chrome,titlebar",
nullptr,
getter_AddRefs(progressWindow));
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,
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 by the thread above.
rv = aOldProfile->Remove(false);
if (NS_FAILED(rv)) NS_WARNING("Could not remove the profile");
return rv;
}