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/large_icon_service.h"
15 #include "components/favicon_base/fallback_icon_style.h"
16 #include "components/favicon_base/favicon_types.h"
17 #include "net/url_request/url_request.h"
21 const int kMaxLargeIconSize
= 192; // Arbitrary bound to safeguard endpoint.
25 LargeIconSource::LargeIconSource(
26 favicon::FallbackIconService
* fallback_icon_service
,
27 favicon::LargeIconService
* large_icon_service
)
28 : fallback_icon_service_(fallback_icon_service
),
29 large_icon_service_(large_icon_service
) {
32 LargeIconSource::~LargeIconSource() {
35 std::string
LargeIconSource::GetSource() const {
36 return chrome::kChromeUILargeIconHost
;
39 void LargeIconSource::StartDataRequest(
40 const std::string
& path
,
41 int render_process_id
,
43 const content::URLDataSource::GotDataCallback
& callback
) {
44 if (!large_icon_service_
) {
45 SendNotFoundResponse(callback
);
49 LargeIconUrlParser parser
;
50 bool success
= parser
.Parse(path
);
52 parser
.size_in_pixels() <= 0 ||
53 parser
.size_in_pixels() > kMaxLargeIconSize
) {
54 SendNotFoundResponse(callback
);
58 GURL
url(parser
.url_string());
59 if (!url
.is_valid()) {
60 SendNotFoundResponse(callback
);
64 // TODO(beaudoin): Potentially allow icon to be scaled up.
65 large_icon_service_
->GetLargeIconOrFallbackStyle(
67 parser
.size_in_pixels(), // Reducing this will enable scale up.
68 parser
.size_in_pixels(),
69 base::Bind(&LargeIconSource::OnLargeIconDataAvailable
,
70 base::Unretained(this), callback
, url
,
71 parser
.size_in_pixels()),
72 &cancelable_task_tracker_
);
75 std::string
LargeIconSource::GetMimeType(const std::string
&) const {
76 // We need to explicitly return a mime type, otherwise if the user tries to
77 // drag the image they get no extension.
81 bool LargeIconSource::ShouldReplaceExistingSource() const {
82 // Leave the existing DataSource in place, otherwise we'll drop any pending
83 // requests on the floor.
87 bool LargeIconSource::ShouldServiceRequest(
88 const net::URLRequest
* request
) const {
89 if (request
->url().SchemeIs(chrome::kChromeSearchScheme
))
90 return InstantIOContext::ShouldServiceRequest(request
);
91 return URLDataSource::ShouldServiceRequest(request
);
94 void LargeIconSource::OnLargeIconDataAvailable(
95 const content::URLDataSource::GotDataCallback
& callback
,
98 const favicon_base::LargeIconResult
& result
) {
99 if (result
.bitmap
.is_valid()) {
100 callback
.Run(result
.bitmap
.bitmap_data
.get());
104 // Bitmap is invalid, use the fallback if service is available.
105 if (!fallback_icon_service_
|| !result
.fallback_icon_style
) {
106 SendNotFoundResponse(callback
);
109 std::vector
<unsigned char> bitmap_data
=
110 fallback_icon_service_
->RenderFallbackIconBitmap(
111 url
, size
, *result
.fallback_icon_style
);
112 callback
.Run(base::RefCountedBytes::TakeVector(&bitmap_data
));
115 void LargeIconSource::SendNotFoundResponse(
116 const content::URLDataSource::GotDataCallback
& callback
) {
117 callback
.Run(nullptr);