Commit a3c9782c authored by Kathleen Brade's avatar Kathleen Brade Committed by Georg Koppen
Browse files

Bug 9173: Change the default Firefox profile directory to be TBB-relative.

This should eliminate our need to rely on a wrapper script that
sets /Users/arthur and launches Firefox with -profile.
parent 52a77ae9
Loading
Loading
Loading
Loading
+34 −120
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include "nsArrayEnumerator.h"
#include "nsEnumeratorUtils.h"
#include "nsReadableUtils.h"
#include "nsXPCOMPrivate.h"  // for XPCOM_FILE_PATH_SEPARATOR

#include "SpecialSystemDirectory.h"

@@ -228,9 +229,6 @@ nsXREDirProvider::GetUserProfilesRootDir(nsIFile** aResult)
  nsresult rv = GetUserDataDirectory(getter_AddRefs(file), false);

  if (NS_SUCCEEDED(rv)) {
#if !defined(XP_UNIX) || defined(XP_MACOSX)
    rv = file->AppendNative(NS_LITERAL_CSTRING("Profiles"));
#endif
    // We must create the profile directory here if it does not exist.
    nsresult tmp = EnsureDirectoryExists(file);
    if (NS_FAILED(tmp)) {
@@ -248,9 +246,6 @@ nsXREDirProvider::GetUserProfilesLocalDir(nsIFile** aResult)
  nsresult rv = GetUserDataDirectory(getter_AddRefs(file), true);

  if (NS_SUCCEEDED(rv)) {
#if !defined(XP_UNIX) || defined(XP_MACOSX)
    rv = file->AppendNative(NS_LITERAL_CSTRING("Profiles"));
#endif
    // We must create the profile directory here if it does not exist.
    nsresult tmp = EnsureDirectoryExists(file);
    if (NS_FAILED(tmp)) {
@@ -1394,87 +1389,44 @@ nsresult
nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile, bool aLocal)
{
  // Copied from nsAppFileLocationProvider (more or less)
  nsresult rv;
  NS_ENSURE_ARG_POINTER(aFile);
  nsCOMPtr<nsIFile> localDir;

  nsresult rv = GetAppDir()->Clone(getter_AddRefs(localDir));
  NS_ENSURE_SUCCESS(rv, rv);

  int levelsToRemove = 1; // In FF21+, appDir points to browser subdirectory.
#if defined(XP_MACOSX)
  FSRef fsRef;
  OSType folderType;
  if (aLocal) {
    folderType = kCachedDataFolderType;
  } else {
#ifdef MOZ_THUNDERBIRD
    folderType = kDomainLibraryFolderType;
#else
    folderType = kApplicationSupportFolderType;
  levelsToRemove += 2;
#endif
  }
  OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef);
  NS_ENSURE_FALSE(err, NS_ERROR_FAILURE);

  rv = NS_NewNativeLocalFile(EmptyCString(), true, getter_AddRefs(localDir));
  while (localDir && (levelsToRemove > 0)) {
    // When crawling up the hierarchy, components named "." do not count.
    nsAutoCString removedName;
    rv = localDir->GetNativeLeafName(removedName);
    NS_ENSURE_SUCCESS(rv, rv);
    bool didRemove = !removedName.Equals(".");

  nsCOMPtr<nsILocalFileMac> dirFileMac = do_QueryInterface(localDir);
  NS_ENSURE_TRUE(dirFileMac, NS_ERROR_UNEXPECTED);

  rv = dirFileMac->InitWithFSRef(&fsRef);
    // Remove a directory component.
    nsCOMPtr<nsIFile> parentDir;
    rv = localDir->GetParent(getter_AddRefs(parentDir));
    NS_ENSURE_SUCCESS(rv, rv);

  localDir = do_QueryInterface(dirFileMac, &rv);
#elif defined(XP_IOS)
  nsAutoCString userDir;
  if (GetUIKitDirectory(aLocal, userDir)) {
    rv = NS_NewNativeLocalFile(userDir, true, getter_AddRefs(localDir));
  } else {
    rv = NS_ERROR_FAILURE;
    localDir = parentDir;
    if (didRemove)
      --levelsToRemove;
  }
  NS_ENSURE_SUCCESS(rv, rv);
#elif defined(XP_WIN)
  nsString path;
  if (aLocal) {
    rv = GetShellFolderPath(FOLDERID_LocalAppData, path);
    if (NS_FAILED(rv))
      rv = GetRegWindowsAppDataFolder(aLocal, path);
  }
  if (!aLocal || NS_FAILED(rv)) {
    rv = GetShellFolderPath(FOLDERID_RoamingAppData, path);
    if (NS_FAILED(rv)) {
      if (!aLocal)
        rv = GetRegWindowsAppDataFolder(aLocal, path);
    }
  }
  NS_ENSURE_SUCCESS(rv, rv);

  rv = NS_NewLocalFile(path, true, getter_AddRefs(localDir));
#elif defined(XP_UNIX)
  const char* homeDir = getenv("HOME");
  if (!homeDir || !*homeDir)
  if (!localDir)
    return NS_ERROR_FAILURE;

#ifdef ANDROID /* We want (ProfD == ProfLD) on Android. */
  aLocal = false;
#endif
  rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser"
                                     XPCOM_FILE_PATH_SEPARATOR "Data"
                                     XPCOM_FILE_PATH_SEPARATOR "Browser"));
  NS_ENSURE_SUCCESS(rv, rv);

  if (aLocal) {
    // If $XDG_CACHE_HOME is defined use it, otherwise use $HOME/.cache.
    const char* cacheHome = getenv("XDG_CACHE_HOME");
    if (cacheHome && *cacheHome) {
      rv = NS_NewNativeLocalFile(nsDependentCString(cacheHome), true,
                                 getter_AddRefs(localDir));
    } else {
      rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
                                 getter_AddRefs(localDir));
      if (NS_SUCCEEDED(rv))
        rv = localDir->AppendNative(NS_LITERAL_CSTRING(".cache"));
    }
  } else {
    rv = NS_NewNativeLocalFile(nsDependentCString(homeDir), true,
                               getter_AddRefs(localDir));
    rv = localDir->AppendNative(NS_LITERAL_CSTRING("Caches"));
    NS_ENSURE_SUCCESS(rv, rv);
  }
#else
#error "Don't know how to get product dir on your platform"
#endif

  NS_IF_ADDREF(*aFile = localDir);
  return rv;
@@ -1662,41 +1614,23 @@ nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal)
  }

  nsAutoCString profile;
  nsAutoCString appName;
  nsAutoCString vendor;
  if (gAppData->profile) {
    profile = gAppData->profile;
  } else {
    appName = gAppData->name;
    vendor = gAppData->vendor;
  }

  nsresult rv;
  nsresult rv = NS_ERROR_FAILURE;

