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> |
11 #include <sys/types.h> | 11 #include <sys/types.h> |
12 #include <unistd.h> | 12 #include <unistd.h> |
13 | 13 |
14 #include <string> | 14 #include <string> |
15 #include <vector> | 15 #include <vector> |
16 | 16 |
17 #include "base/base_paths.h" | 17 #include "base/base_paths.h" |
18 #include "base/command_line.h" | 18 #include "base/command_line.h" |
19 #include "base/environment.h" | 19 #include "base/environment.h" |
20 #include "base/file_util.h" | 20 #include "base/file_util.h" |
21 #include "base/files/file_path.h" | 21 #include "base/files/file_path.h" |
22 #include "base/files/scoped_temp_dir.h" | 22 #include "base/files/scoped_temp_dir.h" |
23 #include "base/i18n/file_util_icu.h" | 23 #include "base/i18n/file_util_icu.h" |
| 24 #include "base/memory/ref_counted_memory.h" |
| 25 #include "base/memory/scoped_ptr.h" |
24 #include "base/message_loop.h" | 26 #include "base/message_loop.h" |
25 #include "base/path_service.h" | 27 #include "base/path_service.h" |
26 #include "base/posix/eintr_wrapper.h" | 28 #include "base/posix/eintr_wrapper.h" |
27 #include "base/process_util.h" | 29 #include "base/process_util.h" |
28 #include "base/strings/string_number_conversions.h" | 30 #include "base/strings/string_number_conversions.h" |
29 #include "base/strings/string_tokenizer.h" | 31 #include "base/strings/string_tokenizer.h" |
30 #include "base/threading/thread.h" | 32 #include "base/threading/thread.h" |
31 #include "base/threading/thread_restrictions.h" | 33 #include "base/threading/thread_restrictions.h" |
32 #include "base/utf_string_conversions.h" | 34 #include "base/utf_string_conversions.h" |
33 #include "build/build_config.h" | 35 #include "build/build_config.h" |
34 #include "chrome/browser/web_applications/web_app.h" | 36 #include "chrome/browser/web_applications/web_app.h" |
35 #include "chrome/common/chrome_constants.h" | 37 #include "chrome/common/chrome_constants.h" |
36 #include "content/public/browser/browser_thread.h" | 38 #include "content/public/browser/browser_thread.h" |
37 #include "googleurl/src/gurl.h" | 39 #include "googleurl/src/gurl.h" |
38 #include "ui/gfx/codec/png_codec.h" | 40 #include "ui/gfx/image/image_family.h" |
39 #include "ui/gfx/image/image_skia.h" | |
40 #include "ui/gfx/image/image_skia_rep.h" | |
41 | 41 |
42 using content::BrowserThread; | 42 using content::BrowserThread; |
43 | 43 |
44 namespace { | 44 namespace { |
45 | 45 |
46 // Helper to launch xdg scripts. We don't want them to ask any questions on the | 46 // Helper to launch xdg scripts. We don't want them to ask any questions on the |
47 // terminal etc. The function returns true if the utility launches and exits | 47 // terminal etc. The function returns true if the utility launches and exits |
48 // cleanly, in which case |exit_code| returns the utility's exit code. | 48 // cleanly, in which case |exit_code| returns the utility's exit code. |
49 bool LaunchXdgUtility(const std::vector<std::string>& argv, int* exit_code) { | 49 bool LaunchXdgUtility(const std::vector<std::string>& argv, int* exit_code) { |
50 // xdg-settings internally runs xdg-mime, which uses mv to move newly-created | 50 // xdg-settings internally runs xdg-mime, which uses mv to move newly-created |
(...skipping 17 matching lines...) Expand all Loading... |
68 return false; | 68 return false; |
69 } | 69 } |
70 close(devnull); | 70 close(devnull); |
71 | 71 |
72 return base::WaitForExitCode(handle, exit_code); | 72 return base::WaitForExitCode(handle, exit_code); |
73 } | 73 } |
74 | 74 |
75 std::string CreateShortcutIcon( | 75 std::string CreateShortcutIcon( |
76 const ShellIntegration::ShortcutInfo& shortcut_info, | 76 const ShellIntegration::ShortcutInfo& shortcut_info, |
77 const base::FilePath& shortcut_filename) { | 77 const base::FilePath& shortcut_filename) { |
78 if (shortcut_info.favicon.IsEmpty()) | 78 if (shortcut_info.favicon.empty()) |
79 return std::string(); | 79 return std::string(); |
80 | 80 |
81 // TODO(phajdan.jr): Report errors from this function, possibly as infobars. | 81 // TODO(phajdan.jr): Report errors from this function, possibly as infobars. |
82 base::ScopedTempDir temp_dir; | 82 base::ScopedTempDir temp_dir; |
83 if (!temp_dir.CreateUniqueTempDir()) | 83 if (!temp_dir.CreateUniqueTempDir()) |
84 return std::string(); | 84 return std::string(); |
85 | 85 |
86 base::FilePath temp_file_path = temp_dir.path().Append( | 86 base::FilePath temp_file_path = temp_dir.path().Append( |
87 shortcut_filename.ReplaceExtension("png")); | 87 shortcut_filename.ReplaceExtension("png")); |
88 std::string icon_name = temp_file_path.BaseName().RemoveExtension().value(); | 88 std::string icon_name = temp_file_path.BaseName().RemoveExtension().value(); |
89 | 89 |
90 std::vector<gfx::ImageSkiaRep> image_reps = | 90 for (gfx::ImageFamily::const_iterator it = shortcut_info.favicon.begin(); |
91 shortcut_info.favicon.ToImageSkia()->image_reps(); | 91 it != shortcut_info.favicon.end(); ++it) { |
92 for (std::vector<gfx::ImageSkiaRep>::const_iterator it = image_reps.begin(); | 92 int width = it->Width(); |
93 it != image_reps.end(); ++it) { | 93 scoped_refptr<base::RefCountedMemory> png_data = it->As1xPNGBytes(); |
94 std::vector<unsigned char> png_data; | 94 if (png_data->size() == 0) { |
95 const SkBitmap& bitmap = it->sk_bitmap(); | |
96 if (!gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &png_data)) { | |
97 // If the bitmap could not be encoded to PNG format, skip it. | 95 // If the bitmap could not be encoded to PNG format, skip it. |
98 LOG(WARNING) << "Could not encode icon " << icon_name << ".png at size " | 96 LOG(WARNING) << "Could not encode icon " << icon_name << ".png at size " |
99 << bitmap.width() << "."; | 97 << width << "."; |
100 continue; | 98 continue; |
101 } | 99 } |
102 int bytes_written = file_util::WriteFile(temp_file_path, | 100 int bytes_written = file_util::WriteFile(temp_file_path, |
103 reinterpret_cast<char*>(png_data.data()), png_data.size()); | 101 reinterpret_cast<const char*>(png_data->front()), png_data->size()); |
104 | 102 |
105 if (bytes_written != static_cast<int>(png_data.size())) | 103 if (bytes_written != static_cast<int>(png_data->size())) |
106 return std::string(); | 104 return std::string(); |
107 | 105 |
108 std::vector<std::string> argv; | 106 std::vector<std::string> argv; |
109 argv.push_back("xdg-icon-resource"); | 107 argv.push_back("xdg-icon-resource"); |
110 argv.push_back("install"); | 108 argv.push_back("install"); |
111 | 109 |
112 // Always install in user mode, even if someone runs the browser as root | 110 // Always install in user mode, even if someone runs the browser as root |
113 // (people do that). | 111 // (people do that). |
114 argv.push_back("--mode"); | 112 argv.push_back("--mode"); |
115 argv.push_back("user"); | 113 argv.push_back("user"); |
116 | 114 |
117 argv.push_back("--size"); | 115 argv.push_back("--size"); |
118 argv.push_back(base::IntToString(bitmap.width())); | 116 argv.push_back(base::IntToString(width)); |
119 | 117 |
120 argv.push_back(temp_file_path.value()); | 118 argv.push_back(temp_file_path.value()); |
121 argv.push_back(icon_name); | 119 argv.push_back(icon_name); |
122 int exit_code; | 120 int exit_code; |
123 if (!LaunchXdgUtility(argv, &exit_code) || exit_code) { | 121 if (!LaunchXdgUtility(argv, &exit_code) || exit_code) { |
124 LOG(WARNING) << "Could not install icon " << icon_name << ".png at size " | 122 LOG(WARNING) << "Could not install icon " << icon_name << ".png at size " |
125 << bitmap.width() << "."; | 123 << width << "."; |
126 } | 124 } |
127 } | 125 } |
128 return icon_name; | 126 return icon_name; |
129 } | 127 } |
130 | 128 |
131 bool CreateShortcutOnDesktop(const base::FilePath& shortcut_filename, | 129 bool CreateShortcutOnDesktop(const base::FilePath& shortcut_filename, |
132 const std::string& contents) { | 130 const std::string& contents) { |
133 // Make sure that we will later call openat in a secure way. | 131 // Make sure that we will later call openat in a secure way. |
134 DCHECK_EQ(shortcut_filename.BaseName().value(), shortcut_filename.value()); | 132 DCHECK_EQ(shortcut_filename.BaseName().value(), shortcut_filename.value()); |
135 | 133 |
(...skipping 703 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 | 837 |
840 base::FilePath shortcut_filename = GetExtensionShortcutFilename( | 838 base::FilePath shortcut_filename = GetExtensionShortcutFilename( |
841 profile_path, extension_id); | 839 profile_path, extension_id); |
842 DCHECK(!shortcut_filename.empty()); | 840 DCHECK(!shortcut_filename.empty()); |
843 | 841 |
844 DeleteShortcutOnDesktop(shortcut_filename); | 842 DeleteShortcutOnDesktop(shortcut_filename); |
845 DeleteShortcutInApplicationsMenu(shortcut_filename); | 843 DeleteShortcutInApplicationsMenu(shortcut_filename); |
846 } | 844 } |
847 | 845 |
848 } // namespace ShellIntegrationLinux | 846 } // namespace ShellIntegrationLinux |
OLD | NEW |