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 <glib.h> | 8 #include <glib.h> |
9 #include <stdlib.h> | 9 #include <stdlib.h> |
10 #include <sys/stat.h> | 10 #include <sys/stat.h> |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 const char kDesktopEntry[] = "Desktop Entry"; | 225 const char kDesktopEntry[] = "Desktop Entry"; |
226 | 226 |
227 const char kXdgOpenShebang[] = "#!/usr/bin/env xdg-open"; | 227 const char kXdgOpenShebang[] = "#!/usr/bin/env xdg-open"; |
228 | 228 |
229 const char kXdgSettings[] = "xdg-settings"; | 229 const char kXdgSettings[] = "xdg-settings"; |
230 const char kXdgSettingsDefaultBrowser[] = "default-web-browser"; | 230 const char kXdgSettingsDefaultBrowser[] = "default-web-browser"; |
231 const char kXdgSettingsDefaultSchemeHandler[] = "default-url-scheme-handler"; | 231 const char kXdgSettingsDefaultSchemeHandler[] = "default-url-scheme-handler"; |
232 | 232 |
233 } // namespace | 233 } // namespace |
234 | 234 |
235 // static | |
236 std::string ShellIntegration::GetDesktopName(base::Environment* env) { | |
237 #if defined(GOOGLE_CHROME_BUILD) | |
238 return "google-chrome.desktop"; | |
239 #else // CHROMIUM_BUILD | |
240 // Allow $CHROME_DESKTOP to override the built-in value, so that development | |
241 // versions can set themselves as the default without interfering with | |
242 // non-official, packaged versions using the built-in value. | |
243 std::string name; | |
244 if (env->GetVar("CHROME_DESKTOP", &name) && !name.empty()) | |
245 return name; | |
246 return "chromium-browser.desktop"; | |
247 #endif | |
248 } | |
249 | |
250 namespace { | 235 namespace { |
251 | 236 |
252 // Utility function to get the path to the version of a script shipped with | 237 // Utility function to get the path to the version of a script shipped with |
253 // Chrome. |script| gives the name of the script. |chrome_version| returns the | 238 // Chrome. |script| gives the name of the script. |chrome_version| returns the |
254 // path to the Chrome version of the script, and the return value of the | 239 // path to the Chrome version of the script, and the return value of the |
255 // function is true if the function is successful and the Chrome version is | 240 // function is true if the function is successful and the Chrome version is |
256 // not the script found on the PATH. | 241 // not the script found on the PATH. |
257 bool GetChromeVersionOfScript(const std::string& script, | 242 bool GetChromeVersionOfScript(const std::string& script, |
258 std::string* chrome_version) { | 243 std::string* chrome_version) { |
259 // Get the path to the Chrome version. | 244 // Get the path to the Chrome version. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 | 285 |
301 std::vector<std::string> argv; | 286 std::vector<std::string> argv; |
302 argv.push_back(kXdgSettings); | 287 argv.push_back(kXdgSettings); |
303 argv.push_back("set"); | 288 argv.push_back("set"); |
304 if (protocol.empty()) { | 289 if (protocol.empty()) { |
305 argv.push_back(kXdgSettingsDefaultBrowser); | 290 argv.push_back(kXdgSettingsDefaultBrowser); |
306 } else { | 291 } else { |
307 argv.push_back(kXdgSettingsDefaultSchemeHandler); | 292 argv.push_back(kXdgSettingsDefaultSchemeHandler); |
308 argv.push_back(protocol); | 293 argv.push_back(protocol); |
309 } | 294 } |
310 argv.push_back(ShellIntegration::GetDesktopName(env.get())); | 295 argv.push_back(ShellIntegrationLinux::GetDesktopName(env.get())); |
311 | 296 |
312 int exit_code; | 297 int exit_code; |
313 bool ran_ok = LaunchXdgUtility(argv, &exit_code); | 298 bool ran_ok = LaunchXdgUtility(argv, &exit_code); |
314 if (ran_ok && exit_code == EXIT_XDG_SETTINGS_SYNTAX_ERROR) { | 299 if (ran_ok && exit_code == EXIT_XDG_SETTINGS_SYNTAX_ERROR) { |
315 if (GetChromeVersionOfScript(kXdgSettings, &argv[0])) { | 300 if (GetChromeVersionOfScript(kXdgSettings, &argv[0])) { |
316 ran_ok = LaunchXdgUtility(argv, &exit_code); | 301 ran_ok = LaunchXdgUtility(argv, &exit_code); |
317 } | 302 } |
318 } | 303 } |
319 | 304 |
320 return ran_ok && exit_code == EXIT_SUCCESS; | 305 return ran_ok && exit_code == EXIT_SUCCESS; |
(...skipping 10 matching lines...) Expand all Loading... |
331 | 316 |
332 std::vector<std::string> argv; | 317 std::vector<std::string> argv; |
333 argv.push_back(kXdgSettings); | 318 argv.push_back(kXdgSettings); |
334 argv.push_back("check"); | 319 argv.push_back("check"); |
335 if (protocol.empty()) { | 320 if (protocol.empty()) { |
336 argv.push_back(kXdgSettingsDefaultBrowser); | 321 argv.push_back(kXdgSettingsDefaultBrowser); |
337 } else { | 322 } else { |
338 argv.push_back(kXdgSettingsDefaultSchemeHandler); | 323 argv.push_back(kXdgSettingsDefaultSchemeHandler); |
339 argv.push_back(protocol); | 324 argv.push_back(protocol); |
340 } | 325 } |
341 argv.push_back(ShellIntegration::GetDesktopName(env.get())); | 326 argv.push_back(ShellIntegrationLinux::GetDesktopName(env.get())); |
342 | 327 |
343 std::string reply; | 328 std::string reply; |
344 int success_code; | 329 int success_code; |
345 bool ran_ok = base::GetAppOutputWithExitCode(CommandLine(argv), &reply, | 330 bool ran_ok = base::GetAppOutputWithExitCode(CommandLine(argv), &reply, |
346 &success_code); | 331 &success_code); |
347 if (ran_ok && success_code == EXIT_XDG_SETTINGS_SYNTAX_ERROR) { | 332 if (ran_ok && success_code == EXIT_XDG_SETTINGS_SYNTAX_ERROR) { |
348 if (GetChromeVersionOfScript(kXdgSettings, &argv[0])) { | 333 if (GetChromeVersionOfScript(kXdgSettings, &argv[0])) { |
349 ran_ok = base::GetAppOutputWithExitCode(CommandLine(argv), &reply, | 334 ran_ok = base::GetAppOutputWithExitCode(CommandLine(argv), &reply, |
350 &success_code); | 335 &success_code); |
351 } | 336 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 argv.push_back(kXdgSettings); | 380 argv.push_back(kXdgSettings); |
396 argv.push_back("get"); | 381 argv.push_back("get"); |
397 argv.push_back(kXdgSettingsDefaultBrowser); | 382 argv.push_back(kXdgSettingsDefaultBrowser); |
398 | 383 |
399 std::string browser; | 384 std::string browser; |
400 // We don't care about the return value here. | 385 // We don't care about the return value here. |
401 base::GetAppOutput(CommandLine(argv), &browser); | 386 base::GetAppOutput(CommandLine(argv), &browser); |
402 return browser.find("irefox") != std::string::npos; | 387 return browser.find("irefox") != std::string::npos; |
403 } | 388 } |
404 | 389 |
405 // static | 390 namespace ShellIntegrationLinux { |
406 bool ShellIntegration::GetDesktopShortcutTemplate( | 391 |
407 base::Environment* env, std::string* output) { | 392 std::string GetDesktopName(base::Environment* env) { |
| 393 #if defined(GOOGLE_CHROME_BUILD) |
| 394 return "google-chrome.desktop"; |
| 395 #else // CHROMIUM_BUILD |
| 396 // Allow $CHROME_DESKTOP to override the built-in value, so that development |
| 397 // versions can set themselves as the default without interfering with |
| 398 // non-official, packaged versions using the built-in value. |
| 399 std::string name; |
| 400 if (env->GetVar("CHROME_DESKTOP", &name) && !name.empty()) |
| 401 return name; |
| 402 return "chromium-browser.desktop"; |
| 403 #endif |
| 404 } |
| 405 |
| 406 bool GetDesktopShortcutTemplate(base::Environment* env, |
| 407 std::string* output) { |
408 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 408 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
409 | 409 |
410 std::vector<FilePath> search_paths; | 410 std::vector<FilePath> search_paths; |
411 | 411 |
412 std::string xdg_data_home; | 412 std::string xdg_data_home; |
413 if (env->GetVar("XDG_DATA_HOME", &xdg_data_home) && | 413 if (env->GetVar("XDG_DATA_HOME", &xdg_data_home) && |
414 !xdg_data_home.empty()) { | 414 !xdg_data_home.empty()) { |
415 search_paths.push_back(FilePath(xdg_data_home)); | 415 search_paths.push_back(FilePath(xdg_data_home)); |
416 } | 416 } |
417 | 417 |
(...skipping 21 matching lines...) Expand all Loading... |
439 if (file_util::PathExists(path)) { | 439 if (file_util::PathExists(path)) { |
440 VLOG(1) << "Found desktop file template at " << path.value(); | 440 VLOG(1) << "Found desktop file template at " << path.value(); |
441 return file_util::ReadFileToString(path, output); | 441 return file_util::ReadFileToString(path, output); |
442 } | 442 } |
443 } | 443 } |
444 | 444 |
445 LOG(ERROR) << "Could not find desktop file template."; | 445 LOG(ERROR) << "Could not find desktop file template."; |
446 return false; | 446 return false; |
447 } | 447 } |
448 | 448 |
449 // static | 449 FilePath GetDesktopShortcutFilename(const GURL& url) { |
450 FilePath ShellIntegration::GetDesktopShortcutFilename(const GURL& url) { | |
451 // Use a prefix, because xdg-desktop-menu requires it. | 450 // Use a prefix, because xdg-desktop-menu requires it. |
452 std::string filename = | 451 std::string filename = |
453 std::string(chrome::kBrowserProcessExecutableName) + "-" + url.spec(); | 452 std::string(chrome::kBrowserProcessExecutableName) + "-" + url.spec(); |
454 file_util::ReplaceIllegalCharactersInPath(&filename, '_'); | 453 file_util::ReplaceIllegalCharactersInPath(&filename, '_'); |
455 | 454 |
456 FilePath desktop_path; | 455 FilePath desktop_path; |
457 if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_path)) | 456 if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_path)) |
458 return FilePath(); | 457 return FilePath(); |
459 | 458 |
460 FilePath filepath = desktop_path.Append(filename); | 459 FilePath filepath = desktop_path.Append(filename); |
461 FilePath alternative_filepath(filepath.value() + ".desktop"); | 460 FilePath alternative_filepath(filepath.value() + ".desktop"); |
462 for (size_t i = 1; i < 100; ++i) { | 461 for (size_t i = 1; i < 100; ++i) { |
463 if (file_util::PathExists(FilePath(alternative_filepath))) { | 462 if (file_util::PathExists(FilePath(alternative_filepath))) { |
464 alternative_filepath = FilePath( | 463 alternative_filepath = FilePath( |
465 filepath.value() + "_" + base::IntToString(i) + ".desktop"); | 464 filepath.value() + "_" + base::IntToString(i) + ".desktop"); |
466 } else { | 465 } else { |
467 return FilePath(alternative_filepath).BaseName(); | 466 return FilePath(alternative_filepath).BaseName(); |
468 } | 467 } |
469 } | 468 } |
470 | 469 |
471 return FilePath(); | 470 return FilePath(); |
472 } | 471 } |
473 | 472 |
474 // static | 473 std::string GetDesktopFileContents( |
475 std::string ShellIntegration::GetDesktopFileContents( | |
476 const std::string& template_contents, | 474 const std::string& template_contents, |
477 const std::string& app_name, | 475 const std::string& app_name, |
478 const GURL& url, | 476 const GURL& url, |
479 const std::string& extension_id, | 477 const std::string& extension_id, |
480 const bool is_platform_app, | 478 const bool is_platform_app, |
481 const FilePath& web_app_path, | 479 const FilePath& web_app_path, |
482 const FilePath& extension_path, | 480 const FilePath& extension_path, |
483 const string16& title, | 481 const string16& title, |
484 const std::string& icon_name) { | 482 const std::string& icon_name) { |
485 if (template_contents.empty()) | 483 if (template_contents.empty()) |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 gchar* data_dump = g_key_file_to_data(key_file, &length, NULL); | 581 gchar* data_dump = g_key_file_to_data(key_file, &length, NULL); |
584 if (data_dump) { | 582 if (data_dump) { |
585 output_buffer += data_dump; | 583 output_buffer += data_dump; |
586 g_free(data_dump); | 584 g_free(data_dump); |
587 } | 585 } |
588 | 586 |
589 g_key_file_free(key_file); | 587 g_key_file_free(key_file); |
590 return output_buffer; | 588 return output_buffer; |
591 } | 589 } |
592 | 590 |
593 // static | 591 bool CreateDesktopShortcut( |
594 bool ShellIntegration::CreateDesktopShortcut( | 592 const ShellIntegration::ShortcutInfo& shortcut_info, |
595 const ShortcutInfo& shortcut_info, | |
596 const std::string& shortcut_template) { | 593 const std::string& shortcut_template) { |
597 DCHECK(!shortcut_info.is_platform_app); | 594 DCHECK(!shortcut_info.is_platform_app); |
598 DCHECK(shortcut_info.extension_id.empty()); | 595 DCHECK(shortcut_info.extension_id.empty()); |
599 | 596 |
600 return ShellIntegrationLinux::CreateDesktopShortcutForChromeApp( | 597 return ShellIntegrationLinux::CreateDesktopShortcutForChromeApp( |
601 shortcut_info, FilePath(), shortcut_template); | 598 shortcut_info, FilePath(), shortcut_template); |
602 } | 599 } |
603 | 600 |
604 namespace ShellIntegrationLinux { | |
605 | |
606 bool CreateDesktopShortcutForChromeApp( | 601 bool CreateDesktopShortcutForChromeApp( |
607 const ShellIntegration::ShortcutInfo& shortcut_info, | 602 const ShellIntegration::ShortcutInfo& shortcut_info, |
608 const FilePath& web_app_path, | 603 const FilePath& web_app_path, |
609 const std::string& shortcut_template) { | 604 const std::string& shortcut_template) { |
610 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 605 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
611 | 606 |
612 FilePath shortcut_filename = ShellIntegration::GetDesktopShortcutFilename( | 607 FilePath shortcut_filename = |
613 shortcut_info.url); | 608 ShellIntegrationLinux::GetDesktopShortcutFilename(shortcut_info.url); |
614 if (shortcut_filename.empty()) | 609 if (shortcut_filename.empty()) |
615 return false; | 610 return false; |
616 | 611 |
617 std::string icon_name = CreateShortcutIcon(shortcut_info, shortcut_filename); | 612 std::string icon_name =CreateShortcutIcon(shortcut_info, shortcut_filename); |
618 | 613 |
619 std::string app_name = | 614 std::string app_name = |
620 web_app::GenerateApplicationNameFromInfo(shortcut_info); | 615 web_app::GenerateApplicationNameFromInfo(shortcut_info); |
621 std::string contents = ShellIntegration::GetDesktopFileContents( | 616 std::string contents = ShellIntegrationLinux::GetDesktopFileContents( |
622 shortcut_template, | 617 shortcut_template, |
623 app_name, | 618 app_name, |
624 shortcut_info.url, | 619 shortcut_info.url, |
625 shortcut_info.extension_id, | 620 shortcut_info.extension_id, |
626 shortcut_info.is_platform_app, | 621 shortcut_info.is_platform_app, |
627 web_app_path, | 622 web_app_path, |
628 shortcut_info.extension_path, | 623 shortcut_info.extension_path, |
629 shortcut_info.title, | 624 shortcut_info.title, |
630 icon_name); | 625 icon_name); |
631 | 626 |
632 bool success = true; | 627 bool success = true; |
633 | 628 |
634 if (shortcut_info.create_on_desktop) | 629 if (shortcut_info.create_on_desktop) |
635 success = CreateShortcutOnDesktop(shortcut_filename, contents); | 630 success = CreateShortcutOnDesktop(shortcut_filename, contents); |
636 | 631 |
637 if (shortcut_info.create_in_applications_menu) | 632 if (shortcut_info.create_in_applications_menu) |
638 success = CreateShortcutInApplicationsMenu(shortcut_filename, contents) && | 633 success = CreateShortcutInApplicationsMenu(shortcut_filename, contents) && |
639 success; | 634 success; |
640 | 635 |
641 return success; | 636 return success; |
642 } | 637 } |
643 | 638 |
644 } // namespace ShellIntegrationLinux | 639 } // namespace ShellIntegrationLinux |
OLD | NEW |