#if defined (XP_MACOSX)
  if (!profile.IsEmpty()) {
    rv = AppendProfileString(aFile, profile.get());
  }
  else {
    // Note that MacOS ignores the vendor when creating the profile hierarchy -
    // all application preferences directories live alongside one another in
    // ~/Library/Application Support/
    rv = aFile->AppendNative(appName);
  }
    NS_ENSURE_SUCCESS(rv, rv);
  }

#elif defined(XP_WIN)
  if (!profile.IsEmpty()) {
    rv = AppendProfileString(aFile, profile.get());
  }
  else {
    if (!vendor.IsEmpty()) {
      rv = aFile->AppendNative(vendor);
    NS_ENSURE_SUCCESS(rv, rv);
  }
    rv = aFile->AppendNative(appName);
  }
  NS_ENSURE_SUCCESS(rv, rv);

#elif defined(ANDROID)
  // The directory used for storing profiles
@@ -1706,12 +1640,6 @@ nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal)
  rv = aFile->AppendNative(nsDependentCString("mozilla"));
  NS_ENSURE_SUCCESS(rv, rv);
#elif defined(XP_UNIX)
  nsAutoCString folder;
  // Make it hidden (by starting with "."), except when local (the
  // profile is already under ~/.cache or XDG_CACHE_HOME).
  if (!aLocal)
    folder.Assign('.');

  if (!profile.IsEmpty()) {
    // Skip any leading path characters
    const char* profileStart = profile.get();
@@ -1720,31 +1648,17 @@ nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal)

    // On the off chance that someone wanted their folder to be hidden don't
    // let it become ".."
    if (*profileStart == '.' && !aLocal)
    if (*profileStart == '.')
      profileStart++;

    // Make it hidden (by starting with ".").
    nsAutoCString folder(".");
    folder.Append(profileStart);
    ToLowerCase(folder);

    rv = AppendProfileString(aFile, folder.BeginReading());
  }
  else {
    if (!vendor.IsEmpty()) {
      folder.Append(vendor);
      ToLowerCase(folder);

      rv = aFile->AppendNative(folder);
    NS_ENSURE_SUCCESS(rv, rv);

      folder.Truncate();
    }

    folder.Append(appName);
    ToLowerCase(folder);

    rv = aFile->AppendNative(folder);
  }
  NS_ENSURE_SUCCESS(rv, rv);

