xref: /aosp_15_r20/external/cronet/base/nix/xdg_util.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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