1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/webui/large_icon_source.h"
9 #include "base/memory/ref_counted_memory.h"
10 #include "chrome/browser/search/instant_io_context.h"
11 #include "chrome/common/favicon/large_icon_url_parser.h"
12 #include "chrome/common/url_constants.h"
13 #include "components/favicon/core/fallback_icon_service.h"
14 #include "components/favicon/core/favicon_service.h"
15 #include "components/favicon_base/fallback_icon_style.h"
16 #include "net/url_request/url_request.h"
17 #include "third_party/skia/include/core/SkColor.h"
21 int kDefaultLargeIconSize
= 96;
22 int kMaxLargeIconSize
= 192; // Arbitrary bound to safeguard endpoint.
26 LargeIconSource::IconRequest::IconRequest() : size(kDefaultLargeIconSize
) {
29 LargeIconSource::IconRequest::IconRequest(
30 const content::URLDataSource::GotDataCallback
& callback_in
,
33 : callback(callback_in
),
38 LargeIconSource::IconRequest::~IconRequest() {
41 LargeIconSource::LargeIconSource(
42 favicon::FaviconService
* favicon_service
,
43 favicon::FallbackIconService
* fallback_icon_service
)
44 : favicon_service_(favicon_service
),
45 fallback_icon_service_(fallback_icon_service
) {
48 LargeIconSource::~LargeIconSource() {
51 std::string
LargeIconSource::GetSource() const {
52 return chrome::kChromeUILargeIconHost
;
55 void LargeIconSource::StartDataRequest(
56 const std::string
& path
,
57 int render_process_id
,
59 const content::URLDataSource::GotDataCallback
& callback
) {
60 if (!favicon_service_
) {
61 SendNotFoundResponse(callback
);
65 LargeIconUrlParser parser
;
66 bool success
= parser
.Parse(path
);
68 parser
.size_in_pixels() <= 0 ||
69 parser
.size_in_pixels() > kMaxLargeIconSize
) {
70 SendNotFoundResponse(callback
);
74 GURL
url(parser
.url_string());
75 if (!url
.is_valid()) {
76 SendNotFoundResponse(callback
);
80 favicon_service_
->GetRawFaviconForPageURL(
82 favicon_base::TOUCH_ICON
| favicon_base::TOUCH_PRECOMPOSED_ICON
,
83 parser
.size_in_pixels(),
85 &LargeIconSource::OnIconDataAvailable
,
86 base::Unretained(this),
87 IconRequest(callback
, url
, parser
.size_in_pixels())),
88 &cancelable_task_tracker_
);
91 std::string
LargeIconSource::GetMimeType(const std::string
&) const {
92 // We need to explicitly return a mime type, otherwise if the user tries to
93 // drag the image they get no extension.
97 bool LargeIconSource::ShouldReplaceExistingSource() const {
98 // Leave the existing DataSource in place, otherwise we'll drop any pending
99 // requests on the floor.
103 bool LargeIconSource::ShouldServiceRequest(
104 const net::URLRequest
* request
) const {
105 if (request
->url().SchemeIs(chrome::kChromeSearchScheme
))
106 return InstantIOContext::ShouldServiceRequest(request
);
107 return URLDataSource::ShouldServiceRequest(request
);
110 void LargeIconSource::OnIconDataAvailable(
111 const IconRequest
& request
,
112 const favicon_base::FaviconRawBitmapResult
& bitmap_result
) {
113 if (!bitmap_result
.is_valid())
114 SendFallbackIcon(request
);
116 request
.callback
.Run(bitmap_result
.bitmap_data
.get());
119 void LargeIconSource::SendFallbackIcon(const IconRequest
& request
) {
120 if (!fallback_icon_service_
) {
121 SendNotFoundResponse(request
.callback
);
124 favicon_base::FallbackIconStyle style
;
125 style
.background_color
= SkColorSetRGB(0x78, 0x78, 0x78);
126 style
.text_color
= SK_ColorWHITE
;
127 style
.font_size_ratio
= 0.44;
128 style
.roundness
= 0; // Square. Round corners can be applied by JavaScript.
129 std::vector
<unsigned char> bitmap_data
=
130 fallback_icon_service_
->RenderFallbackIconBitmap(
131 request
.url
, request
.size
, style
);
132 request
.callback
.Run(base::RefCountedBytes::TakeVector(&bitmap_data
));
135 void LargeIconSource::SendNotFoundResponse(
136 const content::URLDataSource::GotDataCallback
& callback
) {
137 callback
.Run(nullptr);