#else
#error "Don't know how to get profile path on your platform"
+6 −6
Original line number Diff line number Diff line
@@ -50,15 +50,15 @@ public:

  void DoShutdown();

  static nsresult GetUserAppDataDirectory(nsIFile* *aFile) {
  nsresult GetUserAppDataDirectory(nsIFile* *aFile) {
    return GetUserDataDirectory(aFile, false);
  }
  static nsresult GetUserLocalDataDirectory(nsIFile* *aFile) {
  nsresult GetUserLocalDataDirectory(nsIFile* *aFile) {
    return GetUserDataDirectory(aFile, true);
  }

  // GetUserDataDirectory gets the profile path from gAppData.
  static nsresult GetUserDataDirectory(nsIFile** aFile, bool aLocal);
  nsresult GetUserDataDirectory(nsIFile** aFile, bool aLocal);

  /* make sure you clone it, if you need to do stuff to it */
  nsIFile* GetGREDir() { return mGREDir; }
@@ -92,9 +92,9 @@ public:

protected:
  nsresult GetFilesInternal(const char* aProperty, nsISimpleEnumerator** aResult);
  static nsresult GetUserDataDirectoryHome(nsIFile* *aFile, bool aLocal);
  static nsresult GetSysUserExtensionsDirectory(nsIFile* *aFile);
  static nsresult GetSysUserExtensionsDevDirectory(nsIFile* *aFile);
  nsresult GetUserDataDirectoryHome(nsIFile* *aFile, bool aLocal);
  nsresult GetSysUserExtensionsDirectory(nsIFile* *aFile);
  nsresult GetSysUserExtensionsDevDirectory(nsIFile* *aFile);
#if defined(XP_UNIX) || defined(XP_MACOSX)
  static nsresult GetSystemExtensionsDirectory(nsIFile** aFile);
#endif
+36 −60
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include "nsISimpleEnumerator.h"
#include "prenv.h"
#include "nsCRT.h"
#include "nsXPCOMPrivate.h"  // for XPCOM_FILE_PATH_SEPARATOR
#if defined(MOZ_WIDGET_COCOA)
#include <Carbon/Carbon.h>
#include "nsILocalFileMac.h"
@@ -252,9 +253,8 @@ nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile** aLocalFile)
//----------------------------------------------------------------------------------------
// GetProductDirectory - Gets the directory which contains the application data folder
//
// UNIX   : ~/.mozilla/
// WIN    : <Application Data folder on user's machine>\Mozilla
// Mac    : :Documents:Mozilla:
// UNIX and WIN   : <App Folder>/TorBrowser/Data/Browser
// Mac            : <App Folder>/../../TorBrowser/Data/Browser
//----------------------------------------------------------------------------------------
nsresult
nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
@@ -268,48 +268,45 @@ nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
  bool exists;
  nsCOMPtr<nsIFile> localDir;

#if defined(MOZ_WIDGET_COCOA)
  FSRef fsRef;
  OSType folderType = aLocal ? (OSType)kCachedDataFolderType :
                               (OSType)kDomainLibraryFolderType;
  OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef);
  if (err) {
    return NS_ERROR_FAILURE;
  rv = CloneMozBinDirectory(getter_AddRefs(localDir));
  NS_ENSURE_SUCCESS(rv, rv);

  int levelsToRemove = 1; // In FF21+, bin dir points to browser subdirectory.
#if defined(XP_MACOSX)
  levelsToRemove += 2;
#endif
  while (localDir && (levelsToRemove > 0)) {
    // When crawling up the hierarchy, components named "." do not count.
    nsAutoCString removedName;
    rv = localDir->GetNativeLeafName(removedName);
    NS_ENSURE_SUCCESS(rv, rv);
    bool didRemove = !removedName.Equals(".");

    // Remove a directory component.
    nsCOMPtr<nsIFile> parentDir;
    rv = localDir->GetParent(getter_AddRefs(parentDir));
    NS_ENSURE_SUCCESS(rv, rv);
    localDir = parentDir;

    if (didRemove) {
      --levelsToRemove;
    }
  NS_NewLocalFile(EmptyString(), true, getter_AddRefs(localDir));
  }

  if (!localDir) {
    return NS_ERROR_FAILURE;
  }
  nsCOMPtr<nsILocalFileMac> localDirMac(do_QueryInterface(localDir));
  rv = localDirMac->InitWithFSRef(&fsRef);
  if (NS_FAILED(rv)) {
    return rv;
  }
#elif defined(XP_WIN)
  nsCOMPtr<nsIProperties> directoryService =
    do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
  if (NS_FAILED(rv)) {
    return rv;
  }
  const char* prop = aLocal ? NS_WIN_LOCAL_APPDATA_DIR : NS_WIN_APPDATA_DIR;
  rv = directoryService->Get(prop, NS_GET_IID(nsIFile), getter_AddRefs(localDir));
  if (NS_FAILED(rv)) {
    return rv;
  }
#elif defined(XP_UNIX)
  rv = NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), true,
                             getter_AddRefs(localDir));
  if (NS_FAILED(rv)) {
    return rv;
  }
