Bug 1697955 - Resolve the install path used for sync manager locks. r=application-update-reviewers,nalexander

Differential Revision: https://phabricator.services.mozilla.com/D110722
This commit is contained in:
Adam Gashlin 2021-04-05 22:32:39 +00:00
Родитель d1b5874cdb
Коммит d294246c6c
3 изменённых файлов: 56 добавлений и 8 удалений

Просмотреть файл

@ -29,4 +29,20 @@ add_task(async function test_backgroundtask_update_sync_manager() {
extraArgs: [file.path],
});
Assert.equal(81, exitCode, "No other instance is running");
let upperCaseFile = Cc["@mozilla.org/file/local;1"].createInstance(
Ci.nsIFile
);
upperCaseFile.initWithPath(
Services.dirsvc.get("XREExeF", Ci.nsIFile).path.toUpperCase()
);
if (upperCaseFile.exists()) {
// The uppercased path can still be used to access the exe, indicating a
// case-insensitive filesystem (as is usual on Windows and macOS), so path
// normalization can be tested.
exitCode = await do_backgroundtask("update_sync_manager", {
extraArgs: [upperCaseFile.path],
});
Assert.equal(80, exitCode, "Another instance is running");
}
});

Просмотреть файл

@ -958,6 +958,16 @@ function setupTestCommon(aAppUpdateAutoEnabled = false, aAllowBits = false) {
grePrefsFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
}
// The name of the update lock needs to be changed to match the path
// overridden in adjustGeneralPaths() above. Wait until now to reset
// because the GRE dir now exists, which may cause the "install
// path" to be normalized differently now that it can be resolved.
debugDump("resetting update lock");
let syncManager = Cc["@mozilla.org/updates/update-sync-manager;1"].getService(
Ci.nsIUpdateSyncManager
);
syncManager.resetLock();
// Remove the updates directory on Windows and Mac OS X which is located
// outside of the application directory after the call to adjustGeneralPaths
// has set it up. Since the test hasn't ran yet and the directory shouldn't
@ -4425,14 +4435,6 @@ function adjustGeneralPaths() {
debugDump("finish - unregistering directory provider");
});
// Now that we've overridden the directory provider, the name of the update
// lock needs to be changed to match the overridden path.
debugDump("resetting update lock");
let syncManager = Cc["@mozilla.org/updates/update-sync-manager;1"].getService(
Ci.nsIUpdateSyncManager
);
syncManager.resetLock();
}
/**

Просмотреть файл

@ -16,6 +16,10 @@
#include "nsString.h"
#include "nsXULAppAPI.h"
#ifdef XP_WIN
# include "WinUtils.h"
#endif
// The lock code generates a path that already includes the vendor name,
// so this only needs to name the specific lock.
#define UPDATE_LOCK_NAME_TOKEN "UpdateLock"
@ -95,6 +99,32 @@ nsresult nsUpdateSyncManager::OpenLock(nsIFile* anAppFile) {
NS_ENSURE_SUCCESS(rv, rv);
}
// It is possible that the path we have is on a case insensitive
// filesystem in which case the path may vary depending on how the
// application is called. We want to normalize the case somehow.
// On Linux XRE_EXECUTABLE_FILE already seems to be set to the correct path.
//
// See similar nsXREDirProvider::GetInstallHash. The main difference here is
// to allow lookup to fail on OSX, because some tests use a nonexistent
// appFile.
#ifdef XP_WIN
// Windows provides a way to get the correct case.
if (!mozilla::widget::WinUtils::ResolveJunctionPointsAndSymLinks(appFile)) {
NS_WARNING("Failed to resolve install directory.");
}
#elif defined(MOZ_WIDGET_COCOA)
// On OSX roundtripping through an FSRef fixes the case.
FSRef ref;
nsCOMPtr<nsILocalFileMac> macFile = do_QueryInterface(appFile);
if (macFile && NS_SUCCEEDED(macFile->GetFSRef(&ref)) &&
NS_SUCCEEDED(
NS_NewLocalFileWithFSRef(&ref, true, getter_AddRefs(macFile)))) {
appFile = static_cast<nsIFile*>(macFile);
} else {
NS_WARNING("Failed to resolve install directory.");
}
#endif
nsCOMPtr<nsIFile> appDirFile;
rv = appFile->GetParent(getter_AddRefs(appDirFile));
NS_ENSURE_SUCCESS(rv, rv);