Skip to content

Commit 42169be

Browse files
committed
helium/updater: init
1 parent a877712 commit 42169be

11 files changed

Lines changed: 1859 additions & 0 deletions
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--- a/chrome/installer/setup/setup_main.cc
2+
+++ b/chrome/installer/setup/setup_main.cc
3+
@@ -1235,7 +1235,17 @@ InstallStatus InstallProductsHelper(Inst
4+
if (!IsDowngradeAllowed(prefs)) {
5+
const ProductState* product_state =
6+
original_state.GetProductState(system_install);
7+
+ // We used to ship with the versions still using the Chromium versioning,
8+
+ // which breaks updates if we e.g. release an update while still on the same
9+
+ // Chromium base. We migrated off those, but now we need a temporary workaround
10+
+ // because otherwise users updating from "148".x to 0.x.x.x will always hit
11+
+ // that a "higher version of chrome" is already installed.
12+
+ const bool is_helium_version_migration =
13+
+ product_state && product_state->version().components()[0] > 100 &&
14+
+ installer_version->components()[0] == 0;
15+
+
16+
if (product_state != nullptr &&
17+
+ !is_helium_version_migration &&
18+
(product_state->version().CompareTo(*installer_version) > 0)) {
19+
LOG(ERROR) << "Higher version of Chrome is already installed.";
20+
int message_id = IDS_INSTALL_HIGHER_VERSION_BASE;
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
--- a/chrome/browser/BUILD.gn
2+
+++ b/chrome/browser/BUILD.gn
3+
@@ -57,6 +57,7 @@ if (is_android) {
4+
5+
if (is_win) {
6+
import("//build/config/win/manifest.gni")
7+
+ import("//chrome/updater/winsparkle.gni")
8+
}
9+
10+
assert(!is_fuchsia, "Fuchsia shouldn't use anything in //chrome")
11+
@@ -103,6 +104,13 @@ buildflag_header("buildflags") {
12+
13+
if (is_win) {
14+
flags += [ "ENABLE_SEGMENT_HEAP=$enable_segment_heap" ]
15+
+
16+
+ flags += [
17+
+ "ENABLE_WINSPARKLE=$enable_winsparkle",
18+
+ "WINSPARKLE_ED_KEY=\"$winsparkle_ed_key\"",
19+
+ "WINSPARKLE_AUTOMATIC_CHECKS=$winsparkle_automatic_checks",
20+
+ "WINSPARKLE_CHECK_INTERVAL=$winsparkle_check_interval",
21+
+ ]
22+
}
23+
24+
# Android and ChromeOS don't support multiple browser processes, so they don't
25+
@@ -5834,6 +5842,17 @@ static_library("browser") {
26+
}
27+
28+
if (is_win) {
29+
+ if (enable_winsparkle) {
30+
+ sources += [
31+
+ "win/winsparkle_glue.cc",
32+
+ "win/winsparkle_glue.h",
33+
+ ]
34+
+ deps += [
35+
+ "//components/helium_services",
36+
+ "//third_party/winsparkle",
37+
+ ]
38+
+ }
39+
+
40+
libs += [
41+
"secur32.lib",
42+
43+
--- a/chrome/browser/buildflags.gni
44+
+++ b/chrome/browser/buildflags.gni
45+
@@ -3,6 +3,9 @@
46+
# found in the LICENSE file.
47+
48+
import("//build/config/chrome_build.gni")
49+
+if (is_win) {
50+
+ import("//chrome/updater/winsparkle.gni")
51+
+}
52+
53+
# IMPORTANT
54+
# We are not accepting any new build flags in //chrome. See
55+
@@ -17,5 +20,5 @@ declare_args() {
56+
57+
# Detect updates and notify the user for Google Chrome across all platforms.
58+
# Chromium does not use an auto-updater.
59+
- enable_update_notifications = is_chrome_branded
60+
+ enable_update_notifications = enable_winsparkle
61+
}
62+
--- a/chrome/browser/ui/BUILD.gn
63+
+++ b/chrome/browser/ui/BUILD.gn
64+
@@ -31,6 +31,10 @@ import("//ui/views/features.gni")
65+
assert(enable_supervised_users)
66+
assert(!is_fuchsia, "Fuchsia shouldn't use anything in //chrome")
67+
68+
+if (is_win) {
69+
+ import("//chrome/updater/winsparkle.gni")
70+
+}
71+
+
72+
generate_allowlist_from_histograms_file("webui_name_variants") {
73+
namespace = "views_metrics"
74+
input_xml_file = "//tools/metrics/histograms/metadata/page/histograms.xml"
75+
@@ -3527,7 +3531,7 @@ static_library("ui") {
76+
"//chrome/browser/win/installer_downloader:prefs",
77+
"//chrome/updater/app/server/win:updater_legacy_idl",
78+
]
79+
- } else {
80+
+ } else if (!enable_winsparkle) {
81+
sources += [ "webui/help/version_updater_basic.cc" ]
82+
}
83+
}
84+
--- a/chrome/installer/mini_installer/chrome.release
85+
+++ b/chrome/installer/mini_installer/chrome.release
86+
@@ -36,6 +36,7 @@ vk_swiftshader.dll: %(VersionDir)s\
87+
vk_swiftshader_icd.json: %(VersionDir)s\
88+
vulkan-1.dll: %(VersionDir)s\
89+
v8_context_snapshot.bin: %(VersionDir)s\
90+
+WinSparkle.dll: %(VersionDir)s\
91+
#
92+
# Sub directories living in the version dir
93+
#
94+
--- a/chrome/tools/build/win/FILES.cfg
95+
+++ b/chrome/tools/build/win/FILES.cfg
96+
@@ -79,6 +79,12 @@ FILES = [
97+
'filegroup': ['default'],
98+
},
99+
{
100+
+ 'filename': 'WinSparkle.dll',
101+
+ 'buildtype': ['dev', 'official'],
102+
+ 'filegroup': ['default'],
103+
+ 'optional': ['dev', 'official'],
104+
+ },
105+
+ {
106+
'filename': '*.manifest',
107+
'buildtype': ['official'],
108+
'filegroup': ['default'],
109+
--- /dev/null
110+
+++ b/chrome/updater/winsparkle.gni
111+
@@ -0,0 +1,13 @@
112+
+# Copyright 2026 The Helium Authors
113+
+# You can use, redistribute, and/or modify this source code under
114+
+# the terms of the GPL-3.0 license that can be found in the LICENSE file.
115+
+
116+
+declare_args() {
117+
+ enable_winsparkle = true
118+
+ winsparkle_ed_key = ""
119+
+ winsparkle_automatic_checks = true
120+
+ winsparkle_check_interval = 3600
121+
+
122+
+ # Must match the Subject Organization (O= field) of the signing cert.
123+
+ winsparkle_authenticode_org = ""
124+
+}
125+
--- a/infra/archive_config/win-archive-rel.json
126+
+++ b/infra/archive_config/win-archive-rel.json
127+
@@ -33,7 +33,8 @@
128+
"v8_context_snapshot.bin",
129+
"vk_swiftshader.dll",
130+
"vk_swiftshader_icd.json",
131+
- "vulkan-1.dll"
132+
+ "vulkan-1.dll",
133+
+ "WinSparkle.dll"
134+
],
135+
"file_globs": [
136+
"locales\\*.pak",
137+
--- /dev/null
138+
+++ b/third_party/winsparkle/BUILD.gn
139+
@@ -0,0 +1,68 @@
140+
+# Copyright 2026 The Helium Authors
141+
+# You can use, redistribute, and/or modify this source code under
142+
+# the terms of the GPL-3.0 license that can be found in the LICENSE file.
143+
+
144+
+assert(is_win)
145+
+
146+
+config("winsparkle_config") {
147+
+ defines = [ "WIN_SPARKLE_NO_AUTOLINK" ]
148+
+ include_dirs = [ "include" ]
149+
+}
150+
+
151+
+shared_library("winsparkle") {
152+
+ output_name = "WinSparkle"
153+
+
154+
+ sources = [
155+
+ "src/appcast.cpp",
156+
+ "src/appcontroller.cpp",
157+
+ "src/dll_api.cpp",
158+
+ "src/dllmain.cpp",
159+
+ "src/download.cpp",
160+
+ "src/error.cpp",
161+
+ "src/settings.cpp",
162+
+ "src/signatureverifier.cpp",
163+
+ "src/threads.cpp",
164+
+ "src/ui_headless.cpp", # headless replacement for src/ui.cpp.
165+
+ "src/updatechecker.cpp",
166+
+ "src/updatedownloader.cpp",
167+
+ "src/winsparkle.rc",
168+
+ ]
169+
+
170+
+ include_dirs = [
171+
+ "include",
172+
+ "src",
173+
+ ]
174+
+
175+
+ defines = [ "BUILDING_WIN_SPARKLE" ]
176+
+
177+
+ deps = [
178+
+ "//third_party/boringssl",
179+
+ "//third_party/expat",
180+
+ ]
181+
+
182+
+ libs = [
183+
+ "advapi32.lib",
184+
+ "crypt32.lib",
185+
+ "ole32.lib",
186+
+ "rpcrt4.lib",
187+
+ "shell32.lib",
188+
+ "user32.lib",
189+
+ "wininet.lib",
190+
+ ]
191+
+
192+
+ configs -= [
193+
+ "//build/config/compiler:chromium_code",
194+
+ "//build/config/compiler:no_exceptions",
195+
+ ]
196+
+ configs += [
197+
+ "//build/config/compiler:no_chromium_code",
198+
+ "//build/config/compiler:exceptions",
199+
+ ]
200+
+
201+
+ cflags_cc = [
202+
+ "-Wno-misleading-indentation", # appcast.cpp
203+
+ "-Wno-reorder-ctor", # updatedownloader.cpp
204+
+ ]
205+
+
206+
+ public_configs = [ ":winsparkle_config" ]
207+
+}
208+
--- /dev/null
209+
+++ b/third_party/winsparkle/README.chromium
210+
@@ -0,0 +1,13 @@
211+
+Name: WinSparkle
212+
+Short Name: winsparkle
213+
+URL: https://github.com/vslavik/winsparkle
214+
+License: MIT
215+
+License File: COPYING
216+
+Shipped: yes
217+
+Security Critical: yes
218+
+
219+
+Description:
220+
+Used for Windows autoupdates.
221+
+
222+
+Local Modifications:
223+
+Ripped out all UI logic, old DSA signing logic, and dependencies thereof.
224+
--- a/third_party/winsparkle/include/winsparkle.h
225+
+++ b/third_party/winsparkle/include/winsparkle.h
226+
@@ -31,7 +31,11 @@
227+
228+
#include "winsparkle-version.h"
229+
230+
-#if !defined(BUILDING_WIN_SPARKLE) && defined(_MSC_VER)
231+
+// WIN_SPARKLE_NO_AUTOLINK lets GN link the import library explicitly
232+
+// via the build system instead of via this pragma whose hard-coded name
233+
+// may not match the GN import lib.
234+
+#if !defined(BUILDING_WIN_SPARKLE) && !defined(WIN_SPARKLE_NO_AUTOLINK) && \
235+
+ defined(_MSC_VER)
236+
#pragma comment(lib, "WinSparkle.lib")
237+
#endif
238+
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
--- a/chrome/browser/upgrade_detector/get_installed_version_win.cc
2+
+++ b/chrome/browser/upgrade_detector/get_installed_version_win.cc
3+
@@ -11,10 +11,51 @@
4+
#include "base/location.h"
5+
#include "base/task/task_traits.h"
6+
#include "base/task/thread_pool.h"
7+
+#include "chrome/browser/buildflags.h"
8+
+
9+
+#if BUILDFLAG(ENABLE_WINSPARKLE)
10+
+#include <windows.h>
11+
+
12+
+#include <vector>
13+
+
14+
+#include "base/base_paths.h"
15+
+#include "base/files/file_path.h"
16+
+#include "base/path_service.h"
17+
+#include "base/version.h"
18+
+#include "base/version_info/version_info.h"
19+
+#include "chrome/installer/util/util_constants.h"
20+
+#else
21+
#include "chrome/installer/util/install_util.h"
22+
+#endif
23+
24+
namespace {
25+
26+
+#if BUILDFLAG(ENABLE_WINSPARKLE)
27+
+
28+
+// Duplicated helium::HasPendingUpdateSwap() here rather than shared to
29+
+// avoid an upgrade_detector -> //chrome/browser circular dependency.
30+
+bool HasPendingUpdateSwap() {
31+
+ base::FilePath dir;
32+
+ if (!base::PathService::Get(base::DIR_EXE, &dir)) {
33+
+ return false;
34+
+ }
35+
+ return ::GetFileAttributesW(
36+
+ dir.Append(installer::kChromeNewExe).value().c_str()) !=
37+
+ INVALID_FILE_ATTRIBUTES;
38+
+}
39+
+
40+
+InstalledAndCriticalVersion GetInstalledVersionSynchronous() {
41+
+ base::Version running = version_info::GetVersion();
42+
+ if (HasPendingUpdateSwap() && running.IsValid()) {
43+
+ std::vector<uint32_t> components = running.components();
44+
+ components.back() += 1;
45+
+ return InstalledAndCriticalVersion(base::Version(std::move(components)));
46+
+ }
47+
+ return InstalledAndCriticalVersion(std::move(running));
48+
+}
49+
+
50+
+#else // !BUILDFLAG(ENABLE_WINSPARKLE)
51+
+
52+
InstalledAndCriticalVersion GetInstalledVersionSynchronous() {
53+
base::Version installed_version =
54+
InstallUtil::GetChromeVersion(!InstallUtil::IsPerUserInstall());
55+
@@ -28,6 +69,8 @@ InstalledAndCriticalVersion GetInstalled
56+
return InstalledAndCriticalVersion(std::move(installed_version));
57+
}
58+
59+
+#endif // BUILDFLAG(ENABLE_WINSPARKLE)
60+
+
61+
} // namespace
62+
63+
void GetInstalledVersion(InstalledVersionCallback callback) {

0 commit comments

Comments
 (0)