#else
#error dont_know_how_to_get_product_dir_on_your_platform
#endif

  rv = localDir->AppendRelativeNativePath(DEFAULT_PRODUCT_DIR);
  if (NS_FAILED(rv)) {
    return rv;
  rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser"
                                        XPCOM_FILE_PATH_SEPARATOR "Data"
                                        XPCOM_FILE_PATH_SEPARATOR "Browser"));
  NS_ENSURE_SUCCESS(rv, rv);

  if (aLocal) {
    rv = localDir->AppendNative(NS_LITERAL_CSTRING("Caches"));
    NS_ENSURE_SUCCESS(rv, rv);
  }

  rv = localDir->Exists(&exists);

  if (NS_SUCCEEDED(rv) && !exists) {
@@ -328,10 +325,6 @@ nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,

//----------------------------------------------------------------------------------------
// GetDefaultUserProfileRoot - Gets the directory which contains each user profile dir
//
// UNIX   : ~/.mozilla/
// WIN    : <Application Data folder on user's machine>\Mozilla\Profiles
// Mac    : :Documents:Mozilla:Profiles:
//----------------------------------------------------------------------------------------
nsresult
nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsIFile** aLocalFile,
@@ -349,23 +342,6 @@ nsAppFileLocationProvider::GetDefaultUserProfileRoot(nsIFile** aLocalFile,
    return rv;
  }

#if defined(MOZ_WIDGET_COCOA) || defined(XP_WIN)
  // These 3 platforms share this part of the path - do them as one
  rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("Profiles"));
  if (NS_FAILED(rv)) {
    return rv;
  }

  bool exists;
  rv = localDir->Exists(&exists);
  if (NS_SUCCEEDED(rv) && !exists) {
    rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0775);
  }
  if (NS_FAILED(rv)) {
    return rv;
  }
#endif

  localDir.forget(aLocalFile);

  return rv;