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

Side by Side Diff: components/ntp_tiles/icon_cacher_impl.cc

Issue 2873403002: [NTP Tiles] Avoid duplicate requests from IconCacherImpl (Closed)
Patch Set: Fix build for windows Created 3 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "components/ntp_tiles/icon_cacher_impl.h" 5 #include "components/ntp_tiles/icon_cacher_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
10 #include "components/favicon/core/favicon_service.h" 10 #include "components/favicon/core/favicon_service.h"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 } 68 }
69 69
70 IconCacherImpl::~IconCacherImpl() = default; 70 IconCacherImpl::~IconCacherImpl() = default;
71 71
72 void IconCacherImpl::StartFetchPopularSites( 72 void IconCacherImpl::StartFetchPopularSites(
73 PopularSites::Site site, 73 PopularSites::Site site,
74 const base::Closure& icon_available, 74 const base::Closure& icon_available,
75 const base::Closure& preliminary_icon_available) { 75 const base::Closure& preliminary_icon_available) {
76 // Copy values from |site| before it is moved. 76 // Copy values from |site| before it is moved.
77 GURL site_url = site.url; 77 GURL site_url = site.url;
78 if (!StartRequest(site_url, icon_available)) {
79 return;
80 }
81
78 favicon_base::IconType icon_type = IconType(site); 82 favicon_base::IconType icon_type = IconType(site);
79 favicon::GetFaviconImageForPageURL( 83 favicon::GetFaviconImageForPageURL(
80 favicon_service_, site_url, icon_type, 84 favicon_service_, site_url, icon_type,
81 base::Bind(&IconCacherImpl::OnGetFaviconImageForPageURLFinished, 85 base::Bind(&IconCacherImpl::OnGetFaviconImageForPageURLFinished,
82 base::Unretained(this), std::move(site), icon_available, 86 base::Unretained(this), std::move(site),
83 preliminary_icon_available), 87 preliminary_icon_available),
84 &tracker_); 88 &tracker_);
85 } 89 }
86 90
87 void IconCacherImpl::OnGetFaviconImageForPageURLFinished( 91 void IconCacherImpl::OnGetFaviconImageForPageURLFinished(
88 PopularSites::Site site, 92 PopularSites::Site site,
89 const base::Closure& icon_available,
90 const base::Closure& preliminary_icon_available, 93 const base::Closure& preliminary_icon_available,
91 const favicon_base::FaviconImageResult& result) { 94 const favicon_base::FaviconImageResult& result) {
92 if (!result.image.IsEmpty()) { 95 if (!result.image.IsEmpty()) {
96 FinishRequestAndNotifyIconAvailable(site.url, /*newly_available=*/false);
93 return; 97 return;
94 } 98 }
95 99
96 std::unique_ptr<CancelableImageCallback> preliminary_callback = 100 std::unique_ptr<CancelableImageCallback> preliminary_callback =
97 MaybeProvideDefaultIcon(site, preliminary_icon_available); 101 MaybeProvideDefaultIcon(site, preliminary_icon_available);
98 102
99 image_fetcher_->StartOrQueueNetworkRequest( 103 image_fetcher_->StartOrQueueNetworkRequest(
100 std::string(), IconURL(site), 104 std::string(), IconURL(site),
101 base::Bind(&IconCacherImpl::OnPopularSitesFaviconDownloaded, 105 base::Bind(&IconCacherImpl::OnPopularSitesFaviconDownloaded,
102 base::Unretained(this), site, 106 base::Unretained(this), site,
103 base::Passed(std::move(preliminary_callback)), 107 base::Passed(std::move(preliminary_callback))));
104 icon_available));
105 } 108 }
106 109
107 void IconCacherImpl::OnPopularSitesFaviconDownloaded( 110 void IconCacherImpl::OnPopularSitesFaviconDownloaded(
108 PopularSites::Site site, 111 PopularSites::Site site,
109 std::unique_ptr<CancelableImageCallback> preliminary_callback, 112 std::unique_ptr<CancelableImageCallback> preliminary_callback,
110 const base::Closure& icon_available,
111 const std::string& id, 113 const std::string& id,
112 const gfx::Image& fetched_image, 114 const gfx::Image& fetched_image,
113 const image_fetcher::RequestMetadata& metadata) { 115 const image_fetcher::RequestMetadata& metadata) {
114 if (fetched_image.IsEmpty()) { 116 if (fetched_image.IsEmpty()) {
117 FinishRequestAndNotifyIconAvailable(site.url, /*newly_available=*/false);
115 return; 118 return;
116 } 119 }
117 120
118 // Avoid invoking callback about preliminary icon to be triggered. The best 121 // Avoid invoking callback about preliminary icon to be triggered. The best
119 // possible icon has already been downloaded. 122 // possible icon has already been downloaded.
120 if (preliminary_callback) { 123 if (preliminary_callback) {
121 preliminary_callback->Cancel(); 124 preliminary_callback->Cancel();
122 } 125 }
123 SaveAndNotifyIconForSite(site, icon_available, fetched_image); 126 SaveIconForSite(site, fetched_image);
127 FinishRequestAndNotifyIconAvailable(site.url, /*newly_available=*/true);
124 } 128 }
125 129
126 void IconCacherImpl::SaveAndNotifyIconForSite( 130 void IconCacherImpl::SaveAndNotifyDefaultIconForSite(
127 const PopularSites::Site& site, 131 const PopularSites::Site& site,
128 const base::Closure& icon_available, 132 const base::Closure& preliminary_icon_available,
129 const gfx::Image& image) { 133 const gfx::Image& image) {
134 SaveIconForSite(site, image);
135 if (preliminary_icon_available) {
136 preliminary_icon_available.Run();
137 }
138 }
139
140 void IconCacherImpl::SaveIconForSite(const PopularSites::Site& site,
141 const gfx::Image& image) {
130 // Although |SetFaviconColorSpace| affects OSX only, copies of gfx::Images are 142 // Although |SetFaviconColorSpace| affects OSX only, copies of gfx::Images are
131 // just copies of the reference to the image and therefore cheap. 143 // just copies of the reference to the image and therefore cheap.
132 gfx::Image img(image); 144 gfx::Image img(image);
133 favicon_base::SetFaviconColorSpace(&img); 145 favicon_base::SetFaviconColorSpace(&img);
134 146
135 favicon_service_->SetFavicons(site.url, IconURL(site), IconType(site), 147 favicon_service_->SetFavicons(site.url, IconURL(site), IconType(site),
136 std::move(img)); 148 std::move(img));
137
138 if (icon_available) {
139 icon_available.Run();
140 }
141 } 149 }
142 150
143 std::unique_ptr<IconCacherImpl::CancelableImageCallback> 151 std::unique_ptr<IconCacherImpl::CancelableImageCallback>
144 IconCacherImpl::MaybeProvideDefaultIcon(const PopularSites::Site& site, 152 IconCacherImpl::MaybeProvideDefaultIcon(
145 const base::Closure& icon_available) { 153 const PopularSites::Site& site,
154 const base::Closure& preliminary_icon_available) {
146 if (site.default_icon_resource < 0) { 155 if (site.default_icon_resource < 0) {
147 return std::unique_ptr<CancelableImageCallback>(); 156 return std::unique_ptr<CancelableImageCallback>();
148 } 157 }
149 std::unique_ptr<CancelableImageCallback> preliminary_callback( 158 std::unique_ptr<CancelableImageCallback> preliminary_callback(
150 new CancelableImageCallback( 159 new CancelableImageCallback(base::Bind(
151 base::Bind(&IconCacherImpl::SaveAndNotifyIconForSite, 160 &IconCacherImpl::SaveAndNotifyDefaultIconForSite,
152 weak_ptr_factory_.GetWeakPtr(), site, icon_available))); 161 weak_ptr_factory_.GetWeakPtr(), site, preliminary_icon_available)));
153 image_fetcher_->GetImageDecoder()->DecodeImage( 162 image_fetcher_->GetImageDecoder()->DecodeImage(
154 ResourceBundle::GetSharedInstance() 163 ResourceBundle::GetSharedInstance()
155 .GetRawDataResource(site.default_icon_resource) 164 .GetRawDataResource(site.default_icon_resource)
156 .as_string(), 165 .as_string(),
157 gfx::Size(kDesiredFrameSize, kDesiredFrameSize), 166 gfx::Size(kDesiredFrameSize, kDesiredFrameSize),
158 preliminary_callback->callback()); 167 preliminary_callback->callback());
159 return preliminary_callback; 168 return preliminary_callback;
160 } 169 }
161 170
162 void IconCacherImpl::StartFetchMostLikely(const GURL& page_url, 171 void IconCacherImpl::StartFetchMostLikely(const GURL& page_url,
163 const base::Closure& icon_available) { 172 const base::Closure& icon_available) {
173 if (!StartRequest(page_url, icon_available)) {
174 return;
175 }
176
164 // Desired size 0 means that we do not want the service to resize the image 177 // Desired size 0 means that we do not want the service to resize the image
165 // (as we will not use it anyway). 178 // (as we will not use it anyway).
166 large_icon_service_->GetLargeIconOrFallbackStyle( 179 large_icon_service_->GetLargeIconOrFallbackStyle(
167 page_url, kTileIconMinSizePx, /*desired_size_in_pixel=*/0, 180 page_url, kTileIconMinSizePx, /*desired_size_in_pixel=*/0,
168 base::Bind(&IconCacherImpl::OnGetLargeIconOrFallbackStyleFinished, 181 base::Bind(&IconCacherImpl::OnGetLargeIconOrFallbackStyleFinished,
169 weak_ptr_factory_.GetWeakPtr(), page_url, icon_available), 182 weak_ptr_factory_.GetWeakPtr(), page_url),
170 &tracker_); 183 &tracker_);
171 } 184 }
172 185
173 void IconCacherImpl::OnGetLargeIconOrFallbackStyleFinished( 186 void IconCacherImpl::OnGetLargeIconOrFallbackStyleFinished(
174 const GURL& page_url, 187 const GURL& page_url,
175 const base::Closure& icon_available,
176 const favicon_base::LargeIconResult& result) { 188 const favicon_base::LargeIconResult& result) {
177 if (!HasResultDefaultBackgroundColor(result)) { 189 if (!HasResultDefaultBackgroundColor(result)) {
178 // We should only fetch for default "gray" tiles so that we never overrite 190 // We should only fetch for default "gray" tiles so that we never overrite
179 // any favicon of any size. 191 // any favicon of any size.
192 FinishRequestAndNotifyIconAvailable(page_url, /*newly_available=*/false);
180 return; 193 return;
181 } 194 }
182 195
183 large_icon_service_ 196 large_icon_service_
184 ->GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache( 197 ->GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
185 page_url, kTileIconMinSizePx, kTileIconDesiredSizePx, 198 page_url, kTileIconMinSizePx, kTileIconDesiredSizePx,
186 base::Bind(&IconCacherImpl::OnMostLikelyFaviconDownloaded, 199 base::Bind(&IconCacherImpl::FinishRequestAndNotifyIconAvailable,
187 weak_ptr_factory_.GetWeakPtr(), icon_available)); 200 weak_ptr_factory_.GetWeakPtr(), page_url));
188 } 201 }
189 202
190 void IconCacherImpl::OnMostLikelyFaviconDownloaded( 203 bool IconCacherImpl::StartRequest(const GURL& request_url,
191 const base::Closure& icon_available, 204 const base::Closure& icon_available) {
192 bool success) { 205 bool in_flight = in_flight_requests_.count(request_url) > 0;
193 if (!success) { 206 in_flight_requests_[request_url].push_back(icon_available);
207 return !in_flight;
208 }
209
210 void IconCacherImpl::FinishRequestAndNotifyIconAvailable(
211 const GURL& request_url,
212 bool newly_available) {
213 std::vector<base::Closure> callbacks =
214 std::move(in_flight_requests_[request_url]);
215 in_flight_requests_.erase(request_url);
216 if (!newly_available) {
194 return; 217 return;
195 } 218 }
196 if (icon_available) { 219 for (const base::Closure& callback : callbacks) {
197 icon_available.Run(); 220 if (callback) {
221 callback.Run();
222 }
198 } 223 }
199 } 224 }
200 225
201 } // namespace ntp_tiles 226 } // namespace ntp_tiles
OLDNEW
« no previous file with comments | « components/ntp_tiles/icon_cacher_impl.h ('k') | components/ntp_tiles/icon_cacher_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698