Pier Angelo Vendrame pushed to branch base-browser-102.7.0esr-12.5-1 at The Tor Project / Applications / Tor Browser
Commits:
- 
d41058d1
by Pier Angelo Vendrame at 2023-02-08T12:20:09+01:00
- 
9357ba91
by Pier Angelo Vendrame at 2023-02-08T12:20:18+01:00
3 changed files:
- toolkit/xre/nsXREDirProvider.cpp
- toolkit/xre/nsXREDirProvider.h
- xpcom/io/nsAppFileLocationProvider.cpp
Changes:
| ... | ... | @@ -111,6 +111,10 @@ nsIFile* gDataDirHome = nullptr; | 
| 111 | 111 |  nsCOMPtr<nsIFile> gDataDirProfileLocal = nullptr;
 | 
| 112 | 112 |  nsCOMPtr<nsIFile> gDataDirProfile = nullptr;
 | 
| 113 | 113 | |
| 114 | +#if defined(RELATIVE_DATA_DIR)
 | |
| 115 | +mozilla::Maybe<nsCOMPtr<nsIFile>> gDataDirPortable;
 | |
| 116 | +#endif
 | |
| 117 | + | |
| 114 | 118 |  // These are required to allow nsXREDirProvider to be usable in xpcshell tests.
 | 
| 115 | 119 |  // where gAppData is null.
 | 
| 116 | 120 |  #if defined(XP_MACOSX) || defined(XP_UNIX)
 | 
| ... | ... | @@ -1324,6 +1328,91 @@ nsresult nsXREDirProvider::SetUserDataProfileDirectory(nsCOMPtr<nsIFile>& aFile, | 
| 1324 | 1328 |    return NS_OK;
 | 
| 1325 | 1329 |  }
 | 
| 1326 | 1330 | |
| 1331 | +#if defined(RELATIVE_DATA_DIR)
 | |
| 1332 | +nsresult nsXREDirProvider::GetPortableDataDir(nsIFile** aFile,
 | |
| 1333 | +                                              bool& aIsPortable) {
 | |
| 1334 | +  if (gDataDirPortable) {
 | |
| 1335 | +    if (*gDataDirPortable) {
 | |
| 1336 | +      nsresult rv = (*gDataDirPortable)->Clone(aFile);
 | |
| 1337 | +      NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1338 | +      aIsPortable = true;
 | |
| 1339 | +    } else {
 | |
| 1340 | +      aIsPortable = false;
 | |
| 1341 | +    }
 | |
| 1342 | +    return NS_OK;
 | |
| 1343 | +  }
 | |
| 1344 | + | |
| 1345 | +  nsCOMPtr<nsIFile> exeFile, exeDir;
 | |
| 1346 | +  bool persistent = false;
 | |
| 1347 | +  nsresult rv =
 | |
| 1348 | +      GetFile(XRE_EXECUTABLE_FILE, &persistent, getter_AddRefs(exeFile));
 | |
| 1349 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1350 | +  rv = exeFile->Normalize();
 | |
| 1351 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1352 | +  rv = exeFile->GetParent(getter_AddRefs(exeDir));
 | |
| 1353 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1354 | + | |
| 1355 | +#if defined(XP_MACOSX)
 | |
| 1356 | +  nsAutoString exeDirPath;
 | |
| 1357 | +  rv = exeDir->GetPath(exeDirPath);
 | |
| 1358 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1359 | +  // When the browser is installed in /Applications, we never run in portable
 | |
| 1360 | +  // mode.
 | |
| 1361 | +  if (exeDirPath.Find("/Applications/", true /* ignore case */) == 0) {
 | |
| 1362 | +    aIsPortable = false;
 | |
| 1363 | +    return NS_OK;
 | |
| 1364 | +  }
 | |
| 1365 | +#endif
 | |
| 1366 | + | |
| 1367 | +  nsCOMPtr<nsIFile> systemInstallFile;
 | |
| 1368 | +  rv = exeDir->Clone(getter_AddRefs(systemInstallFile));
 | |
| 1369 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1370 | +  rv = systemInstallFile->AppendNative("system-install"_ns);
 | |
| 1371 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1372 | + | |
| 1373 | +  bool exists = false;
 | |
| 1374 | +  rv = systemInstallFile->Exists(&exists);
 | |
| 1375 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1376 | +  if (exists) {
 | |
| 1377 | +    aIsPortable = false;
 | |
| 1378 | +    gDataDirPortable.emplace(nullptr);
 | |
| 1379 | +    return NS_OK;
 | |
| 1380 | +  }
 | |
| 1381 | + | |
| 1382 | +  nsCOMPtr<nsIFile> localDir = exeDir;
 | |
| 1383 | +#if defined(XP_MACOSX)
 | |
| 1384 | +  rv = exeDir->GetParent(getter_AddRefs(localDir));
 | |
| 1385 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1386 | +  exeDir = localDir;
 | |
| 1387 | +  rv = exeDir->GetParent(getter_AddRefs(localDir));
 | |
| 1388 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1389 | +#endif
 | |
| 1390 | +  rv = localDir->SetRelativePath(localDir.get(),
 | |
| 1391 | +                                 nsLiteralCString(RELATIVE_DATA_DIR));
 | |
| 1392 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1393 | + | |
| 1394 | +#if defined(XP_MACOSX)
 | |
| 1395 | +  // On macOS we try to create the directory immediately to switch to
 | |
| 1396 | +  // system-install mode if needed (e.g., when running from the DMG).
 | |
| 1397 | +  rv = localDir->Exists(&exists);
 | |
| 1398 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1399 | +  if (!exists) {
 | |
| 1400 | +    rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
 | |
| 1401 | +    if (NS_FAILED(rv)) {
 | |
| 1402 | +      aIsPortable = false;
 | |
| 1403 | +      return NS_OK;
 | |
| 1404 | +    }
 | |
| 1405 | +  }
 | |
| 1406 | +#endif
 | |
| 1407 | + | |
| 1408 | +  gDataDirPortable.emplace(localDir);
 | |
| 1409 | +  rv = (*gDataDirPortable)->Clone(aFile);
 | |
| 1410 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1411 | +  aIsPortable = true;
 | |
| 1412 | +  return rv;
 | |
| 1413 | +}
 | |
