Verified Commit 6d62d940 authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame 🎃
Browse files

Bug 13252: Customize profile management on macOS

On macOS we allow both portable mode and system installation.
However, in the latter case, we customize Firefox's directories to
match the hierarchy we use for the portable mode.

Also, display an informative error message if the TorBrowser-Data
directory cannot be created due to an "access denied" or a
"read only volume" error.
parent ed5a5ef6
Loading
Loading
Loading
Loading
+44 −5
Original line number Diff line number Diff line
@@ -235,7 +235,9 @@ nsresult nsXREDirProvider::GetUserProfilesRootDir(nsIFile** aResult) {
  nsresult rv = GetUserDataDirectory(getter_AddRefs(file), false);

  if (NS_SUCCEEDED(rv)) {
#if !defined(XP_UNIX) || defined(XP_MACOSX)
    // For some reason, we have decided not to append "Profiles" in Tor Browser.
    // So, let's keep removing it, or we should somehow migrate the profile.
#if !defined(TOR_BROWSER) && (!defined(XP_UNIX) || defined(XP_MACOSX))
    rv = file->AppendNative("Profiles"_ns);
#endif
    // We must create the profile directory here if it does not exist.
@@ -253,7 +255,7 @@ nsresult nsXREDirProvider::GetUserProfilesLocalDir(nsIFile** aResult) {
  nsresult rv = GetUserDataDirectory(getter_AddRefs(file), true);

  if (NS_SUCCEEDED(rv)) {
#if !defined(XP_UNIX) || defined(XP_MACOSX)
#if !defined(TOR_BROWSER) && (!defined(XP_UNIX) || defined(XP_MACOSX))
    rv = file->AppendNative("Profiles"_ns);
#endif
    // We must create the profile directory here if it does not exist.
@@ -1421,6 +1423,9 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,

#if defined(XP_MACOSX)
  FSRef fsRef;
#  if defined(TOR_BROWSER)
  OSType folderType = kApplicationSupportFolderType;
#  else
  OSType folderType;
  if (aLocal) {
    folderType = kCachedDataFolderType;
@@ -1431,6 +1436,7 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
    folderType = kApplicationSupportFolderType;
#    endif
  }
#  endif
  OSErr err = ::FSFindFolder(kUserDomain, folderType, kCreateFolder, &fsRef);
  NS_ENSURE_FALSE(err, NS_ERROR_FAILURE);

@@ -1443,6 +1449,17 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
  rv = dirFileMac->InitWithFSRef(&fsRef);
  NS_ENSURE_SUCCESS(rv, rv);

#  if defined(TOR_BROWSER)
  rv = dirFileMac->AppendNative("TorBrowser-Data"_ns);
  NS_ENSURE_SUCCESS(rv, rv);
  rv = dirFileMac->AppendNative("Browser"_ns);
  NS_ENSURE_SUCCESS(rv, rv);
  if (aLocal) {
    rv = dirFileMac->AppendNative("Caches"_ns);
    NS_ENSURE_SUCCESS(rv, rv);
  }
#  endif

  localDir = dirFileMac;
#elif defined(XP_IOS)
  nsAutoCString userDir;
@@ -1632,6 +1649,9 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) {
  nsresult rv = NS_OK;

#if defined(XP_MACOSX)
#  ifndef TOR_BROWSER
  // For Tor Browser we already prepare the data directory as we need it, even
  // when we are running a system install.
  if (!profile.IsEmpty()) {
    rv = AppendProfileString(aFile, profile.get());
  } else {
@@ -1641,6 +1661,7 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) {
    rv = aFile->AppendNative(appName);
  }
  NS_ENSURE_SUCCESS(rv, rv);
#  endif

#elif defined(XP_WIN)
  if (!profile.IsEmpty()) {
@@ -1725,3 +1746,21 @@ nsresult nsXREDirProvider::AppendProfileString(nsIFile* aFile,

  return NS_OK;
}

nsresult nsXREDirProvider::GetTorBrowserUserDataDir(nsIFile** aFile) {
#ifdef ANDROID
  // We expect this function not to be called on Android.
  // But, for sake of completeness, we handle also this case.
  const char* homeDir = getenv("HOME");
  if (!homeDir || !*homeDir) {
    return NS_ERROR_FAILURE;
  }
  return NS_NewNativeLocalFile(nsDependentCString(homeDir), true, aFile);
#endif

  NS_ENSURE_ARG_POINTER(aFile);
  nsCOMPtr<nsIFile> dataDir;
  nsresult rv = GetUserDataDirectoryHome(getter_AddRefs(dataDir), false);
  NS_ENSURE_SUCCESS(rv, rv);
  return dataDir->GetParent(aFile);
}
+7 −0
Original line number Diff line number Diff line
@@ -109,6 +109,13 @@ class nsXREDirProvider final : public nsIDirectoryServiceProvider2,
   */
  nsresult GetProfileDir(nsIFile** aResult);

  /**
   * Get the Tor Browser user data directory.
   * We take for granted that for Tor Browser we can take the parent directory
   * of the one returned by GetUserDataDirectoryHome (with aLocal = false).
   */
  nsresult GetTorBrowserUserDataDir(nsIFile** aFile);

 private:
  nsresult GetFilesInternal(const char* aProperty,
                            nsISimpleEnumerator** aResult);
+4 −0
Original line number Diff line number Diff line
@@ -330,8 +330,12 @@ CFTypeRefPtr<CFURLRef> GetTemporaryFolder() {
CFTypeRefPtr<CFURLRef> GetProductDirectory(bool aLocal) {
  nsAutoreleasePool localPool;

#if defined(TOR_BROWSER)
  NSSearchPathDirectory folderType = NSApplicationSupportDirectory;
#else
  NSSearchPathDirectory folderType =
      aLocal ? NSCachesDirectory : NSLibraryDirectory;
#endif
  NSFileManager* manager = [NSFileManager defaultManager];
  return CFTypeRefPtr<CFURLRef>::WrapUnderGetRule((__bridge CFURLRef)[[manager
      URLsForDirectory:folderType
+16 −0
Original line number Diff line number Diff line
@@ -309,6 +309,17 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
  if (NS_FAILED(rv)) {
    return rv;
  }

#  if defined(TOR_BROWSER)
  rv = localDir->AppendNative("TorBrowser-Data"_ns);
  NS_ENSURE_SUCCESS(rv, rv);
  rv = localDir->AppendNative("Browser"_ns);
  NS_ENSURE_SUCCESS(rv, rv);
  if (aLocal) {
    rv = localDir->AppendNative("Caches"_ns);
    NS_ENSURE_SUCCESS(rv, rv);
  }
#  endif
#elif defined(XP_WIN)
  nsCOMPtr<nsIProperties> directoryService =
      do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
@@ -331,10 +342,12 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
#  error dont_know_how_to_get_product_dir_on_your_platform
#endif

#if !defined(TOR_BROWSER)
  rv = localDir->AppendRelativeNativePath(DEFAULT_PRODUCT_DIR);
  if (NS_FAILED(rv)) {
    return rv;
  }
#endif
  rv = localDir->Exists(&exists);

  if (NS_SUCCEEDED(rv) && !exists) {
@@ -375,10 +388,13 @@ nsresult nsAppFileLocationProvider::GetDefaultUserProfileRoot(

#if defined(MOZ_WIDGET_COCOA) || defined(XP_WIN)
  // These 3 platforms share this part of the path - do them as one
#  ifndef TOR_BROWSER
  // Legacy: we do not use "Profiles" on Tor Browser.
  rv = localDir->AppendRelativeNativePath("Profiles"_ns);
  if (NS_FAILED(rv)) {
    return rv;
  }
#  endif

  bool exists;
  rv = localDir->Exists(&exists);