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

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

Issue 15388002: Supporting high dpi favicons in Instant Extended. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Moving reusable pieces to chrome/common Created 7 years, 7 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
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/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
10 #include "chrome/browser/favicon/favicon_service_factory.h" 10 #include "chrome/browser/favicon/favicon_service_factory.h"
11 #include "chrome/browser/history/top_sites.h" 11 #include "chrome/browser/history/top_sites.h"
12 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/search/instant_io_context.h" 13 #include "chrome/browser/search/instant_io_context.h"
14 #include "chrome/browser/search/instant_service.h" 14 #include "chrome/browser/search/instant_service.h"
15 #include "chrome/browser/search/instant_service_factory.h" 15 #include "chrome/browser/search/instant_service_factory.h"
16 #include "chrome/common/favicon_types.h"
17 #include "chrome/common/favicon_url_parser.h"
16 #include "chrome/common/url_constants.h" 18 #include "chrome/common/url_constants.h"
17 #include "grit/locale_settings.h" 19 #include "grit/locale_settings.h"
18 #include "grit/ui_resources.h" 20 #include "grit/ui_resources.h"
19 #include "net/url_request/url_request.h" 21 #include "net/url_request/url_request.h"
20 #include "ui/base/l10n/l10n_util.h" 22 #include "ui/base/l10n/l10n_util.h"
21 #include "ui/base/layout.h" 23 #include "ui/base/layout.h"
22 #include "ui/base/resource/resource_bundle.h" 24 #include "ui/base/resource/resource_bundle.h"
23 #include "ui/webui/web_ui_util.h" 25 #include "ui/webui/web_ui_util.h"
24 26
25 namespace {
26
27 // Parameters which can be used in chrome://favicon path. See .h file for a
28 // description of what each does.
29 const char kIconURLParameter[] = "iconurl/";
30 const char kLargestParameter[] = "largest/";
31 const char kOriginParameter[] = "origin/";
32 const char kSizeParameter[] = "size/";
33
34 // Returns true if |search| is a substring of |path| which starts at
35 // |start_index|.
36 bool HasSubstringAt(const std::string& path,
37 size_t start_index,
38 const std::string& search) {
39 if (search.empty())
40 return false;
41
42 if (start_index + search.size() >= path.size())
43 return false;
44
45 return (path.compare(start_index, search.size(), search) == 0);
46 }
47
48 } // namespace
49
50 FaviconSource::IconRequest::IconRequest() 27 FaviconSource::IconRequest::IconRequest()
51 : size_in_dip(gfx::kFaviconSize), 28 : size_in_dip(gfx::kFaviconSize),
52 scale_factor(ui::SCALE_FACTOR_NONE) { 29 scale_factor(ui::SCALE_FACTOR_NONE) {
53 } 30 }
54 31
55 FaviconSource::IconRequest::IconRequest( 32 FaviconSource::IconRequest::IconRequest(
56 const content::URLDataSource::GotDataCallback& cb, 33 const content::URLDataSource::GotDataCallback& cb,
57 const GURL& path, 34 const GURL& path,
58 int size, 35 int size,
59 ui::ScaleFactor scale) 36 ui::ScaleFactor scale)
(...skipping 15 matching lines...) Expand all
75 52
76 FaviconSource::~FaviconSource() { 53 FaviconSource::~FaviconSource() {
77 } 54 }
78 55
79 std::string FaviconSource::GetSource() const { 56 std::string FaviconSource::GetSource() const {
80 return icon_types_ == chrome::FAVICON ? 57 return icon_types_ == chrome::FAVICON ?
81 chrome::kChromeUIFaviconHost : chrome::kChromeUITouchIconHost; 58 chrome::kChromeUIFaviconHost : chrome::kChromeUITouchIconHost;
82 } 59 }
83 60
84 void FaviconSource::StartDataRequest( 61 void FaviconSource::StartDataRequest(
85 const std::string& raw_path, 62 const std::string& path,
86 int render_process_id, 63 int render_process_id,
87 int render_view_id, 64 int render_view_id,
88 const content::URLDataSource::GotDataCallback& callback) { 65 const content::URLDataSource::GotDataCallback& callback) {
89 FaviconService* favicon_service = 66 FaviconService* favicon_service =
90 FaviconServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); 67 FaviconServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS);
91 if (!favicon_service) { 68 if (!favicon_service) {
92 SendDefaultResponse(callback); 69 SendDefaultResponse(callback);
93 return; 70 return;
94 } 71 }
95 72
96 bool is_icon_url = false; 73 bool is_icon_url = false;
97 GURL url; 74 GURL url;
98 int size_in_dip = 16; 75 int size_in_dip = 16;
99 ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_100P; 76 ui::ScaleFactor scale_factor = ui::SCALE_FACTOR_100P;
100 bool success = ParsePath(raw_path, &is_icon_url, &url, &size_in_dip, 77
78 bool success = ParsePath(path, &is_icon_url, &url, &size_in_dip,
101 &scale_factor); 79 &scale_factor);
102 80
103 if (!success) { 81 if (!success) {
104 SendDefaultResponse(callback); 82 SendDefaultResponse(callback);
105 return; 83 return;
106 } 84 }
107 85
108 if (is_icon_url) { 86 if (is_icon_url) {
109 // TODO(michaelbai): Change GetRawFavicon to support combination of 87 // TODO(michaelbai): Change GetRawFavicon to support combination of
110 // IconType. 88 // IconType.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 } 144 }
167 return URLDataSource::ShouldServiceRequest(request); 145 return URLDataSource::ShouldServiceRequest(request);
168 } 146 }
169 147
170 bool FaviconSource::HandleMissingResource(const IconRequest& request) { 148 bool FaviconSource::HandleMissingResource(const IconRequest& request) {
171 // No additional checks to locate the favicon resource in the base 149 // No additional checks to locate the favicon resource in the base
172 // implementation. 150 // implementation.
173 return false; 151 return false;
174 } 152 }
175 153
176 bool FaviconSource::ParsePath(const std::string& raw_path, 154 bool FaviconSource::ParsePath(const std::string& path,
177 bool* is_icon_url, 155 bool* is_icon_url,
178 GURL* url, 156 GURL* url,
179 int* size_in_dip, 157 int* size_in_dip,
180 ui::ScaleFactor* scale_factor) const { 158 ui::ScaleFactor* scale_factor) const {
181 DCHECK_EQ(16, gfx::kFaviconSize); 159 DCHECK_EQ(16, gfx::kFaviconSize);
182 160
183 *is_icon_url = false; 161 std::string url_string;
184 *url = GURL(); 162 std::string params;
185 *size_in_dip = 16; 163 bool success = chrome::ParseFaviconPath(path, true, icon_types_,
186 *scale_factor = ui::SCALE_FACTOR_100P; 164 is_icon_url, &url_string, size_in_dip, scale_factor, &params);
187 165
188 if (raw_path.empty()) 166 *url = GURL(url_string);
189 return false;
190 167
191 // Translate to regular path if |raw_path| is of the form 168 return success;
192 // chrome-search://favicon/<most_visited_item_id>, where
193 // "most_visited_item_id" is a uint64.
194 std::string path = InstantService::MaybeTranslateInstantPathOnUI(profile_,
195 raw_path);
196 size_t parsed_index = 0;
197 if (HasSubstringAt(path, parsed_index, kLargestParameter)) {
198 parsed_index += strlen(kLargestParameter);
199 *size_in_dip = 0;
200 } else if (HasSubstringAt(path, parsed_index, kSizeParameter)) {
201 parsed_index += strlen(kSizeParameter);
202
203 size_t slash = path.find("/", parsed_index);
204 if (slash == std::string::npos)
205 return false;
206
207 size_t scale_delimiter = path.find("@", parsed_index);
208 std::string size_str;
209 std::string scale_str;
210 if (scale_delimiter == std::string::npos) {
211 // Support the legacy size format of 'size/aa/' where 'aa' is the desired
212 // size in DIP for the sake of not regressing the extensions which use it.
213 size_str = path.substr(parsed_index, slash - parsed_index);
214 } else {
215 size_str = path.substr(parsed_index, scale_delimiter - parsed_index);
216 scale_str = path.substr(scale_delimiter + 1,
217 slash - scale_delimiter - 1);
218 }
219
220 if (!base::StringToInt(size_str, size_in_dip))
221 return false;
222
223 if (*size_in_dip != 64 && *size_in_dip != 32) {
224 // Only 64x64, 32x32 and 16x16 icons are supported.
225 *size_in_dip = 16;
226 }
227
228 if (!scale_str.empty())
229 webui::ParseScaleFactor(scale_str, scale_factor);
230
231 // Return the default favicon (as opposed to a resized favicon) for
232 // favicon sizes which are not cached by the favicon service.
233 // Currently the favicon service caches:
234 // - favicons of sizes "16 * scale factor" px of type FAVICON
235 // where scale factor is one of FaviconUtil::GetFaviconScaleFactors().
236 // - the largest TOUCH_ICON / TOUCH_PRECOMPOSED_ICON
237 if (*size_in_dip != 16 && icon_types_ == chrome::FAVICON)
238 return false;
239
240 parsed_index = slash + 1;
241 }
242
243 if (HasSubstringAt(path, parsed_index, kIconURLParameter)) {
244 parsed_index += strlen(kIconURLParameter);
245 *is_icon_url = true;
246 *url = GURL(path.substr(parsed_index));
247 } else {
248 // URL requests prefixed with "origin/" are converted to a form with an
249 // empty path and a valid scheme. (e.g., example.com -->
250 // http://example.com/ or http://example.com/a --> http://example.com/)
251 if (HasSubstringAt(path, parsed_index, kOriginParameter)) {
252 parsed_index += strlen(kOriginParameter);
253 std::string possibly_invalid_url = path.substr(parsed_index);
254
255 // If the URL does not specify a scheme (e.g., example.com instead of
256 // http://example.com), add "http://" as a default.
257 if (!GURL(possibly_invalid_url).has_scheme())
258 possibly_invalid_url = "http://" + possibly_invalid_url;
259
260 // Strip the path beyond the top-level domain.
261 *url = GURL(possibly_invalid_url).GetOrigin();
262 } else {
263 *url = GURL(path.substr(parsed_index));
264 }
265 }
266 return true;
267 } 169 }
268 170
269 void FaviconSource::OnFaviconDataAvailable( 171 void FaviconSource::OnFaviconDataAvailable(
270 const IconRequest& request, 172 const IconRequest& request,
271 const chrome::FaviconBitmapResult& bitmap_result) { 173 const chrome::FaviconBitmapResult& bitmap_result) {
272 if (bitmap_result.is_valid()) { 174 if (bitmap_result.is_valid()) {
273 // Forward the data along to the networking system. 175 // Forward the data along to the networking system.
274 request.callback.Run(bitmap_result.bitmap_data); 176 request.callback.Run(bitmap_result.bitmap_data);
275 } else if (!HandleMissingResource(request)) { 177 } else if (!HandleMissingResource(request)) {
276 SendDefaultResponse(request); 178 SendDefaultResponse(request);
(...skipping 27 matching lines...) Expand all
304 206
305 if (!default_favicon) { 207 if (!default_favicon) {
306 ui::ScaleFactor scale_factor = icon_request.scale_factor; 208 ui::ScaleFactor scale_factor = icon_request.scale_factor;
307 default_favicon = ResourceBundle::GetSharedInstance() 209 default_favicon = ResourceBundle::GetSharedInstance()
308 .LoadDataResourceBytesForScale(resource_id, scale_factor); 210 .LoadDataResourceBytesForScale(resource_id, scale_factor);
309 default_favicons_[favicon_index] = default_favicon; 211 default_favicons_[favicon_index] = default_favicon;
310 } 212 }
311 213
312 icon_request.callback.Run(default_favicon); 214 icon_request.callback.Run(default_favicon);
313 } 215 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698