OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/shell_integration_linux.h" | 5 #include "chrome/browser/shell_integration_linux.h" |
6 | 6 |
7 #include <fcntl.h> | 7 #include <fcntl.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
157 if (ran_ok && exit_code == EXIT_XDG_SETTINGS_SYNTAX_ERROR) { | 157 if (ran_ok && exit_code == EXIT_XDG_SETTINGS_SYNTAX_ERROR) { |
158 if (GetChromeVersionOfScript(kXdgSettings, &argv[0])) { | 158 if (GetChromeVersionOfScript(kXdgSettings, &argv[0])) { |
159 ran_ok = LaunchXdgUtility(argv, &exit_code); | 159 ran_ok = LaunchXdgUtility(argv, &exit_code); |
160 } | 160 } |
161 } | 161 } |
162 | 162 |
163 return ran_ok && exit_code == EXIT_SUCCESS; | 163 return ran_ok && exit_code == EXIT_SUCCESS; |
164 #endif | 164 #endif |
165 } | 165 } |
166 | 166 |
167 // If |protocol| is empty this function checks if Chrome is the default browser, | 167 #if !defined(OS_CHROMEOS) |
168 // otherwise it checks if Chrome is the default handler application for | 168 // If |check| is true, returns the output of "xdg-settings check {property} |
169 // |protocol|. | 169 // *.desktop", otherwise returns the output of "xdg-settings get {property}", |
170 DefaultWebClientState GetIsDefaultWebClient(const std::string& protocol) { | 170 // where property is "default-web-browser" if |protocol| is empty or |
171 #if defined(OS_CHROMEOS) | 171 // "default-url-scheme-handler |protocol|" otherwise. Returns "" if |
172 return UNKNOWN_DEFAULT; | 172 // xdg-settings fails for any reason. |
173 #else | 173 std::string GetXdgSettingsOutput(bool check, |
174 base::ThreadRestrictions::AssertIOAllowed(); | 174 const std::string& protocol, |
175 | 175 base::Environment* env) { |
176 std::unique_ptr<base::Environment> env(base::Environment::Create()); | |
177 | |
178 std::vector<std::string> argv; | 176 std::vector<std::string> argv; |
179 argv.push_back(kXdgSettings); | 177 argv.push_back(kXdgSettings); |
180 argv.push_back("check"); | 178 argv.push_back(check ? "check" : "get"); |
181 if (protocol.empty()) { | 179 if (protocol.empty()) { |
182 argv.push_back(kXdgSettingsDefaultBrowser); | 180 argv.push_back(kXdgSettingsDefaultBrowser); |
183 } else { | 181 } else { |
184 argv.push_back(kXdgSettingsDefaultSchemeHandler); | 182 argv.push_back(kXdgSettingsDefaultSchemeHandler); |
185 argv.push_back(protocol); | 183 argv.push_back(protocol); |
186 } | 184 } |
187 argv.push_back(shell_integration_linux::GetDesktopName(env.get())); | 185 if (check) |
186 argv.push_back(shell_integration_linux::GetDesktopName(env)); | |
188 | 187 |
189 std::string reply; | 188 std::string reply; |
190 int success_code; | 189 int success_code; |
191 bool ran_ok = base::GetAppOutputWithExitCode(base::CommandLine(argv), &reply, | 190 bool ran_ok = base::GetAppOutputWithExitCode(base::CommandLine(argv), &reply, |
192 &success_code); | 191 &success_code); |
193 if (ran_ok && success_code == EXIT_XDG_SETTINGS_SYNTAX_ERROR) { | 192 if (ran_ok && success_code == EXIT_XDG_SETTINGS_SYNTAX_ERROR) { |
194 if (GetChromeVersionOfScript(kXdgSettings, &argv[0])) { | 193 if (GetChromeVersionOfScript(kXdgSettings, &argv[0])) { |
195 ran_ok = base::GetAppOutputWithExitCode(base::CommandLine(argv), &reply, | 194 ran_ok = base::GetAppOutputWithExitCode(base::CommandLine(argv), &reply, |
196 &success_code); | 195 &success_code); |
197 } | 196 } |
198 } | 197 } |
199 | 198 |
200 if (!ran_ok || success_code != EXIT_SUCCESS) { | 199 if (!ran_ok || success_code != EXIT_SUCCESS) |
201 // xdg-settings failed: we can't determine or set the default browser. | 200 return std::string(); |
202 return UNKNOWN_DEFAULT; | 201 |
202 return reply; | |
203 } | |
204 #endif | |
205 | |
206 // If |protocol| is empty this function checks if Chrome is the default browser, | |
207 // otherwise it checks if Chrome is the default handler application for | |
208 // |protocol|. | |
209 DefaultWebClientState GetDefaultWebClient(const std::string& protocol) { | |
210 #if defined(OS_CHROMEOS) | |
211 return UNKNOWN_DEFAULT; | |
212 #else | |
213 base::ThreadRestrictions::AssertIOAllowed(); | |
214 | |
215 std::unique_ptr<base::Environment> env(base::Environment::Create()); | |
216 std::string xdg_is_default = GetXdgSettingsOutput(true, protocol, env.get()); | |
217 if (base::StartsWith(xdg_is_default, "yes", base::CompareCase::SENSITIVE)) { | |
218 return IS_DEFAULT; | |
219 } | |
220 if (base::StartsWith(xdg_is_default, "no", base::CompareCase::SENSITIVE)) { | |
221 // An output of "no" does not necessarily mean Chrom[e,ium] is not the | |
Mike Mammarella
2017/03/11 03:05:04
So, you're sort of defeating the purpose of having
| |
222 // default. According to the xdg-settings man page, this can happen when | |
223 // "only some of the underlying settings actually reflect that value". Don't | |
224 // return NOT_DEFAULT unless we're sure, or else an annoying "Chrome is not | |
225 // your default browser" banner will appear on every launch | |
226 // (https://crbug.com/578888). | |
227 if (base::StartsWith(GetXdgSettingsOutput(false, protocol, env.get()), | |
228 shell_integration_linux::GetDesktopName(env.get()), | |
229 base::CompareCase::SENSITIVE)) { | |
230 // This is the odd case where 'xdg-settings check' said that Chrome wasn't | |
231 // the default, but 'xdg-settings get' returned Chrome as the default. | |
232 return UNKNOWN_DEFAULT; | |
233 } | |
234 // xdg-settings says the default is non-Chrome, and is self-consistent. | |
235 return NOT_DEFAULT; | |
203 } | 236 } |
204 | 237 |
205 // Allow any reply that starts with "yes". | 238 // xdg-settings failed: we can't determine or set the default browser. |
206 return base::StartsWith(reply, "yes", base::CompareCase::SENSITIVE) | 239 return UNKNOWN_DEFAULT; |
207 ? IS_DEFAULT | |
208 : NOT_DEFAULT; | |
209 #endif | 240 #endif |
210 } | 241 } |
211 | 242 |
212 // https://wiki.gnome.org/Projects/GnomeShell/ApplicationBased | 243 // https://wiki.gnome.org/Projects/GnomeShell/ApplicationBased |
213 // The WM_CLASS property should be set to the same as the *.desktop file without | 244 // The WM_CLASS property should be set to the same as the *.desktop file without |
214 // the .desktop extension. We cannot simply use argv[0] in this case, because | 245 // the .desktop extension. We cannot simply use argv[0] in this case, because |
215 // on the stable channel, the executable name is google-chrome-stable, but the | 246 // on the stable channel, the executable name is google-chrome-stable, but the |
216 // desktop file is google-chrome.desktop. | 247 // desktop file is google-chrome.desktop. |
217 std::string GetDesktopBaseName(const std::string& desktop_file_name) { | 248 std::string GetDesktopBaseName(const std::string& desktop_file_name) { |
218 static const char kDesktopExtension[] = ".desktop"; | 249 static const char kDesktopExtension[] = ".desktop"; |
(...skipping 17 matching lines...) Expand all Loading... | |
236 | 267 |
237 DefaultWebClientSetPermission GetDefaultWebClientSetPermission() { | 268 DefaultWebClientSetPermission GetDefaultWebClientSetPermission() { |
238 return SET_DEFAULT_UNATTENDED; | 269 return SET_DEFAULT_UNATTENDED; |
239 } | 270 } |
240 | 271 |
241 base::string16 GetApplicationNameForProtocol(const GURL& url) { | 272 base::string16 GetApplicationNameForProtocol(const GURL& url) { |
242 return base::ASCIIToUTF16("xdg-open"); | 273 return base::ASCIIToUTF16("xdg-open"); |
243 } | 274 } |
244 | 275 |
245 DefaultWebClientState GetDefaultBrowser() { | 276 DefaultWebClientState GetDefaultBrowser() { |
246 return GetIsDefaultWebClient(std::string()); | 277 return GetDefaultWebClient(std::string()); |
247 } | 278 } |
248 | 279 |
249 bool IsFirefoxDefaultBrowser() { | 280 bool IsFirefoxDefaultBrowser() { |
250 std::vector<std::string> argv; | 281 std::vector<std::string> argv; |
251 argv.push_back(kXdgSettings); | 282 argv.push_back(kXdgSettings); |
252 argv.push_back("get"); | 283 argv.push_back("get"); |
253 argv.push_back(kXdgSettingsDefaultBrowser); | 284 argv.push_back(kXdgSettingsDefaultBrowser); |
254 | 285 |
255 std::string browser; | 286 std::string browser; |
256 // We don't care about the return value here. | 287 // We don't care about the return value here. |
257 base::GetAppOutput(base::CommandLine(argv), &browser); | 288 base::GetAppOutput(base::CommandLine(argv), &browser); |
258 return browser.find("irefox") != std::string::npos; | 289 return browser.find("irefox") != std::string::npos; |
259 } | 290 } |
260 | 291 |
261 DefaultWebClientState IsDefaultProtocolClient(const std::string& protocol) { | 292 DefaultWebClientState IsDefaultProtocolClient(const std::string& protocol) { |
262 return GetIsDefaultWebClient(protocol); | 293 return GetDefaultWebClient(protocol); |
263 } | 294 } |
264 | 295 |
265 } // namespace shell_integration | 296 } // namespace shell_integration |
266 | 297 |
267 namespace shell_integration_linux { | 298 namespace shell_integration_linux { |
268 | 299 |
269 namespace { | 300 namespace { |
270 | 301 |
271 #if BUILDFLAG(ENABLE_APP_LIST) | 302 #if BUILDFLAG(ENABLE_APP_LIST) |
272 // The Categories for the App Launcher desktop shortcut. Should be the same as | 303 // The Categories for the App Launcher desktop shortcut. Should be the same as |
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1107 base::FilePath applications_menu = GetDataWriteLocation(env.get()); | 1138 base::FilePath applications_menu = GetDataWriteLocation(env.get()); |
1108 applications_menu = applications_menu.AppendASCII("applications"); | 1139 applications_menu = applications_menu.AppendASCII("applications"); |
1109 std::vector<base::FilePath> shortcut_filenames_app_menu = | 1140 std::vector<base::FilePath> shortcut_filenames_app_menu = |
1110 GetExistingProfileShortcutFilenames(profile_path, applications_menu); | 1141 GetExistingProfileShortcutFilenames(profile_path, applications_menu); |
1111 for (const auto& menu : shortcut_filenames_app_menu) { | 1142 for (const auto& menu : shortcut_filenames_app_menu) { |
1112 DeleteShortcutInApplicationsMenu(menu, base::FilePath(kDirectoryFilename)); | 1143 DeleteShortcutInApplicationsMenu(menu, base::FilePath(kDirectoryFilename)); |
1113 } | 1144 } |
1114 } | 1145 } |
1115 | 1146 |
1116 } // namespace shell_integration_linux | 1147 } // namespace shell_integration_linux |
OLD | NEW |