Bug 1891616: shared libraries for getting an installation's directory layout r=bytesized
This change creates the installation directory layout DLLs to be used in the versioned install directory project outlined in https://bugzilla.mozilla.org/show_bug.cgi?id=1891600 These DLLs are both named InstallationDirLayout.dll, and their only functionality is to return whether the current client installation uses a single install directory (the current way), or versioned install directories. Eventually, the updater or installer will choose the appropriate version of this directory to be installed on the client machine. Until we have that functionality, the "single layout" version of the library will be installed in the bin directory of the installation, and the "versioned layout" version will be installed in a subdirectory. More details are in the index.rst document included in this change. Differential Revision: https://phabricator.services.mozilla.com/D236065
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
;+# 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/.
|
||||
|
||||
LIBRARY InstallationDirLayout
|
||||
EXPORTS
|
||||
GetInstallationDirLayoutType
|
||||
11
browser/app/installation_dir_layout/InstallationDirLayout.h
Normal file
11
browser/app/installation_dir_layout/InstallationDirLayout.h
Normal file
@@ -0,0 +1,11 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
#ifndef INSTALL_DIR_LAYOUT_H
|
||||
#define INSTALL_DIR_LAYOUT_H
|
||||
|
||||
enum class InstallationDirLayoutType { Single, Versioned };
|
||||
|
||||
InstallationDirLayoutType GetInstallationDirLayoutType();
|
||||
|
||||
#endif // INSTALL_DIR_LAYOUT_H
|
||||
65
browser/app/installation_dir_layout/docs/index.rst
Normal file
65
browser/app/installation_dir_layout/docs/index.rst
Normal file
@@ -0,0 +1,65 @@
|
||||
=============================
|
||||
Installation Directory Layout
|
||||
=============================
|
||||
|
||||
Rationale
|
||||
===================
|
||||
|
||||
Firefox supports automatic downloading and applying of updates while the user is still using
|
||||
the browser. However, once the update has been installed, files that the browser relies on
|
||||
may have changed on disk, which caused the original implementation of update functionality to
|
||||
force the user to restart the browser after updates. (See
|
||||
_this bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1891600 for details and discussion.)
|
||||
|
||||
|
||||
In order to let users continue to use the browser after updates are applied, the updater needs
|
||||
to leave in place the files associated with the running browser, for as long as the browser's process
|
||||
exists.
|
||||
|
||||
The approach we are taking to enable this behavior is a new installation layout called "versioned install directories".
|
||||
What this involves is:
|
||||
|
||||
- Under the "base" install directory, there will be one or more "versioned" install directories,
|
||||
with names based on the version of Firefox installed in them.
|
||||
- Each versioned directory contains a complete installation of Firefox at the approapriate version.
|
||||
- In the base install directory, there will be a launcher exectuable that launches the Firefox
|
||||
executable in the appropriate versioned directory for the current Firefox version,
|
||||
|
||||
Example of "single" layout
|
||||
|
||||
This process allows all of the file resolution in Firefox to remain unchanged (for example,
|
||||
C:\\Program Files\\Mozilla Firefox\\136.0.1a\\firefox.exe will load libraries from the directory
|
||||
C:\\Program Files\\Mozilla Firefox\\136.0.1a\\). Most code will have no need to be aware of the change.
|
||||
|
||||
However, when applying updates to an installation,
|
||||
the updater needs to know if it should:
|
||||
- apply updates to a "single" install directory, and leave a single install directory in place (current behavior)
|
||||
- apply updates to a single install directory, and migrate it to be a versioned install
|
||||
- apply updates to a versioned install directory, using the new versioned install behavior
|
||||
|
||||
This means that the updater needs a way to know unambiguously whether an installation
|
||||
is using a single or versioned layout. This is the functionality provided by this module.
|
||||
|
||||
Module contents
|
||||
===============
|
||||
|
||||
The installation_dir_layout module provides two different implementations of a library `installation_dir_layout.dll`
|
||||
|
||||
This library has a single function, `GetInstallationDirLayoutType`, which returns an enumerated type.
|
||||
|
||||
The implementation of `installation_dir_layout.dll` in the `single` directory returns `InstallationDirLayoutType::Single`
|
||||
The implementation of `installation_dir_layout.dll` in the `versioned` directory returns `InstallationDirLayoutType::Versioned`
|
||||
|
||||
The interface for both implementations is specified in InstallationDirLayout.h
|
||||
|
||||
DLL installation
|
||||
================
|
||||
|
||||
When Firefox is installed or updated, the installer or updater will choose the appropriate version of `installation_dir_layout.dll`
|
||||
to install. This version will be available to firefox.exe and its supporting utilities as a runtime library.
|
||||
|
||||
DLL usage
|
||||
=========
|
||||
|
||||
Code that needs to know about the installation directory layout (such as updater and uninstaller) will load the installed
|
||||
version of the DLL and call `GetInstallationDirLayoutType`.
|
||||
11
browser/app/installation_dir_layout/moz.build
Normal file
11
browser/app/installation_dir_layout/moz.build
Normal file
@@ -0,0 +1,11 @@
|
||||
# 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/.
|
||||
|
||||
DIRS += ["single", "versioned"]
|
||||
|
||||
TEST_DIRS += [
|
||||
"tests/gtest",
|
||||
]
|
||||
|
||||
SPHINX_TREES["/installation_dir_layout"] = "docs"
|
||||
@@ -0,0 +1,9 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "InstallationDirLayout.h"
|
||||
|
||||
InstallationDirLayoutType GetInstallationDirLayoutType() {
|
||||
return InstallationDirLayoutType::Single;
|
||||
}
|
||||
16
browser/app/installation_dir_layout/single/moz.build
Normal file
16
browser/app/installation_dir_layout/single/moz.build
Normal file
@@ -0,0 +1,16 @@
|
||||
# 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/.
|
||||
|
||||
LOCAL_INCLUDES = [".."]
|
||||
SOURCES = [
|
||||
"InstallationDirLayout.cpp",
|
||||
]
|
||||
DEFFILE = "../InstallationDirLayout.def"
|
||||
|
||||
# Note: This library is currently the default layout
|
||||
# When we eventually switch to the default layout being versioned, the
|
||||
# line below should be uncommented
|
||||
# DIST_SUBDIR = "installation_dir_layout/single"
|
||||
|
||||
SharedLibrary("InstallationDirLayout")
|
||||
@@ -0,0 +1,79 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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 "gtest/gtest.h"
|
||||
#include <windows.h>
|
||||
#include "InstallationDirLayout.h"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
class InstallationDirLayoutTest : public ::testing::Test {
|
||||
protected:
|
||||
std::wstring dist_bin_dir;
|
||||
|
||||
void SetUp() override {
|
||||
wchar_t pathbuf[MAX_PATH];
|
||||
DWORD dwRet = GetCurrentDirectoryW(sizeof(pathbuf), pathbuf);
|
||||
if (dwRet == 0) {
|
||||
FAIL() << "Failed getting cwd";
|
||||
}
|
||||
if (dwRet > sizeof(pathbuf)) {
|
||||
FAIL() << "Path was too long for buffer";
|
||||
}
|
||||
// We have the current directory in pathbuf. Now construct the path to
|
||||
// dist/bin.
|
||||
wchar_t* cut_location = wcsstr(pathbuf, L"\\_tests\\gtest");
|
||||
if (!cut_location) {
|
||||
FAIL() << "\\_tests\\gtest directory not found in path";
|
||||
}
|
||||
// Null-terminate the string at the cut location.
|
||||
*cut_location = 0;
|
||||
// And then stuff it into a wstring, so we can let the standard library
|
||||
// worry about buffer limits
|
||||
dist_bin_dir.append(pathbuf);
|
||||
dist_bin_dir.append(L"\\dist\\bin");
|
||||
}
|
||||
|
||||
void TearDown() override {}
|
||||
};
|
||||
|
||||
using FuncType = InstallationDirLayoutType (*)();
|
||||
|
||||
TEST_F(InstallationDirLayoutTest, SingleLayoutTest) {
|
||||
std::wstring runtimelib_path;
|
||||
runtimelib_path.append(dist_bin_dir);
|
||||
// Since this is the default, we don't need to access its by path.
|
||||
runtimelib_path.append(L"\\InstallationDirLayout.dll");
|
||||
std::wcout << L"Here is dll str: " << runtimelib_path << std::endl;
|
||||
HINSTANCE hRuntimeLibrary =
|
||||
LoadLibraryEx(runtimelib_path.c_str(), nullptr, 0);
|
||||
ASSERT_NE(hRuntimeLibrary, nullptr);
|
||||
FuncType dirLayoutFunc =
|
||||
(FuncType)GetProcAddress(hRuntimeLibrary, "GetInstallationDirLayoutType");
|
||||
ASSERT_NE(dirLayoutFunc, nullptr);
|
||||
|
||||
InstallationDirLayoutType layoutType = dirLayoutFunc();
|
||||
ASSERT_EQ(layoutType, InstallationDirLayoutType::Single);
|
||||
bool freeResult = FreeLibrary(hRuntimeLibrary);
|
||||
ASSERT_TRUE(freeResult);
|
||||
}
|
||||
|
||||
TEST_F(InstallationDirLayoutTest, VersionedLayoutTest) {
|
||||
std::wstring runtimelib_path;
|
||||
runtimelib_path.append(dist_bin_dir);
|
||||
runtimelib_path.append(
|
||||
L"\\installation_dir_layout\\versioned\\InstallationDirLayout.dll");
|
||||
HINSTANCE hRuntimeLibrary =
|
||||
LoadLibraryEx(runtimelib_path.c_str(), nullptr, 0);
|
||||
ASSERT_NE(hRuntimeLibrary, nullptr);
|
||||
FuncType dirLayoutFunc =
|
||||
(FuncType)GetProcAddress(hRuntimeLibrary, "GetInstallationDirLayoutType");
|
||||
ASSERT_NE(dirLayoutFunc, nullptr);
|
||||
|
||||
InstallationDirLayoutType layoutType = dirLayoutFunc();
|
||||
ASSERT_EQ(layoutType, InstallationDirLayoutType::Versioned);
|
||||
bool freeResult = FreeLibrary(hRuntimeLibrary);
|
||||
ASSERT_TRUE(freeResult);
|
||||
}
|
||||
19
browser/app/installation_dir_layout/tests/gtest/moz.build
Normal file
19
browser/app/installation_dir_layout/tests/gtest/moz.build
Normal file
@@ -0,0 +1,19 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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 https://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEFINES["UNICODE"] = True
|
||||
DEFINES["_UNICODE"] = True
|
||||
LOCAL_INCLUDES += [
|
||||
"/browser/app/installation_dir_layout",
|
||||
]
|
||||
|
||||
Library("installation_dir_layout_test")
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"InstallationDirLayoutTest.cpp",
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = "xul-gtest"
|
||||
@@ -0,0 +1,9 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "InstallationDirLayout.h"
|
||||
|
||||
InstallationDirLayoutType GetInstallationDirLayoutType() {
|
||||
return InstallationDirLayoutType::Versioned;
|
||||
}
|
||||
13
browser/app/installation_dir_layout/versioned/moz.build
Normal file
13
browser/app/installation_dir_layout/versioned/moz.build
Normal file
@@ -0,0 +1,13 @@
|
||||
# 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/.
|
||||
|
||||
LOCAL_INCLUDES = [".."]
|
||||
SOURCES = [
|
||||
"InstallationDirLayout.cpp",
|
||||
]
|
||||
|
||||
DIST_SUBDIR = "installation_dir_layout/versioned"
|
||||
|
||||
DEFFILE = "../InstallationDirLayout.def"
|
||||
SharedLibrary("InstallationDirLayout")
|
||||
@@ -76,6 +76,7 @@ if CONFIG["CC_TYPE"] == "clang-cl":
|
||||
if CONFIG["OS_ARCH"] == "WINNT":
|
||||
RCINCLUDE = "splash.rc"
|
||||
DIRS += [
|
||||
"installation_dir_layout",
|
||||
"pbproxy",
|
||||
"winlauncher",
|
||||
]
|
||||
|
||||
@@ -91,6 +91,8 @@
|
||||
#endif
|
||||
#ifdef XP_WIN
|
||||
@BINPATH@/@MOZ_CHILD_PROCESS_NAME@
|
||||
@BINPATH@/@DLL_PREFIX@InstallationDirLayout@DLL_SUFFIX@
|
||||
@BINPATH@/installation_dir_layout/versioned/@DLL_PREFIX@InstallationDirLayout@DLL_SUFFIX@
|
||||
#if MOZ_PACKAGE_MSVC_DLLS
|
||||
@BINPATH@/@MSVC_C_RUNTIME_DLL@
|
||||
#ifdef MSVC_C_RUNTIME_1_DLL
|
||||
|
||||
Reference in New Issue
Block a user