1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/nix/xdg_util.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <optional>
8*6777b538SAndroid Build Coastguard Worker #include <string>
9*6777b538SAndroid Build Coastguard Worker
10*6777b538SAndroid Build Coastguard Worker #include "base/base_paths.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/command_line.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/environment.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/files/file_path.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/no_destructor.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/path_service.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/process/launch.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_split.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_tokenizer.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/third_party/xdg_user_dirs/xdg_user_dir_lookup.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/threading/scoped_blocking_call.h"
24*6777b538SAndroid Build Coastguard Worker
25*6777b538SAndroid Build Coastguard Worker namespace {
26*6777b538SAndroid Build Coastguard Worker
27*6777b538SAndroid Build Coastguard Worker // The KDE session version environment variable introduced in KDE 4.
28*6777b538SAndroid Build Coastguard Worker const char kKDESessionEnvVar[] = "KDE_SESSION_VERSION";
29*6777b538SAndroid Build Coastguard Worker
GetXdgActivationTokenCreator()30*6777b538SAndroid Build Coastguard Worker base::nix::XdgActivationTokenCreator& GetXdgActivationTokenCreator() {
31*6777b538SAndroid Build Coastguard Worker static base::NoDestructor<base::nix::XdgActivationTokenCreator> creator;
32*6777b538SAndroid Build Coastguard Worker return *creator;
33*6777b538SAndroid Build Coastguard Worker }
34*6777b538SAndroid Build Coastguard Worker
GetXdgActivationToken()35*6777b538SAndroid Build Coastguard Worker std::optional<std::string>& GetXdgActivationToken() {
36*6777b538SAndroid Build Coastguard Worker static base::NoDestructor<std::optional<std::string>> token;
37*6777b538SAndroid Build Coastguard Worker return *token;
38*6777b538SAndroid Build Coastguard Worker }
39*6777b538SAndroid Build Coastguard Worker
40*6777b538SAndroid Build Coastguard Worker } // namespace
41*6777b538SAndroid Build Coastguard Worker
42*6777b538SAndroid Build Coastguard Worker namespace base::nix {
43*6777b538SAndroid Build Coastguard Worker
44*6777b538SAndroid Build Coastguard Worker const char kDotConfigDir[] = ".config";
45*6777b538SAndroid Build Coastguard Worker const char kXdgConfigHomeEnvVar[] = "XDG_CONFIG_HOME";
46*6777b538SAndroid Build Coastguard Worker const char kXdgCurrentDesktopEnvVar[] = "XDG_CURRENT_DESKTOP";
47*6777b538SAndroid Build Coastguard Worker const char kXdgSessionTypeEnvVar[] = "XDG_SESSION_TYPE";
48*6777b538SAndroid Build Coastguard Worker const char kXdgActivationTokenEnvVar[] = "XDG_ACTIVATION_TOKEN";
49*6777b538SAndroid Build Coastguard Worker const char kXdgActivationTokenSwitch[] = "xdg-activation-token";
50*6777b538SAndroid Build Coastguard Worker
GetXDGDirectory(Environment * env,const char * env_name,const char * fallback_dir)51*6777b538SAndroid Build Coastguard Worker FilePath GetXDGDirectory(Environment* env,
52*6777b538SAndroid Build Coastguard Worker const char* env_name,
53*6777b538SAndroid Build Coastguard Worker const char* fallback_dir) {
54*6777b538SAndroid Build Coastguard Worker FilePath path;
55*6777b538SAndroid Build Coastguard Worker std::string env_value;
56*6777b538SAndroid Build Coastguard Worker if (env->GetVar(env_name, &env_value) && !env_value.empty()) {
57*6777b538SAndroid Build Coastguard Worker path = FilePath(env_value);
58*6777b538SAndroid Build Coastguard Worker } else {
59*6777b538SAndroid Build Coastguard Worker PathService::Get(DIR_HOME, &path);
60*6777b538SAndroid Build Coastguard Worker path = path.Append(fallback_dir);
61*6777b538SAndroid Build Coastguard Worker }
62*6777b538SAndroid Build Coastguard Worker return path.StripTrailingSeparators();
63*6777b538SAndroid Build Coastguard Worker }
64*6777b538SAndroid Build Coastguard Worker
GetXDGUserDirectory(const char * dir_name,const char * fallback_dir)65*6777b538SAndroid Build Coastguard Worker FilePath GetXDGUserDirectory(const char* dir_name, const char* fallback_dir) {
66*6777b538SAndroid Build Coastguard Worker FilePath path;
67*6777b538SAndroid Build Coastguard Worker char* xdg_dir = xdg_user_dir_lookup(dir_name);
68*6777b538SAndroid Build Coastguard Worker if (xdg_dir) {
69*6777b538SAndroid Build Coastguard Worker path = FilePath(xdg_dir);
70*6777b538SAndroid Build Coastguard Worker free(xdg_dir);
71*6777b538SAndroid Build Coastguard Worker } else {
72*6777b538SAndroid Build Coastguard Worker PathService::Get(DIR_HOME, &path);
73*6777b538SAndroid Build Coastguard Worker path = path.Append(fallback_dir);
74*6777b538SAndroid Build Coastguard Worker }
75*6777b538SAndroid Build Coastguard Worker return path.StripTrailingSeparators();
76*6777b538SAndroid Build Coastguard Worker }
77*6777b538SAndroid Build Coastguard Worker
GetXDGDataWriteLocation(Environment * env)78*6777b538SAndroid Build Coastguard Worker FilePath GetXDGDataWriteLocation(Environment* env) {
79*6777b538SAndroid Build Coastguard Worker return GetXDGDirectory(env, "XDG_DATA_HOME", ".local/share");
80*6777b538SAndroid Build Coastguard Worker }
81*6777b538SAndroid Build Coastguard Worker
GetXDGDataSearchLocations(Environment * env)82*6777b538SAndroid Build Coastguard Worker std::vector<FilePath> GetXDGDataSearchLocations(Environment* env) {
83*6777b538SAndroid Build Coastguard Worker ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::MAY_BLOCK);
84*6777b538SAndroid Build Coastguard Worker
85*6777b538SAndroid Build Coastguard Worker std::vector<FilePath> search_paths;
86*6777b538SAndroid Build Coastguard Worker search_paths.push_back(GetXDGDataWriteLocation(env));
87*6777b538SAndroid Build Coastguard Worker
88*6777b538SAndroid Build Coastguard Worker std::string xdg_data_dirs;
89*6777b538SAndroid Build Coastguard Worker if (env->GetVar("XDG_DATA_DIRS", &xdg_data_dirs) && !xdg_data_dirs.empty()) {
90*6777b538SAndroid Build Coastguard Worker StringTokenizer tokenizer(xdg_data_dirs, ":");
91*6777b538SAndroid Build Coastguard Worker while (tokenizer.GetNext()) {
92*6777b538SAndroid Build Coastguard Worker search_paths.emplace_back(tokenizer.token_piece());
93*6777b538SAndroid Build Coastguard Worker }
94*6777b538SAndroid Build Coastguard Worker } else {
95*6777b538SAndroid Build Coastguard Worker search_paths.emplace_back("/usr/local/share");
96*6777b538SAndroid Build Coastguard Worker search_paths.emplace_back("/usr/share");
97*6777b538SAndroid Build Coastguard Worker }
98*6777b538SAndroid Build Coastguard Worker
99*6777b538SAndroid Build Coastguard Worker return search_paths;
100*6777b538SAndroid Build Coastguard Worker }
101*6777b538SAndroid Build Coastguard Worker
GetDesktopEnvironment(Environment * env)102*6777b538SAndroid Build Coastguard Worker DesktopEnvironment GetDesktopEnvironment(Environment* env) {
103*6777b538SAndroid Build Coastguard Worker // kXdgCurrentDesktopEnvVar is the newest standard circa 2012.
104*6777b538SAndroid Build Coastguard Worker std::string xdg_current_desktop;
105*6777b538SAndroid Build Coastguard Worker if (env->GetVar(kXdgCurrentDesktopEnvVar, &xdg_current_desktop)) {
106*6777b538SAndroid Build Coastguard Worker // It could have multiple values separated by colon in priority order.
107*6777b538SAndroid Build Coastguard Worker for (const auto& value : SplitStringPiece(
108*6777b538SAndroid Build Coastguard Worker xdg_current_desktop, ":", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY)) {
109*6777b538SAndroid Build Coastguard Worker if (value == "Unity") {
110*6777b538SAndroid Build Coastguard Worker // gnome-fallback sessions set kXdgCurrentDesktopEnvVar to Unity
111*6777b538SAndroid Build Coastguard Worker // DESKTOP_SESSION can be gnome-fallback or gnome-fallback-compiz
112*6777b538SAndroid Build Coastguard Worker std::string desktop_session;
113*6777b538SAndroid Build Coastguard Worker if (env->GetVar("DESKTOP_SESSION", &desktop_session) &&
114*6777b538SAndroid Build Coastguard Worker desktop_session.find("gnome-fallback") != std::string::npos) {
115*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_GNOME;
116*6777b538SAndroid Build Coastguard Worker }
117*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_UNITY;
118*6777b538SAndroid Build Coastguard Worker }
119*6777b538SAndroid Build Coastguard Worker if (value == "Deepin") {
120*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_DEEPIN;
121*6777b538SAndroid Build Coastguard Worker }
122*6777b538SAndroid Build Coastguard Worker if (value == "GNOME") {
123*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_GNOME;
124*6777b538SAndroid Build Coastguard Worker }
125*6777b538SAndroid Build Coastguard Worker if (value == "X-Cinnamon") {
126*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_CINNAMON;
127*6777b538SAndroid Build Coastguard Worker }
128*6777b538SAndroid Build Coastguard Worker if (value == "KDE") {
129*6777b538SAndroid Build Coastguard Worker std::string kde_session;
130*6777b538SAndroid Build Coastguard Worker if (env->GetVar(kKDESessionEnvVar, &kde_session)) {
131*6777b538SAndroid Build Coastguard Worker if (kde_session == "5") {
132*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_KDE5;
133*6777b538SAndroid Build Coastguard Worker }
134*6777b538SAndroid Build Coastguard Worker if (kde_session == "6") {
135*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_KDE6;
136*6777b538SAndroid Build Coastguard Worker }
137*6777b538SAndroid Build Coastguard Worker }
138*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_KDE4;
139*6777b538SAndroid Build Coastguard Worker }
140*6777b538SAndroid Build Coastguard Worker if (value == "Pantheon") {
141*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_PANTHEON;
142*6777b538SAndroid Build Coastguard Worker }
143*6777b538SAndroid Build Coastguard Worker if (value == "XFCE") {
144*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_XFCE;
145*6777b538SAndroid Build Coastguard Worker }
146*6777b538SAndroid Build Coastguard Worker if (value == "UKUI") {
147*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_UKUI;
148*6777b538SAndroid Build Coastguard Worker }
149*6777b538SAndroid Build Coastguard Worker if (value == "LXQt") {
150*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_LXQT;
151*6777b538SAndroid Build Coastguard Worker }
152*6777b538SAndroid Build Coastguard Worker }
153*6777b538SAndroid Build Coastguard Worker }
154*6777b538SAndroid Build Coastguard Worker
155*6777b538SAndroid Build Coastguard Worker // DESKTOP_SESSION was what everyone used in 2010.
156*6777b538SAndroid Build Coastguard Worker std::string desktop_session;
157*6777b538SAndroid Build Coastguard Worker if (env->GetVar("DESKTOP_SESSION", &desktop_session)) {
158*6777b538SAndroid Build Coastguard Worker if (desktop_session == "deepin") {
159*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_DEEPIN;
160*6777b538SAndroid Build Coastguard Worker }
161*6777b538SAndroid Build Coastguard Worker if (desktop_session == "gnome" || desktop_session == "mate") {
162*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_GNOME;
163*6777b538SAndroid Build Coastguard Worker }
164*6777b538SAndroid Build Coastguard Worker if (desktop_session == "kde4" || desktop_session == "kde-plasma") {
165*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_KDE4;
166*6777b538SAndroid Build Coastguard Worker }
167*6777b538SAndroid Build Coastguard Worker if (desktop_session == "kde") {
168*6777b538SAndroid Build Coastguard Worker // This may mean KDE4 on newer systems, so we have to check.
169*6777b538SAndroid Build Coastguard Worker if (env->HasVar(kKDESessionEnvVar)) {
170*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_KDE4;
171*6777b538SAndroid Build Coastguard Worker }
172*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_KDE3;
173*6777b538SAndroid Build Coastguard Worker }
174*6777b538SAndroid Build Coastguard Worker if (desktop_session.find("xfce") != std::string::npos ||
175*6777b538SAndroid Build Coastguard Worker desktop_session == "xubuntu") {
176*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_XFCE;
177*6777b538SAndroid Build Coastguard Worker }
178*6777b538SAndroid Build Coastguard Worker if (desktop_session == "ukui") {
179*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_UKUI;
180*6777b538SAndroid Build Coastguard Worker }
181*6777b538SAndroid Build Coastguard Worker }
182*6777b538SAndroid Build Coastguard Worker
183*6777b538SAndroid Build Coastguard Worker // Fall back on some older environment variables.
184*6777b538SAndroid Build Coastguard Worker // Useful particularly in the DESKTOP_SESSION=default case.
185*6777b538SAndroid Build Coastguard Worker if (env->HasVar("GNOME_DESKTOP_SESSION_ID")) {
186*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_GNOME;
187*6777b538SAndroid Build Coastguard Worker }
188*6777b538SAndroid Build Coastguard Worker if (env->HasVar("KDE_FULL_SESSION")) {
189*6777b538SAndroid Build Coastguard Worker if (env->HasVar(kKDESessionEnvVar)) {
190*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_KDE4;
191*6777b538SAndroid Build Coastguard Worker }
192*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_KDE3;
193*6777b538SAndroid Build Coastguard Worker }
194*6777b538SAndroid Build Coastguard Worker
195*6777b538SAndroid Build Coastguard Worker return DESKTOP_ENVIRONMENT_OTHER;
196*6777b538SAndroid Build Coastguard Worker }
197*6777b538SAndroid Build Coastguard Worker
GetDesktopEnvironmentName(DesktopEnvironment env)198*6777b538SAndroid Build Coastguard Worker const char* GetDesktopEnvironmentName(DesktopEnvironment env) {
199*6777b538SAndroid Build Coastguard Worker switch (env) {
200*6777b538SAndroid Build Coastguard Worker case DESKTOP_ENVIRONMENT_OTHER:
201*6777b538SAndroid Build Coastguard Worker return nullptr;
202*6777b538SAndroid Build Coastguard Worker case DESKTOP_ENVIRONMENT_CINNAMON:
203*6777b538SAndroid Build Coastguard Worker return "CINNAMON";
204*6777b538SAndroid Build Coastguard Worker case DESKTOP_ENVIRONMENT_DEEPIN:
205*6777b538SAndroid Build Coastguard Worker return "DEEPIN";
206*6777b538SAndroid Build Coastguard Worker case DESKTOP_ENVIRONMENT_GNOME:
207*6777b538SAndroid Build Coastguard Worker return "GNOME";
208*6777b538SAndroid Build Coastguard Worker case DESKTOP_ENVIRONMENT_KDE3:
209*6777b538SAndroid Build Coastguard Worker return "KDE3";
210*6777b538SAndroid Build Coastguard Worker case DESKTOP_ENVIRONMENT_KDE4:
211*6777b538SAndroid Build Coastguard Worker return "KDE4";
212*6777b538SAndroid Build Coastguard Worker case DESKTOP_ENVIRONMENT_KDE5:
213*6777b538SAndroid Build Coastguard Worker return "KDE5";
214*6777b538SAndroid Build Coastguard Worker case DESKTOP_ENVIRONMENT_KDE6:
215*6777b538SAndroid Build Coastguard Worker return "KDE6";
216*6777b538SAndroid Build Coastguard Worker case DESKTOP_ENVIRONMENT_PANTHEON:
217*6777b538SAndroid Build Coastguard Worker return "PANTHEON";
218*6777b538SAndroid Build Coastguard Worker case DESKTOP_ENVIRONMENT_UNITY:
219*6777b538SAndroid Build Coastguard Worker return "UNITY";
220*6777b538SAndroid Build Coastguard Worker case DESKTOP_ENVIRONMENT_XFCE:
221*6777b538SAndroid Build Coastguard Worker return "XFCE";
222*6777b538SAndroid Build Coastguard Worker case DESKTOP_ENVIRONMENT_UKUI:
223*6777b538SAndroid Build Coastguard Worker return "UKUI";
224*6777b538SAndroid Build Coastguard Worker case DESKTOP_ENVIRONMENT_LXQT:
225*6777b538SAndroid Build Coastguard Worker return "LXQT";
226*6777b538SAndroid Build Coastguard Worker }
227*6777b538SAndroid Build Coastguard Worker return nullptr;
228*6777b538SAndroid Build Coastguard Worker }
229*6777b538SAndroid Build Coastguard Worker
GetDesktopEnvironmentName(Environment * env)230*6777b538SAndroid Build Coastguard Worker const char* GetDesktopEnvironmentName(Environment* env) {
231*6777b538SAndroid Build Coastguard Worker return GetDesktopEnvironmentName(GetDesktopEnvironment(env));
232*6777b538SAndroid Build Coastguard Worker }
233*6777b538SAndroid Build Coastguard Worker
GetSessionType(Environment & env)234*6777b538SAndroid Build Coastguard Worker SessionType GetSessionType(Environment& env) {
235*6777b538SAndroid Build Coastguard Worker std::string xdg_session_type;
236*6777b538SAndroid Build Coastguard Worker if (!env.GetVar(kXdgSessionTypeEnvVar, &xdg_session_type)) {
237*6777b538SAndroid Build Coastguard Worker return SessionType::kUnset;
238*6777b538SAndroid Build Coastguard Worker }
239*6777b538SAndroid Build Coastguard Worker
240*6777b538SAndroid Build Coastguard Worker TrimWhitespaceASCII(ToLowerASCII(xdg_session_type), TrimPositions::TRIM_ALL,
241*6777b538SAndroid Build Coastguard Worker &xdg_session_type);
242*6777b538SAndroid Build Coastguard Worker
243*6777b538SAndroid Build Coastguard Worker if (xdg_session_type == "wayland") {
244*6777b538SAndroid Build Coastguard Worker return SessionType::kWayland;
245*6777b538SAndroid Build Coastguard Worker }
246*6777b538SAndroid Build Coastguard Worker
247*6777b538SAndroid Build Coastguard Worker if (xdg_session_type == "x11") {
248*6777b538SAndroid Build Coastguard Worker return SessionType::kX11;
249*6777b538SAndroid Build Coastguard Worker }
250*6777b538SAndroid Build Coastguard Worker
251*6777b538SAndroid Build Coastguard Worker if (xdg_session_type == "tty") {
252*6777b538SAndroid Build Coastguard Worker return SessionType::kTty;
253*6777b538SAndroid Build Coastguard Worker }
254*6777b538SAndroid Build Coastguard Worker
255*6777b538SAndroid Build Coastguard Worker if (xdg_session_type == "mir") {
256*6777b538SAndroid Build Coastguard Worker return SessionType::kMir;
257*6777b538SAndroid Build Coastguard Worker }
258*6777b538SAndroid Build Coastguard Worker
259*6777b538SAndroid Build Coastguard Worker if (xdg_session_type == "unspecified") {
260*6777b538SAndroid Build Coastguard Worker return SessionType::kUnspecified;
261*6777b538SAndroid Build Coastguard Worker }
262*6777b538SAndroid Build Coastguard Worker
263*6777b538SAndroid Build Coastguard Worker LOG(ERROR) << "Unknown XDG_SESSION_TYPE: " << xdg_session_type;
264*6777b538SAndroid Build Coastguard Worker return SessionType::kOther;
265*6777b538SAndroid Build Coastguard Worker }
266*6777b538SAndroid Build Coastguard Worker
ExtractXdgActivationTokenFromEnv(Environment & env)267*6777b538SAndroid Build Coastguard Worker std::optional<std::string> ExtractXdgActivationTokenFromEnv(Environment& env) {
268*6777b538SAndroid Build Coastguard Worker std::string token;
269*6777b538SAndroid Build Coastguard Worker if (env.GetVar(kXdgActivationTokenEnvVar, &token) && !token.empty()) {
270*6777b538SAndroid Build Coastguard Worker GetXdgActivationToken() = std::move(token);
271*6777b538SAndroid Build Coastguard Worker env.UnSetVar(kXdgActivationTokenEnvVar);
272*6777b538SAndroid Build Coastguard Worker }
273*6777b538SAndroid Build Coastguard Worker return GetXdgActivationToken();
274*6777b538SAndroid Build Coastguard Worker }
275*6777b538SAndroid Build Coastguard Worker
ExtractXdgActivationTokenFromCmdLine(base::CommandLine & cmd_line)276*6777b538SAndroid Build Coastguard Worker void ExtractXdgActivationTokenFromCmdLine(base::CommandLine& cmd_line) {
277*6777b538SAndroid Build Coastguard Worker std::string token = cmd_line.GetSwitchValueASCII(kXdgActivationTokenSwitch);
278*6777b538SAndroid Build Coastguard Worker if (!token.empty()) {
279*6777b538SAndroid Build Coastguard Worker GetXdgActivationToken() = std::move(token);
280*6777b538SAndroid Build Coastguard Worker cmd_line.RemoveSwitch(kXdgActivationTokenSwitch);
281*6777b538SAndroid Build Coastguard Worker }
282*6777b538SAndroid Build Coastguard Worker }
283*6777b538SAndroid Build Coastguard Worker
TakeXdgActivationToken()284*6777b538SAndroid Build Coastguard Worker std::optional<std::string> TakeXdgActivationToken() {
285*6777b538SAndroid Build Coastguard Worker auto token = GetXdgActivationToken();
286*6777b538SAndroid Build Coastguard Worker GetXdgActivationToken().reset();
287*6777b538SAndroid Build Coastguard Worker return token;
288*6777b538SAndroid Build Coastguard Worker }
289*6777b538SAndroid Build Coastguard Worker
SetXdgActivationTokenCreator(XdgActivationTokenCreator token_creator)290*6777b538SAndroid Build Coastguard Worker void SetXdgActivationTokenCreator(XdgActivationTokenCreator token_creator) {
291*6777b538SAndroid Build Coastguard Worker GetXdgActivationTokenCreator() = std::move(token_creator);
292*6777b538SAndroid Build Coastguard Worker }
293*6777b538SAndroid Build Coastguard Worker
CreateLaunchOptionsWithXdgActivation(XdgActivationLaunchOptionsCallback callback)294*6777b538SAndroid Build Coastguard Worker void CreateLaunchOptionsWithXdgActivation(
295*6777b538SAndroid Build Coastguard Worker XdgActivationLaunchOptionsCallback callback) {
296*6777b538SAndroid Build Coastguard Worker if (!GetXdgActivationTokenCreator()) {
297*6777b538SAndroid Build Coastguard Worker // There is no token creator, so return an empty LaunchOptions.
298*6777b538SAndroid Build Coastguard Worker std::move(callback).Run(LaunchOptions());
299*6777b538SAndroid Build Coastguard Worker return;
300*6777b538SAndroid Build Coastguard Worker }
301*6777b538SAndroid Build Coastguard Worker auto create_token_cb =
302*6777b538SAndroid Build Coastguard Worker [](XdgActivationLaunchOptionsCallback launch_options_cb,
303*6777b538SAndroid Build Coastguard Worker std::string token) {
304*6777b538SAndroid Build Coastguard Worker base::LaunchOptions options;
305*6777b538SAndroid Build Coastguard Worker if (!token.empty()) {
306*6777b538SAndroid Build Coastguard Worker options.environment[kXdgActivationTokenEnvVar] = token;
307*6777b538SAndroid Build Coastguard Worker }
308*6777b538SAndroid Build Coastguard Worker std::move(launch_options_cb).Run(options);
309*6777b538SAndroid Build Coastguard Worker };
310*6777b538SAndroid Build Coastguard Worker GetXdgActivationTokenCreator().Run(
311*6777b538SAndroid Build Coastguard Worker base::BindOnce(create_token_cb, std::move(callback)));
312*6777b538SAndroid Build Coastguard Worker }
313*6777b538SAndroid Build Coastguard Worker
314*6777b538SAndroid Build Coastguard Worker } // namespace base::nix
315