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

Side by Side Diff: chrome/browser/ui/webui/favicon_source.cc

Issue 11787015: Allow the password manager in the settings page to have hidpi favicons too (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 7 years, 11 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/ui/webui/favicon_source.h ('k') | no next file » | 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/ui/webui/favicon_source.h" 5 #include "chrome/browser/ui/webui/favicon_source.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/string_number_conversions.h"
9 #include "chrome/browser/favicon/favicon_service_factory.h" 10 #include "chrome/browser/favicon/favicon_service_factory.h"
10 #include "chrome/browser/history/top_sites.h" 11 #include "chrome/browser/history/top_sites.h"
11 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/webui/web_ui_util.h" 13 #include "chrome/browser/ui/webui/web_ui_util.h"
13 #include "chrome/common/url_constants.h" 14 #include "chrome/common/url_constants.h"
14 #include "grit/locale_settings.h" 15 #include "grit/locale_settings.h"
15 #include "grit/ui_resources.h" 16 #include "grit/ui_resources.h"
16 #include "ui/base/l10n/l10n_util.h" 17 #include "ui/base/l10n/l10n_util.h"
17 #include "ui/base/layout.h" 18 #include "ui/base/layout.h"
18 #include "ui/base/resource/resource_bundle.h" 19 #include "ui/base/resource/resource_bundle.h"
19 20
21 namespace {
22
23 // Parameters which can be used in chrome://favicon path. See .h file for a
24 // description of what each does.
25 const char kSizeParameter[] = "size/";
26 const char kIconURLParameter[] = "iconurl/";
27 const char kOriginParameter[] = "origin/";
28
29 // Returns true if |search| is a substring of |path| which starts at
30 // |start_index|.
31 bool HasSubstringAt(const std::string& path,
32 size_t start_index,
33 const std::string& search) {
34 if (search.empty())
35 return false;
36
37 if (start_index + search.size() >= path.size())
38 return false;
39
40 return (path.compare(start_index, search.size(), search) == 0);
41 }
42
43 } // namespace
44
20 FaviconSource::IconRequest::IconRequest() 45 FaviconSource::IconRequest::IconRequest()
21 : size_in_dip(gfx::kFaviconSize), 46 : size_in_dip(gfx::kFaviconSize),
22 scale_factor(ui::SCALE_FACTOR_NONE) { 47 scale_factor(ui::SCALE_FACTOR_NONE) {
23 } 48 }
24 49
25 FaviconSource::IconRequest::IconRequest( 50 FaviconSource::IconRequest::IconRequest(
26 const content::URLDataSource::GotDataCallback& cb, 51 const content::URLDataSource::GotDataCallback& cb,
27 const std::string& path, 52 const std::string& path,
28 int size, 53 int size,
29 ui::ScaleFactor scale) 54 ui::ScaleFactor scale)
(...skipping 21 matching lines...) Expand all
51 chrome::kChromeUIFaviconHost : chrome::kChromeUITouchIconHost; 76 chrome::kChromeUIFaviconHost : chrome::kChromeUITouchIconHost;
52 } 77 }
53 78
54 void FaviconSource::StartDataRequest( 79 void FaviconSource::StartDataRequest(
55 const std::string& path, 80 const std::string& path,
56 bool is_incognito, 81 bool is_incognito,
57 const content::URLDataSource::GotDataCallback& callback) { 82 const content::URLDataSource::GotDataCallback& callback) {
58 FaviconService* favicon_service = 83 FaviconService* favicon_service =
59 FaviconServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); 84 FaviconServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS);
60 if (!favicon_service || path.empty()) { 85 if (!favicon_service || path.empty()) {
61 SendDefaultResponse(IconRequest(callback, 86 SendDefaultResponse(callback);
62 "",
63 16,
64 ui::SCALE_FACTOR_100P));
65 return; 87 return;
66 } 88 }
67 89
68 int size_in_dip = gfx::kFaviconSize; 90 DCHECK_EQ(16, gfx::kFaviconSize);
91 int size_in_dip = 16;
69 ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_100P; 92 ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_100P;
70 93
71 if (path.size() > 8 && 94 size_t parsed_index = 0;
72 (path.substr(0, 8) == "iconurl/" || path.substr(0, 8) == "iconurl@")) { 95 if (HasSubstringAt(path, parsed_index, kSizeParameter)) {
73 size_t prefix_length = 8; 96 parsed_index += strlen(kSizeParameter);
74 // Optional scale factor appended to iconurl, which may be @1x or @2x. 97
75 if (path.at(7) == '@') { 98 size_t scale_delimiter = path.find("@", parsed_index);
76 size_t slash = path.find("/"); 99 if (scale_delimiter == std::string::npos) {
77 std::string scale_str = path.substr(8, slash - 8); 100 SendDefaultResponse(callback);
78 web_ui_util::ParseScaleFactor(scale_str, &scale_factor); 101 return;
79 prefix_length = slash + 1;
80 } 102 }
103
104 std::string size = path.substr(parsed_index,
105 scale_delimiter - parsed_index);
106 if (!base::StringToInt(size, &size_in_dip)) {
107 SendDefaultResponse(callback);
108 return;
109 }
110
111 if (size_in_dip != 64 && size_in_dip != 32) {
112 // Only 64x64, 32x32 and 16x16 icons are supported.
113 size_in_dip = 16;
114 }
115
116 size_t slash = path.find("/", scale_delimiter);
117 if (slash == std::string::npos) {
118 SendDefaultResponse(callback);
119 return;
120 }
121
122 std::string scale_str = path.substr(scale_delimiter + 1,
123 slash - scale_delimiter - 1);
124 web_ui_util::ParseScaleFactor(scale_str, &scale_factor);
125
126 if (scale_factor != ui::SCALE_FACTOR_100P && size_in_dip != 16) {
127 SendDefaultResponse(callback);
128 return;
129 }
130
131 parsed_index = slash + 1;
132 }
133
134 if (HasSubstringAt(path, parsed_index, kIconURLParameter)) {
135 parsed_index += strlen(kIconURLParameter);
81 // TODO(michaelbai): Change GetRawFavicon to support combination of 136 // TODO(michaelbai): Change GetRawFavicon to support combination of
82 // IconType. 137 // IconType.
83 favicon_service->GetRawFavicon( 138 favicon_service->GetRawFavicon(
84 GURL(path.substr(prefix_length)), 139 GURL(path.substr(parsed_index)),
85 history::FAVICON, 140 history::FAVICON,
86 size_in_dip, 141 size_in_dip,
87 scale_factor, 142 scale_factor,
88 base::Bind(&FaviconSource::OnFaviconDataAvailable, 143 base::Bind(&FaviconSource::OnFaviconDataAvailable,
89 base::Unretained(this), 144 base::Unretained(this),
90 IconRequest(callback, 145 IconRequest(callback,
91 path.substr(prefix_length), 146 path.substr(parsed_index),
92 size_in_dip, 147 size_in_dip,
93 scale_factor)), 148 scale_factor)),
94 &cancelable_task_tracker_); 149 &cancelable_task_tracker_);
95 } else { 150 } else {
96 GURL url; 151 std::string url;
97 if (path.size() > 5 && path.substr(0, 5) == "size/") { 152
98 size_t slash = path.find("/", 5); 153 // URL requests prefixed with "origin/" are converted to a form with an
99 size_t scale_delimiter = path.find("@", 5); 154 // empty path and a valid scheme. (e.g., example.com -->
100 std::string size = path.substr(5, slash - 5); 155 // http://example.com/ or http://example.com/a --> http://example.com/)
101 size_in_dip = atoi(size.c_str()); 156 if (HasSubstringAt(path, parsed_index, kOriginParameter)) {
102 if (size_in_dip != 64 && size_in_dip != 32 && size_in_dip != 16) { 157 parsed_index += strlen(kOriginParameter);
103 // Only 64x64, 32x32 and 16x16 icons are supported. 158 url = path.substr(parsed_index);
104 size_in_dip = 16; 159
105 } 160 // If the URL does not specify a scheme (e.g., example.com instead of
106 // Optional scale factor. 161 // http://example.com), add "http://" as a default.
107 if (scale_delimiter != std::string::npos && scale_delimiter < slash) { 162 if (!GURL(url).has_scheme())
108 DCHECK(size_in_dip == 16); 163 url = "http://" + url;
109 std::string scale_str = path.substr(scale_delimiter + 1, 164
110 slash - scale_delimiter - 1); 165 // Strip the path beyond the top-level domain.
111 web_ui_util::ParseScaleFactor(scale_str, &scale_factor); 166 url = GURL(url).GetOrigin().spec();
112 }
113 url = GURL(path.substr(slash + 1));
114 } else { 167 } else {
115 // URL requests prefixed with "origin/" are converted to a form with an 168 url = path.substr(parsed_index);
116 // empty path and a valid scheme. (e.g., example.com -->
117 // http://example.com/ or http://example.com/a --> http://example.com/)
118 if (path.size() > 7 && path.substr(0, 7) == "origin/") {
119 std::string originalUrl = path.substr(7);
120
121 // If the original URL does not specify a scheme (e.g., example.com
122 // instead of http://example.com), add "http://" as a default.
123 if (!GURL(originalUrl).has_scheme())
124 originalUrl = "http://" + originalUrl;
125
126 // Strip the path beyond the top-level domain.
127 url = GURL(originalUrl).GetOrigin();
128 } else {
129 url = GURL(path);
130 }
131 } 169 }
132 170
133 // Intercept requests for prepopulated pages. 171 // Intercept requests for prepopulated pages.
134 for (size_t i = 0; i < arraysize(history::kPrepopulatedPages); i++) { 172 for (size_t i = 0; i < arraysize(history::kPrepopulatedPages); i++) {
135 if (url.spec() == 173 if (url ==
136 l10n_util::GetStringUTF8(history::kPrepopulatedPages[i].url_id)) { 174 l10n_util::GetStringUTF8(history::kPrepopulatedPages[i].url_id)) {
137 callback.Run( 175 callback.Run(
138 ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale( 176 ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale(
139 history::kPrepopulatedPages[i].favicon_id, 177 history::kPrepopulatedPages[i].favicon_id,
140 scale_factor)); 178 scale_factor));
141 return; 179 return;
142 } 180 }
143 } 181 }
144 182
145 favicon_service->GetRawFaviconForURL( 183 favicon_service->GetRawFaviconForURL(
146 FaviconService::FaviconForURLParams( 184 FaviconService::FaviconForURLParams(
147 profile_, url, icon_types_, size_in_dip), 185 profile_, GURL(url), icon_types_, size_in_dip),
148 scale_factor, 186 scale_factor,
149 base::Bind(&FaviconSource::OnFaviconDataAvailable, 187 base::Bind(&FaviconSource::OnFaviconDataAvailable,
150 base::Unretained(this), 188 base::Unretained(this),
151 IconRequest(callback, 189 IconRequest(callback,
152 url.spec(), 190 url,
153 size_in_dip, 191 size_in_dip,
154 scale_factor)), 192 scale_factor)),
155 &cancelable_task_tracker_); 193 &cancelable_task_tracker_);
156 } 194 }
157 } 195 }
158 196
159 std::string FaviconSource::GetMimeType(const std::string&) const { 197 std::string FaviconSource::GetMimeType(const std::string&) const {
160 // We need to explicitly return a mime type, otherwise if the user tries to 198 // We need to explicitly return a mime type, otherwise if the user tries to
161 // drag the image they get no extension. 199 // drag the image they get no extension.
162 return "image/png"; 200 return "image/png";
(...skipping 15 matching lines...) Expand all
178 const IconRequest& request, 216 const IconRequest& request,
179 const history::FaviconBitmapResult& bitmap_result) { 217 const history::FaviconBitmapResult& bitmap_result) {
180 if (bitmap_result.is_valid()) { 218 if (bitmap_result.is_valid()) {
181 // Forward the data along to the networking system. 219 // Forward the data along to the networking system.
182 request.callback.Run(bitmap_result.bitmap_data); 220 request.callback.Run(bitmap_result.bitmap_data);
183 } else if (!HandleMissingResource(request)) { 221 } else if (!HandleMissingResource(request)) {
184 SendDefaultResponse(request); 222 SendDefaultResponse(request);
185 } 223 }
186 } 224 }
187 225
226 void FaviconSource::SendDefaultResponse(
227 const content::URLDataSource::GotDataCallback& callback) {
228 SendDefaultResponse(IconRequest(callback,
229 "",
230 16,
231 ui::SCALE_FACTOR_100P));
232 }
233
188 void FaviconSource::SendDefaultResponse(const IconRequest& icon_request) { 234 void FaviconSource::SendDefaultResponse(const IconRequest& icon_request) {
189 int favicon_index; 235 int favicon_index;
190 int resource_id; 236 int resource_id;
191 switch (icon_request.size_in_dip) { 237 switch (icon_request.size_in_dip) {
192 case 64: 238 case 64:
193 favicon_index = SIZE_64; 239 favicon_index = SIZE_64;
194 resource_id = IDR_DEFAULT_FAVICON_64; 240 resource_id = IDR_DEFAULT_FAVICON_64;
195 break; 241 break;
196 case 32: 242 case 32:
197 favicon_index = SIZE_32; 243 favicon_index = SIZE_32;
198 resource_id = IDR_DEFAULT_FAVICON_32; 244 resource_id = IDR_DEFAULT_FAVICON_32;
199 break; 245 break;
200 default: 246 default:
201 favicon_index = SIZE_16; 247 favicon_index = SIZE_16;
202 resource_id = IDR_DEFAULT_FAVICON; 248 resource_id = IDR_DEFAULT_FAVICON;
203 break; 249 break;
204 } 250 }
205 base::RefCountedMemory* default_favicon = default_favicons_[favicon_index]; 251 base::RefCountedMemory* default_favicon = default_favicons_[favicon_index];
206 252
207 if (!default_favicon) { 253 if (!default_favicon) {
208 ui::ScaleFactor scale_factor = icon_request.scale_factor; 254 ui::ScaleFactor scale_factor = icon_request.scale_factor;
209 default_favicon = ResourceBundle::GetSharedInstance() 255 default_favicon = ResourceBundle::GetSharedInstance()
210 .LoadDataResourceBytesForScale(resource_id, scale_factor); 256 .LoadDataResourceBytesForScale(resource_id, scale_factor);
211 default_favicons_[favicon_index] = default_favicon; 257 default_favicons_[favicon_index] = default_favicon;
212 } 258 }
213 259
214 icon_request.callback.Run(default_favicon); 260 icon_request.callback.Run(default_favicon);
215 } 261 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/webui/favicon_source.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698