Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(276)

Side by Side Diff: chrome/browser/shell_integration_linux.cc

Issue 10735048: Revert 146065 - Remove app shortcuts when app is uninstalled on Linux. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/shell_integration_linux.h ('k') | chrome/browser/shell_integration_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 // |shortcut_filename| we'll just undo his action. 147 // |shortcut_filename| we'll just undo his action.
148 unlinkat(desktop_fd, shortcut_filename.value().c_str(), 0); 148 unlinkat(desktop_fd, shortcut_filename.value().c_str(), 0);
149 } 149 }
150 150
151 if (HANDLE_EINTR(close(desktop_fd)) < 0) 151 if (HANDLE_EINTR(close(desktop_fd)) < 0)
152 PLOG(ERROR) << "close"; 152 PLOG(ERROR) << "close";
153 153
154 return true; 154 return true;
155 } 155 }
156 156
157 void DeleteShortcutOnDesktop(const FilePath& shortcut_filename) {
158 FilePath desktop_path;
159 if (PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_path))
160 file_util::Delete(desktop_path.Append(shortcut_filename), false);
161 }
162
163 bool CreateShortcutInApplicationsMenu(const FilePath& shortcut_filename, 157 bool CreateShortcutInApplicationsMenu(const FilePath& shortcut_filename,
164 const std::string& contents) { 158 const std::string& contents) {
165 ScopedTempDir temp_dir; 159 ScopedTempDir temp_dir;
166 if (!temp_dir.CreateUniqueTempDir()) 160 if (!temp_dir.CreateUniqueTempDir())
167 return false; 161 return false;
168 162
169 FilePath temp_file_path = temp_dir.path().Append(shortcut_filename); 163 FilePath temp_file_path = temp_dir.path().Append(shortcut_filename);
170 164
171 int bytes_written = file_util::WriteFile(temp_file_path, contents.data(), 165 int bytes_written = file_util::WriteFile(temp_file_path, contents.data(),
172 contents.length()); 166 contents.length());
173 167
174 if (bytes_written != static_cast<int>(contents.length())) 168 if (bytes_written != static_cast<int>(contents.length()))
175 return false; 169 return false;
176 170
177 std::vector<std::string> argv; 171 std::vector<std::string> argv;
178 argv.push_back("xdg-desktop-menu"); 172 argv.push_back("xdg-desktop-menu");
179 argv.push_back("install"); 173 argv.push_back("install");
180 174
181 // Always install in user mode, even if someone runs the browser as root 175 // Always install in user mode, even if someone runs the browser as root
182 // (people do that). 176 // (people do that).
183 argv.push_back("--mode"); 177 argv.push_back("--mode");
184 argv.push_back("user"); 178 argv.push_back("user");
185 179
186 argv.push_back(temp_file_path.value()); 180 argv.push_back(temp_file_path.value());
187 int exit_code; 181 int exit_code;
188 LaunchXdgUtility(argv, &exit_code); 182 LaunchXdgUtility(argv, &exit_code);
189 return exit_code == 0; 183 return exit_code == 0;
190 } 184 }
191 185
192 void DeleteShortcutInApplicationsMenu(const FilePath& shortcut_filename) {
193 std::vector<std::string> argv;
194 argv.push_back("xdg-desktop-menu");
195 argv.push_back("uninstall");
196
197 // Uninstall in user mode, to match the install.
198 argv.push_back("--mode");
199 argv.push_back("user");
200
201 // The file does not need to exist anywhere - xdg-desktop-menu will uninstall
202 // items from the menu with a matching name.
203 argv.push_back(shortcut_filename.value());
204 int exit_code;
205 LaunchXdgUtility(argv, &exit_code);
206 }
207
208 // Quote a string such that it appears as one verbatim argument for the Exec 186 // Quote a string such that it appears as one verbatim argument for the Exec
209 // key in a desktop file. 187 // key in a desktop file.
210 std::string QuoteArgForDesktopFileExec(const std::string& arg) { 188 std::string QuoteArgForDesktopFileExec(const std::string& arg) {
211 // http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s06.html 189 // http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s06.html
212 190
213 // Quoting is only necessary if the argument has a reserved character. 191 // Quoting is only necessary if the argument has a reserved character.
214 if (arg.find_first_of(" \t\n\"'\\><~|&;$*?#()`") == std::string::npos) 192 if (arg.find_first_of(" \t\n\"'\\><~|&;$*?#()`") == std::string::npos)
215 return arg; // No quoting necessary. 193 return arg; // No quoting necessary.
216 194
217 std::string quoted = "\""; 195 std::string quoted = "\"";
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 if (file_util::PathExists(path)) { 448 if (file_util::PathExists(path)) {
471 VLOG(1) << "Found desktop file template at " << path.value(); 449 VLOG(1) << "Found desktop file template at " << path.value();
472 return file_util::ReadFileToString(path, output); 450 return file_util::ReadFileToString(path, output);
473 } 451 }
474 } 452 }
475 453
476 LOG(ERROR) << "Could not find desktop file template."; 454 LOG(ERROR) << "Could not find desktop file template.";
477 return false; 455 return false;
478 } 456 }
479 457
480 FilePath GetWebShortcutFilename(const GURL& url) { 458 FilePath GetDesktopShortcutFilename(const GURL& url) {
481 // Use a prefix, because xdg-desktop-menu requires it. 459 // Use a prefix, because xdg-desktop-menu requires it.
482 std::string filename = 460 std::string filename =
483 std::string(chrome::kBrowserProcessExecutableName) + "-" + url.spec(); 461 std::string(chrome::kBrowserProcessExecutableName) + "-" + url.spec();
484 file_util::ReplaceIllegalCharactersInPath(&filename, '_'); 462 file_util::ReplaceIllegalCharactersInPath(&filename, '_');
485 463
486 FilePath desktop_path; 464 FilePath desktop_path;
487 if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_path)) 465 if (!PathService::Get(chrome::DIR_USER_DESKTOP, &desktop_path))
488 return FilePath(); 466 return FilePath();
489 467
490 FilePath filepath = desktop_path.Append(filename); 468 FilePath filepath = desktop_path.Append(filename);
491 FilePath alternative_filepath(filepath.value() + ".desktop"); 469 FilePath alternative_filepath(filepath.value() + ".desktop");
492 for (size_t i = 1; i < 100; ++i) { 470 for (size_t i = 1; i < 100; ++i) {
493 if (file_util::PathExists(FilePath(alternative_filepath))) { 471 if (file_util::PathExists(FilePath(alternative_filepath))) {
494 alternative_filepath = FilePath( 472 alternative_filepath = FilePath(
495 filepath.value() + "_" + base::IntToString(i) + ".desktop"); 473 filepath.value() + "_" + base::IntToString(i) + ".desktop");
496 } else { 474 } else {
497 return FilePath(alternative_filepath).BaseName(); 475 return FilePath(alternative_filepath).BaseName();
498 } 476 }
499 } 477 }
500 478
501 return FilePath(); 479 return FilePath();
502 } 480 }
503 481
504 FilePath GetExtensionShortcutFilename(const FilePath& profile_path,
505 const std::string& extension_id) {
506 DCHECK(!extension_id.empty());
507
508 // Use a prefix, because xdg-desktop-menu requires it.
509 std::string filename(chrome::kBrowserProcessExecutableName);
510 filename.append("-")
511 .append(extension_id)
512 .append("-")
513 .append(profile_path.BaseName().value());
514 file_util::ReplaceIllegalCharactersInPath(&filename, '_');
515 return FilePath(filename.append(".desktop"));
516 }
517
518 std::string GetDesktopFileContents( 482 std::string GetDesktopFileContents(
519 const std::string& template_contents, 483 const std::string& template_contents,
520 const std::string& app_name, 484 const std::string& app_name,
521 const GURL& url, 485 const GURL& url,
522 const std::string& extension_id, 486 const std::string& extension_id,
523 const bool is_platform_app, 487 const bool is_platform_app,
524 const FilePath& extension_path, 488 const FilePath& extension_path,
525 const string16& title, 489 const string16& title,
526 const std::string& icon_name, 490 const std::string& icon_name,
527 const FilePath& profile_path) { 491 const FilePath& profile_path) {
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 590
627 g_key_file_free(key_file); 591 g_key_file_free(key_file);
628 return output_buffer; 592 return output_buffer;
629 } 593 }
630 594
631 bool CreateDesktopShortcut( 595 bool CreateDesktopShortcut(
632 const ShellIntegration::ShortcutInfo& shortcut_info, 596 const ShellIntegration::ShortcutInfo& shortcut_info,
633 const std::string& shortcut_template) { 597 const std::string& shortcut_template) {
634 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 598 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
635 599
636 FilePath shortcut_filename; 600 FilePath shortcut_filename =
637 if (!shortcut_info.extension_id.empty()) { 601 ShellIntegrationLinux::GetDesktopShortcutFilename(shortcut_info.url);
638 shortcut_filename = GetExtensionShortcutFilename(
639 shortcut_info.profile_path, shortcut_info.extension_id);
640 // For extensions we do not want duplicate shortcuts. So, delete any that
641 // already exist and replace them.
642 if (shortcut_info.create_on_desktop)
643 DeleteShortcutOnDesktop(shortcut_filename);
644 if (shortcut_info.create_in_applications_menu)
645 DeleteShortcutInApplicationsMenu(shortcut_filename);
646 } else {
647 shortcut_filename = GetWebShortcutFilename(shortcut_info.url);
648 }
649 if (shortcut_filename.empty()) 602 if (shortcut_filename.empty())
650 return false; 603 return false;
651 604
652 std::string icon_name = CreateShortcutIcon(shortcut_info, shortcut_filename); 605 std::string icon_name = CreateShortcutIcon(shortcut_info, shortcut_filename);
653 606
654 std::string app_name = 607 std::string app_name =
655 web_app::GenerateApplicationNameFromInfo(shortcut_info); 608 web_app::GenerateApplicationNameFromInfo(shortcut_info);
656 std::string contents = ShellIntegrationLinux::GetDesktopFileContents( 609 std::string contents = ShellIntegrationLinux::GetDesktopFileContents(
657 shortcut_template, 610 shortcut_template,
658 app_name, 611 app_name,
(...skipping 10 matching lines...) Expand all
669 if (shortcut_info.create_on_desktop) 622 if (shortcut_info.create_on_desktop)
670 success = CreateShortcutOnDesktop(shortcut_filename, contents); 623 success = CreateShortcutOnDesktop(shortcut_filename, contents);
671 624
672 if (shortcut_info.create_in_applications_menu) 625 if (shortcut_info.create_in_applications_menu)
673 success = CreateShortcutInApplicationsMenu(shortcut_filename, contents) && 626 success = CreateShortcutInApplicationsMenu(shortcut_filename, contents) &&
674 success; 627 success;
675 628
676 return success; 629 return success;
677 } 630 }
678 631
679 void DeleteDesktopShortcuts(const FilePath& profile_path,
680 const std::string& extension_id) {
681 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
682
683 FilePath shortcut_filename = GetExtensionShortcutFilename(
684 profile_path, extension_id);
685 DCHECK(!shortcut_filename.empty());
686
687 DeleteShortcutOnDesktop(shortcut_filename);
688 DeleteShortcutInApplicationsMenu(shortcut_filename);
689 }
690
691 } // namespace ShellIntegrationLinux 632 } // namespace ShellIntegrationLinux
OLDNEW
« no previous file with comments | « chrome/browser/shell_integration_linux.h ('k') | chrome/browser/shell_integration_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698