gecko-dev/toolkit/xre/ProfileReset.h
Dave Townsend ca5293cbed Bug 1474285: Implement dedicated profiles per install. r=froydnj, r=Gijs
Uses a different profile depending on the install directory of the application.
installs.ini is used to map a hash of the install directory to a profile
directory.

If no profile is marked as default for the current install we use a heuristic
explained in the code to decide whether to use the profile that would have
been used before this feature.

The feature is disabled in snap builds where the install directory changes for
every version of the app, but multiple instances cannot share profiles anyway.
A boolean flag is used to turn on the feature because in a later patch we need
to be able to turn off the behaviour at runtime.

Includes code folded in from bug 1518634, bug 1522751, bug 1518632 and bug 1523024.

--HG--
extra : rebase_source : 0250c70e992fd8369e52ccee3755cf116a894791
extra : intermediate-source : e69cac07b209ad4ef4229815ffd8138ed64c348e
extra : source : e406bf0bcd665bd0e54ddb13d9ae880004badef1
2019-01-25 16:02:28 -08:00

81 lines
2.7 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 "nsToolkitProfileService.h"
#include "nsIFile.h"
#include "nsThreadUtils.h"
static bool gProfileResetCleanupCompleted = false;
static const char kResetProgressURL[] =
"chrome://global/content/resetProfileProgress.xul";
nsresult ProfileResetCleanup(nsToolkitProfileService* aService,
nsIToolkitProfile* aOldProfile);
class ProfileResetCleanupResultTask : public mozilla::Runnable {
public:
ProfileResetCleanupResultTask()
: mozilla::Runnable("ProfileResetCleanupResultTask"),
mWorkerThread(do_GetCurrentThread()) {
MOZ_ASSERT(!NS_IsMainThread());
}
NS_IMETHOD Run() override {
MOZ_ASSERT(NS_IsMainThread());
mWorkerThread->Shutdown();
return NS_OK;
}
private:
nsCOMPtr<nsIThread> mWorkerThread;
};
class ProfileResetCleanupAsyncTask : public mozilla::Runnable {
public:
ProfileResetCleanupAsyncTask(nsIFile* aProfileDir, nsIFile* aProfileLocalDir,
nsIFile* aTargetDir, const nsAString& aLeafName)
: mozilla::Runnable("ProfileResetCleanupAsyncTask"),
mProfileDir(aProfileDir),
mProfileLocalDir(aProfileLocalDir),
mTargetDir(aTargetDir),
mLeafName(aLeafName) {}
/**
* Copy a root profile to a backup folder before deleting it. Then delete the
* local profile dir.
*/
NS_IMETHOD Run() override {
// Copy to the destination then delete the profile. A move doesn't follow
// links.
nsresult rv = mProfileDir->CopyToFollowingLinks(mTargetDir, mLeafName);
if (NS_SUCCEEDED(rv)) rv = mProfileDir->Remove(true);
if (NS_WARN_IF(NS_FAILED(rv))) {
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;
nsresult rvLocal = mProfileDir->Equals(mProfileLocalDir, &sameDir);
if (NS_SUCCEEDED(rvLocal) && !sameDir) {
rvLocal = mProfileLocalDir->Remove(true);
if (NS_FAILED(rvLocal))
NS_WARNING("Could not remove the old local profile directory (cache)");
}
gProfileResetCleanupCompleted = true;
nsCOMPtr<nsIRunnable> resultRunnable = new ProfileResetCleanupResultTask();
NS_DispatchToMainThread(resultRunnable);
return NS_OK;
}
private:
nsCOMPtr<nsIFile> mProfileDir;
nsCOMPtr<nsIFile> mProfileLocalDir;
nsCOMPtr<nsIFile> mTargetDir;
nsString mLeafName;
};