| 1414 | +#endif
 | |
| 1415 | + | |
| 1327 | 1416 |  nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile,
 | 
| 1328 | 1417 |                                                      bool aLocal) {
 | 
| 1329 | 1418 |    // Copied from nsAppFileLocationProvider (more or less)
 | 
| ... | ... | @@ -1343,16 +1432,20 @@ nsresult nsXREDirProvider::GetUserDataDirectoryHome(nsIFile** aFile, | 
| 1343 | 1432 |    if (!singleton) {
 | 
| 1344 | 1433 |      return NS_ERROR_OUT_OF_MEMORY;
 | 
| 1345 | 1434 |    }
 | 
| 1346 | -  rv = singleton->GetAppRootDir(getter_AddRefs(localDir));
 | |
| 1347 | -  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1348 | -  nsAutoCString profileDir(RELATIVE_DATA_DIR);
 | |
| 1349 | -  rv = localDir->SetRelativePath(localDir.get(), profileDir);
 | |
| 1435 | +  bool isPortable = false;
 | |
| 1436 | +  rv = singleton->GetPortableDataDir(getter_AddRefs(localDir), isPortable);
 | |
| 1350 | 1437 |    NS_ENSURE_SUCCESS(rv, rv);
 | 
| 1351 | -  if (aLocal) {
 | |
| 1352 | -    rv = localDir->AppendNative("Caches"_ns);
 | |
| 1353 | -    NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1438 | +  if (isPortable) {
 | |
| 1439 | +    if (aLocal) {
 | |
| 1440 | +      rv = localDir->AppendNative("Caches"_ns);
 | |
| 1441 | +      NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1442 | +    }
 | |
| 1443 | +    NS_IF_ADDREF(*aFile = localDir);
 | |
| 1444 | +    return rv;
 | |
| 1354 | 1445 |    }
 | 
| 1355 | -#elif defined(XP_MACOSX)
 | |
| 1446 | +#endif
 | |
| 1447 | + | |
| 1448 | +#if defined(XP_MACOSX)
 | |
| 1356 | 1449 |    FSRef fsRef;
 | 
| 1357 | 1450 |    OSType folderType;
 | 
| 1358 | 1451 |    if (aLocal) {
 | 
| ... | ... | @@ -1495,25 +1588,6 @@ nsresult nsXREDirProvider::GetUserDataDirectory(nsIFile** aFile, bool aLocal) { | 
| 1495 | 1588 |    return NS_OK;
 | 
| 1496 | 1589 |  }
 | 
| 1497 | 1590 | |
| 1498 | -nsresult nsXREDirProvider::GetAppRootDir(nsIFile** aFile) {
 | |
| 1499 | -  bool persistent = false;
 | |
| 1500 | -  nsCOMPtr<nsIFile> file, appRootDir;
 | |
| 1501 | -  nsresult rv = GetFile(XRE_EXECUTABLE_FILE, &persistent, getter_AddRefs(file));
 | |
| 1502 | -  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1503 | -  rv = file->Normalize();
 | |
| 1504 | -  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1505 | -  int levelsToRemove = 1;
 | |
| 1506 | -#if defined(XP_MACOSX)
 | |
| 1507 | -  levelsToRemove += 2;
 | |
| 1508 | -#endif
 | |
| 1509 | -  while (levelsToRemove-- > 0) {
 | |
| 1510 | -    rv = file->GetParent(getter_AddRefs(appRootDir));
 | |
| 1511 | -    NS_ENSURE_SUCCESS(rv, rv);
 | |
| 1512 | -    file = appRootDir;
 | |
| 1513 | -  }
 | |
| 1514 | -  return appRootDir->Clone(aFile);
 | |
| 1515 | -}
 | |
| 1516 | - | |
| 1517 | 1591 |  nsresult nsXREDirProvider::EnsureDirectoryExists(nsIFile* aDirectory) {
 | 
| 1518 | 1592 |    nsresult rv = aDirectory->Create(nsIFile::DIRECTORY_TYPE, 0700);
 | 
| 1519 | 1593 | |
| ... | ... | @@ -1564,6 +1638,13 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) { | 
| 1564 | 1638 |      return NS_OK;
 | 
| 1565 | 1639 |    }
 | 
| 1566 | 1640 | |
| 1641 | +#if defined(RELATIVE_DATA_DIR)
 | |
| 1642 | +  if (gDataDirPortable && *gDataDirPortable) {
 | |
| 1643 | +    // Do nothing in portable mode
 | |
| 1644 | +    return NS_OK;
 | |
| 1645 | +  }
 | |
| 1646 | +#endif
 | |
| 1647 | + | |
| 1567 | 1648 |    nsAutoCString profile;
 | 
| 1568 | 1649 |    nsAutoCString appName;
 | 
| 1569 | 1650 |    nsAutoCString vendor;
 | 
| ... | ... | @@ -1579,27 +1660,23 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) { | 
| 1579 | 1660 |  #if defined(XP_MACOSX)
 | 
| 1580 | 1661 |    if (!profile.IsEmpty()) {
 | 
| 1581 | 1662 |      rv = AppendProfileString(aFile, profile.get());
 | 
| 1582 | -#  ifndef RELATIVE_DATA_DIR
 | |
| 1583 | 1663 |    } else {
 | 
| 1584 | 1664 |      // Note that MacOS ignores the vendor when creating the profile hierarchy -
 | 
| 1585 | 1665 |      // all application preferences directories live alongside one another in
 | 
| 1586 | 1666 |      // ~/Library/Application Support/
 | 
| 1587 | 1667 |      rv = aFile->AppendNative(appName);
 | 
| 1588 | -#  endif
 | |
| 1589 | 1668 |    }
 | 
| 1590 | 1669 |    NS_ENSURE_SUCCESS(rv, rv);
 | 
| 1591 | 1670 | |
| 1592 | 1671 |  #elif defined(XP_WIN)
 | 
| 1593 | 1672 |    if (!profile.IsEmpty()) {
 | 
| 1594 | 1673 |      rv = AppendProfileString(aFile, profile.get());
 | 
| 1595 | -#  ifndef RELATIVE_DATA_DIR
 | |
| 1596 | 1674 |    } else {
 | 
| 1597 | 1675 |      if (!vendor.IsEmpty()) {
 | 
| 1598 | 1676 |        rv = aFile->AppendNative(vendor);
 | 
| 1599 | 1677 |        NS_ENSURE_SUCCESS(rv, rv);
 | 
| 1600 | 1678 |      }
 | 
| 1601 | 1679 |      rv = aFile->AppendNative(appName);
 | 
| 1602 | -#  endif
 | |
| 1603 | 1680 |    }
 | 
| 1604 | 1681 |    NS_ENSURE_SUCCESS(rv, rv);
 | 
| 1605 | 1682 | |
| ... | ... | @@ -1614,26 +1691,21 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) { | 
| 1614 | 1691 |    nsAutoCString folder;
 | 
| 1615 | 1692 |    // Make it hidden (by starting with "."), except when local (the
 | 
| 1616 | 1693 |    // profile is already under ~/.cache or XDG_CACHE_HOME).
 | 
| 1617 | -#  ifndef RELATIVE_DATA_DIR
 | |
| 1618 | 1694 |    if (!aLocal) folder.Assign('.');
 | 
| 1619 | -#  endif
 | |
| 1620 | 1695 | |
| 1621 | 1696 |    if (!profile.IsEmpty()) {
 | 
| 1622 | 1697 |      // Skip any leading path characters
 | 
| 1623 | 1698 |      const char* profileStart = profile.get();
 | 
| 1624 | 1699 |      while (*profileStart == '/' || *profileStart == '\\') profileStart++;
 | 
| 1625 | 1700 | |
| 1626 | -#  ifndef RELATIVE_DATA_DIR
 | |
| 1627 | 1701 |      // On the off chance that someone wanted their folder to be hidden don't
 | 
| 1628 | 1702 |      // let it become ".."
 | 
| 1629 | 1703 |      if (*profileStart == '.' && !aLocal) profileStart++;
 | 
| 1630 | -#  endif
 | |
| 1631 | 1704 | |
| 1632 | 1705 |      folder.Append(profileStart);
 | 
| 1633 | 1706 |      ToLowerCase(folder);
 | 
| 1634 | 1707 | |
| 1635 | 1708 |      rv = AppendProfileString(aFile, folder.BeginReading());
 | 
| 1636 | -#  ifndef RELATIVE_DATA_DIR
 | |
| 1637 | 1709 |    } else {
 | 
| 1638 | 1710 |      if (!vendor.IsEmpty()) {
 | 
| 1639 | 1711 |        folder.Append(vendor);
 | 
| ... | ... | @@ -1652,7 +1724,6 @@ nsresult nsXREDirProvider::AppendProfilePath(nsIFile* aFile, bool aLocal) { | 
| 1652 | 1724 | |
| 1653 | 1725 |        rv = aFile->AppendNative(folder);
 | 
| 1654 | 1726 |      }
 | 
| 1655 | -#  endif
 | |
| 1656 | 1727 |    }
 | 
| 1657 | 1728 |    NS_ENSURE_SUCCESS(rv, rv);
 | 
| 1658 | 1729 | 
| ... | ... | @@ -109,14 +109,6 @@ class nsXREDirProvider final : public nsIDirectoryServiceProvider2, | 
| 109 | 109 |     */
 | 
| 110 | 110 |    nsresult GetProfileDir(nsIFile** aResult);
 | 
| 111 | 111 | |
| 112 | -  /**
 | |
| 113 | -   * Get the path to the base application directory.
 | |
| 114 | -   *
 | |
| 115 | -   * In almost all platforms it is the directory that contains the Firefox
 | |
| 116 | -   * executable; on macOS we remove also Contents/MacOS from it.
 | |
| 117 | -   */
 | |
| 118 | -  nsresult GetAppRootDir(nsIFile** aFile);
 | |
| 119 | - | |
| 120 | 112 |   protected:
 | 
| 121 | 113 |    nsresult GetFilesInternal(const char* aProperty,
 | 
| 122 | 114 |                              nsISimpleEnumerator** aResult);
 | 
| ... | ... | @@ -163,6 +155,14 @@ class nsXREDirProvider final : public nsIDirectoryServiceProvider2, | 
| 163 | 155 |   private:
 | 
| 164 | 156 |    static nsresult SetUserDataProfileDirectory(nsCOMPtr<nsIFile>& aFile,
 | 
| 165 | 157 |                                                bool aLocal);
 | 
| 158 | + | |
| 159 | +#if defined(RELATIVE_DATA_DIR)
 | |
| 160 | +  /**
 | |
| 161 | +   * Get the path to the portable data dir, if the application is running in
 | |
| 162 | +   * portable mode.
 | |
| 163 | +   */
 | |
| 164 | +  nsresult GetPortableDataDir(nsIFile** aFile, bool& aIsPortable);
 | |
| 165 | +#endif
 | |
| 166 | 166 |  };
 | 
| 167 | 167 | |
| 168 | 168 |  #endif | 
| ... | ... | @@ -229,57 +229,130 @@ nsresult nsAppFileLocationProvider::CloneMozBinDirectory(nsIFile** aLocalFile) { | 
| 229 | 229 |    return NS_OK;
 | 
| 230 | 230 |  }
 | 
| 231 | 231 | |
| 232 | -//----------------------------------------------------------------------------------------
 | |
| 233 | -// GetProductDirectory - Gets the directory which contains the application data
 | |
| 234 | -// folder
 | |
| 235 | -//
 | |
| 236 | -// UNIX   : ~/.mozilla/
 | |
| 237 | -// WIN    : <Application Data folder on user's machine>\Mozilla
 | |
| 238 | -// Mac    : :Documents:Mozilla:
 | |
| 239 | -//----------------------------------------------------------------------------------------
 | |
| 240 | -nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
 | |
| 241 | -                                                        bool aLocal) {
 | |
| 242 | -  if (NS_WARN_IF(!aLocalFile)) {
 | |
| 243 | -    return NS_ERROR_INVALID_ARG;
 | |
| 244 | -  }
 | |
| 232 | +#ifdef RELATIVE_DATA_DIR
 | |
| 233 | +static nsresult SetupPortableMode(nsIFile** aDirectory, bool aLocal,
 | |
| 234 | +                                  bool& aIsPortable) {
 | |
| 235 | +  // This is almost the same as nsXREDirProvider::GetPortableDataDir.
 | |
| 236 | +  // However, it seems that this is never called, at least during simple usage
 | |
| 237 | +  // of the browser.
 | |
| 245 | 238 | |
| 246 | 239 |    nsresult rv = NS_ERROR_UNEXPECTED;
 | 
| 247 | -  bool exists;
 | |
| 248 | -  nsCOMPtr<nsIFile> localDir;
 | |
| 249 | - | |
| 250 | -#if defined(RELATIVE_DATA_DIR)
 | |
| 251 | 240 |    nsCOMPtr<nsIProperties> directoryService(
 | 
| 252 | 241 |        do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
 | 
| 253 | 242 |    NS_ENSURE_SUCCESS(rv, rv);
 | 
| 254 | - | |
| 255 | -  bool persistent = false;
 | |
| 256 | -  nsCOMPtr<nsIFile> file, appRootDir;
 | |
| 243 | +  nsCOMPtr<nsIFile> exeFile, exeDir;
 | |
| 257 | 244 |    rv = directoryService->Get(XRE_EXECUTABLE_FILE, NS_GET_IID(nsIFile),
 | 
| 258 | -                             getter_AddRefs(file));
 | |
| 245 | +                             getter_AddRefs(exeFile));
 | |
| 246 | +  rv = exeFile->Normalize();
 | |
| 259 | 247 |    NS_ENSURE_SUCCESS(rv, rv);
 | 
| 260 | -  rv = file->Normalize();
 | |
| 248 | +  rv = exeFile->GetParent(getter_AddRefs(exeDir));
 | |
| 261 | 249 |    NS_ENSURE_SUCCESS(rv, rv);
 | 
| 262 | -  int levelsToRemove = 1;
 | |
| 250 | + | |
| 263 | 251 |  #  if defined(XP_MACOSX)
 | 
| 264 | -  levelsToRemove += 2;
 | |
| 252 | +  nsAutoString exeDirPath;
 | |
| 253 | +  rv = exeDir->GetPath(exeDirPath);
 | |
| 254 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 255 | +  // When the browser is installed in /Applications, we never run in portable
 | |
| 256 | +  // mode.
 | |
| 257 | +  if (exeDirPath.Find("/Applications/", true /* ignore case */) == 0) {
 | |
| 258 | +    aIsPortable = false;
 | |
| 259 | +    return NS_OK;
 | |
| 260 | +  }
 | |
| 265 | 261 |  #  endif
 | 
| 266 | -  while (levelsToRemove-- > 0) {
 | |
| 267 | -    rv = file->GetParent(getter_AddRefs(appRootDir));
 | |
| 268 | -    NS_ENSURE_SUCCESS(rv, rv);
 | |
| 269 | -    file = appRootDir;
 | |
| 262 | + | |
| 263 | +  nsCOMPtr<nsIFile> systemInstallFile;
 | |
| 264 | +  rv = exeDir->Clone(getter_AddRefs(systemInstallFile));
 | |
| 265 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 266 | +  rv = systemInstallFile->AppendNative("system-install"_ns);
 | |
| 267 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 268 | + | |
| 269 | +  bool exists = false;
 | |
| 270 | +  rv = systemInstallFile->Exists(&exists);
 | |
| 271 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 272 | +  if (exists) {
 | |
| 273 | +    aIsPortable = false;
 | |
| 274 | +    return NS_OK;
 | |
| 270 | 275 |    }
 | 
| 271 | 276 | |
| 272 | -  localDir = appRootDir;
 | |
| 273 | -  nsAutoCString profileDir(RELATIVE_DATA_DIR);
 | |
| 274 | -  rv = localDir->SetRelativePath(localDir.get(), profileDir);
 | |
| 277 | +  nsCOMPtr<nsIFile> localDir = exeDir;
 | |
| 278 | +#  if defined(XP_MACOSX)
 | |
| 279 | +  rv = exeDir->GetParent(getter_AddRefs(localDir));
 | |
| 275 | 280 |    NS_ENSURE_SUCCESS(rv, rv);
 | 
| 281 | +  exeDir = localDir;
 | |
| 282 | +  rv = exeDir->GetParent(getter_AddRefs(localDir));
 | |
| 283 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 284 | +#  endif
 | |
| 276 | 285 | |
| 286 | +  rv = localDir->SetRelativePath(localDir.get(),
 | |
| 287 | +                                 nsLiteralCString(RELATIVE_DATA_DIR));
 | |
| 288 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 277 | 289 |    if (aLocal) {
 | 
| 278 | 290 |      rv = localDir->AppendNative("Caches"_ns);
 | 
| 279 | 291 |      NS_ENSURE_SUCCESS(rv, rv);
 | 
| 280 | 292 |    }
 | 
| 281 | 293 | |
| 282 | -#elif defined(MOZ_WIDGET_COCOA)
 | |
| 294 | +  rv = localDir->Exists(&exists);
 | |
| 295 | +  NS_ENSURE_SUCCESS(rv, rv);
 | |
| 296 | +  if (!exists) {
 | |
| 297 | +    rv = localDir->Create(nsIFile::DIRECTORY_TYPE, 0700);
 | |
| 298 | +#  if defined(XP_MACOSX)
 | |
| 299 | +    if (NS_FAILED(rv)) {
 | |
| 300 | +      // On macOS, we forgive this failure to allow running from the DMG.
 | |
| 301 | +      aIsPortable = false;
 | |
| 302 | +      return NS_OK;
 | |
| 303 | +    }
 | |
| 304 | +#  else
 | |
| 305 | +    NS_ENSURE_SUCCESS(rv, rv);
 | |
| 306 | +#  endif
 | |
| 307 | +  }
 | |
| 308 | + | |
| 309 | +  localDir.forget(aDirectory);
 | |
| 310 | +  aIsPortable = true;
 | |
| 311 | +  return rv;
 | |
| 312 | +}
 | |
| 313 | +#endif
 | |
| 314 | + | |
| 315 | +//----------------------------------------------------------------------------------------
 | |
| 316 | +// GetProductDirectory - Gets the directory which contains the application data
 | |
| 317 | +// folder
 | |
| 318 | +//
 | |
| 319 | +// If portable mode is enabled:
 | |
| 320 | +//  - aLocal == false: $APP_ROOT/$RELATIVE_DATA_DIR
 | |
| 321 | +//  - aLocal == true:  $APP_ROOT/$RELATIVE_DATA_DIR/Caches
 | |
| 322 | +// where $APP_ROOT is:
 | |
| 323 | +//  - the parent directory of the executable on Windows and Linux
 | |
| 324 | +//  - the root of the app bundle on macOS
 | |
| 325 | +//
 | |
| 326 | +// Otherwise:
 | |
| 327 | +//  - Windows:
 | |
| 328 | +//    - aLocal == false: %APPDATA%/$MOZ_USER_DIR
 | |
| 329 | +//    - aLocal == true: %LOCALAPPDATA%/$MOZ_USER_DIR
 | |
| 330 | +//  - macOS:
 | |
| 331 | +//    - aLocal == false: kDomainLibraryFolderType/$MOZ_USER_DIR
 | |
| 332 | +//    - aLocal == true: kCachedDataFolderType/$MOZ_USER_DIR
 | |
| 333 | +//  - Unix: ~/$MOZ_USER_DIR
 | |
| 334 | +//----------------------------------------------------------------------------------------
 | |
| 335 | +nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile,
 | |
| 336 | +                                                        bool aLocal) {
 | |
| 337 | +  if (NS_WARN_IF(!aLocalFile)) {
 | |
| 338 | +    return NS_ERROR_INVALID_ARG;
 | |
| 339 | +  }
 | |
| 340 | + | |
| 341 | +  nsresult rv = NS_ERROR_UNEXPECTED;
 | |
| 342 | +  bool exists;
 | |
| 343 | +  nsCOMPtr<nsIFile> localDir;
 | |
| 344 | + | |
| 345 | +#if defined(RELATIVE_DATA_DIR)
 | |
| 346 | +  bool isPortable = false;
 | |
| 347 | +  rv = SetupPortableMode(aLocalFile, aLocal, isPortable);
 | |
| 348 | +  // If portable mode is enabled, we absolutely want it (e.g., to be sure there
 | |
| 349 | +  // will not be disk leaks), so a failure is to be propagated.
 | |
| 350 | +  if (NS_FAILED(rv) || isPortable) {
 | |
| 351 | +    return rv;
 | |
| 352 | +  }
 | |
| 353 | +#endif
 | |
| 354 | + | |
| 355 | +#if defined(MOZ_WIDGET_COCOA)
 | |
| 283 | 356 |    FSRef fsRef;
 | 
| 284 | 357 |    OSType folderType =
 | 
| 285 | 358 |        aLocal ? (OSType)kCachedDataFolderType : (OSType)kDomainLibraryFolderType;
 | 
| ... | ... | @@ -318,12 +391,10 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile, | 
| 318 | 391 |  #  error dont_know_how_to_get_product_dir_on_your_platform
 | 
| 319 | 392 |  #endif
 | 
| 320 | 393 | |
| 321 | -#if !defined(RELATIVE_DATA_DIR)
 | |
| 322 | 394 |    rv = localDir->AppendRelativeNativePath(DEFAULT_PRODUCT_DIR);
 | 
| 323 | 395 |    if (NS_FAILED(rv)) {
 | 
| 324 | 396 |      return rv;
 | 
| 325 | 397 |    }
 | 
| 326 | -#endif
 | |
| 327 | 398 |    rv = localDir->Exists(&exists);
 | 
| 328 | 399 | |
| 329 | 400 |    if (NS_SUCCEEDED(rv) && !exists) {
 | 
| ... | ... | @@ -342,6 +413,11 @@ nsresult nsAppFileLocationProvider::GetProductDirectory(nsIFile** aLocalFile, | 
| 342 | 413 |  //----------------------------------------------------------------------------------------
 | 
| 343 | 414 |  // GetDefaultUserProfileRoot - Gets the directory which contains each user
 | 
| 344 | 415 |  // profile dir
 | 
| 416 | +//
 | |
| 417 | +// - Windows and macOS: $PRODUCT_DIRECTORY/Profiles
 | |
| 418 | +// - Unix: $PRODUCT_DIRECTORY
 | |
| 419 | +// See also GetProductDirectory for instructions on how $PRODUCT_DIRECTORY is
 | |
| 420 | +// generated.
 | |
| 345 | 421 |  //----------------------------------------------------------------------------------------
 | 
| 346 | 422 |  nsresult nsAppFileLocationProvider::GetDefaultUserProfileRoot(
 | 
| 347 | 423 |      nsIFile** aLocalFile, bool aLocal) {
 |