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

Side by Side Diff: chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc

Issue 2968693003: [Android Webapps] Make AddToHomescreenDataFetcher easier to test (Closed)
Patch Set: Merge branch 'master' into homescreen_fetcher_weak_ptr2 Created 3 years, 5 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 2015 The Chromium Authors. All rights reserved. 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 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/android/webapps/add_to_homescreen_data_fetcher.h" 5 #include "chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/location.h" 10 #include "base/location.h"
11 #include "base/metrics/user_metrics.h" 11 #include "base/metrics/user_metrics.h"
12 #include "base/task_scheduler/post_task.h" 12 #include "base/task_scheduler/post_task.h"
13 #include "chrome/browser/android/shortcut_helper.h"
13 #include "chrome/browser/android/webapk/webapk_web_manifest_checker.h" 14 #include "chrome/browser/android/webapk/webapk_web_manifest_checker.h"
14 #include "chrome/browser/favicon/favicon_service_factory.h" 15 #include "chrome/browser/favicon/favicon_service_factory.h"
15 #include "chrome/browser/installable/installable_manager.h" 16 #include "chrome/browser/installable/installable_manager.h"
16 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/common/chrome_constants.h" 18 #include "chrome/common/chrome_constants.h"
18 #include "chrome/common/render_messages.h" 19 #include "chrome/common/render_messages.h"
19 #include "chrome/common/web_application_info.h" 20 #include "chrome/common/web_application_info.h"
20 #include "components/dom_distiller/core/url_utils.h" 21 #include "components/dom_distiller/core/url_utils.h"
21 #include "components/favicon/core/favicon_service.h" 22 #include "components/favicon/core/favicon_service.h"
22 #include "components/favicon_base/favicon_types.h" 23 #include "components/favicon_base/favicon_types.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 return params; 58 return params;
58 } 59 }
59 60
60 InstallableParams ParamsToPerformInstallableCheck( 61 InstallableParams ParamsToPerformInstallableCheck(
61 bool check_webapk_compatibility) { 62 bool check_webapk_compatibility) {
62 InstallableParams params; 63 InstallableParams params;
63 params.check_installable = check_webapk_compatibility; 64 params.check_installable = check_webapk_compatibility;
64 return params; 65 return params;
65 } 66 }
66 67
68 // Creates a launcher icon from |icon|. |start_url| is used to generate the icon
69 // if |icon| is empty or is not large enough. Returns a std::pair with:
70 // - the generated icon
71 // - whether |icon| was used in generating the launcher icon
72 std::pair<SkBitmap, bool> CreateLauncherIconInBackground(const GURL& start_url,
73 const SkBitmap& icon) {
74 base::ThreadRestrictions::AssertIOAllowed();
75
76 bool is_generated = false;
77 SkBitmap primary_icon = ShortcutHelper::FinalizeLauncherIconInBackground(
78 icon, start_url, &is_generated);
79 return std::make_pair(primary_icon, is_generated);
80 }
81
82 // Creates a launcher icon from |bitmap_result|. |start_url| is used to
83 // generate the icon if there is no bitmap in |bitmap_result| or the bitmap is
84 // not large enough. Returns a std::pair with:
85 // - the generated icon
86 // - whether the bitmap in |bitmap_result| was used in generating the launcher
87 // icon
88 std::pair<SkBitmap, bool> CreateLauncherIconFromFaviconInBackground(
89 const GURL& start_url,
90 const favicon_base::FaviconRawBitmapResult& bitmap_result) {
91 base::ThreadRestrictions::AssertIOAllowed();
92
93 SkBitmap decoded;
94 if (bitmap_result.is_valid()) {
95 gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(),
96 bitmap_result.bitmap_data->size(), &decoded);
97 }
98 return CreateLauncherIconInBackground(start_url, decoded);
99 }
100
67 } // namespace 101 } // namespace
68 102
69 AddToHomescreenDataFetcher::AddToHomescreenDataFetcher( 103 AddToHomescreenDataFetcher::AddToHomescreenDataFetcher(
70 content::WebContents* web_contents, 104 content::WebContents* web_contents,
71 int ideal_icon_size_in_px, 105 int ideal_icon_size_in_px,
72 int minimum_icon_size_in_px, 106 int minimum_icon_size_in_px,
73 int ideal_splash_image_size_in_px, 107 int ideal_splash_image_size_in_px,
74 int minimum_splash_image_size_in_px, 108 int minimum_splash_image_size_in_px,
75 int badge_size_in_px, 109 int badge_size_in_px,
76 int data_timeout_ms, 110 int data_timeout_ms,
77 bool check_webapk_compatibility, 111 bool check_webapk_compatibility,
78 Observer* observer) 112 Observer* observer)
79 : content::WebContentsObserver(web_contents), 113 : content::WebContentsObserver(web_contents),
80 installable_manager_(InstallableManager::FromWebContents(web_contents)), 114 installable_manager_(InstallableManager::FromWebContents(web_contents)),
81 weak_observer_(observer), 115 observer_(observer),
82 shortcut_info_(GetShortcutUrl(web_contents->GetBrowserContext(), 116 shortcut_info_(GetShortcutUrl(web_contents->GetBrowserContext(),
83 web_contents->GetLastCommittedURL())), 117 web_contents->GetLastCommittedURL())),
84 ideal_icon_size_in_px_(ideal_icon_size_in_px), 118 ideal_icon_size_in_px_(ideal_icon_size_in_px),
85 minimum_icon_size_in_px_(minimum_icon_size_in_px), 119 minimum_icon_size_in_px_(minimum_icon_size_in_px),
86 ideal_splash_image_size_in_px_(ideal_splash_image_size_in_px), 120 ideal_splash_image_size_in_px_(ideal_splash_image_size_in_px),
87 minimum_splash_image_size_in_px_(minimum_splash_image_size_in_px), 121 minimum_splash_image_size_in_px_(minimum_splash_image_size_in_px),
88 badge_size_in_px_(badge_size_in_px), 122 badge_size_in_px_(badge_size_in_px),
89 data_timeout_ms_(data_timeout_ms), 123 data_timeout_ms_(data_timeout_ms),
90 check_webapk_compatibility_(check_webapk_compatibility), 124 check_webapk_compatibility_(check_webapk_compatibility),
91 is_waiting_for_web_application_info_(true), 125 is_waiting_for_web_application_info_(true),
92 is_installable_check_complete_(false) { 126 weak_ptr_factory_(this) {
93 DCHECK(minimum_icon_size_in_px <= ideal_icon_size_in_px); 127 DCHECK(minimum_icon_size_in_px <= ideal_icon_size_in_px);
94 DCHECK(minimum_splash_image_size_in_px <= ideal_splash_image_size_in_px); 128 DCHECK(minimum_splash_image_size_in_px <= ideal_splash_image_size_in_px);
95 129
96 // Send a message to the renderer to retrieve information about the page. 130 // Send a message to the renderer to retrieve information about the page.
97 content::RenderFrameHost* main_frame = web_contents->GetMainFrame(); 131 content::RenderFrameHost* main_frame = web_contents->GetMainFrame();
98 main_frame->Send( 132 main_frame->Send(
99 new ChromeFrameMsg_GetWebApplicationInfo(main_frame->GetRoutingID())); 133 new ChromeFrameMsg_GetWebApplicationInfo(main_frame->GetRoutingID()));
100 } 134 }
101 135
136 AddToHomescreenDataFetcher::~AddToHomescreenDataFetcher() {}
137
102 void AddToHomescreenDataFetcher::OnDidGetWebApplicationInfo( 138 void AddToHomescreenDataFetcher::OnDidGetWebApplicationInfo(
103 const WebApplicationInfo& received_web_app_info) { 139 const WebApplicationInfo& received_web_app_info) {
104 is_waiting_for_web_application_info_ = false; 140 is_waiting_for_web_application_info_ = false;
105 if (!web_contents() || !weak_observer_) 141 if (!web_contents())
106 return; 142 return;
107 143
108 // Sanitize received_web_app_info. 144 // Sanitize received_web_app_info.
109 WebApplicationInfo web_app_info = received_web_app_info; 145 WebApplicationInfo web_app_info = received_web_app_info;
110 web_app_info.title = 146 web_app_info.title =
111 web_app_info.title.substr(0, chrome::kMaxMetaTagAttributeLength); 147 web_app_info.title.substr(0, chrome::kMaxMetaTagAttributeLength);
112 148
113 // Simply set the user-editable title to be the page's title 149 // Simply set the user-editable title to be the page's title
114 shortcut_info_.user_title = web_app_info.title.empty() 150 shortcut_info_.user_title = web_app_info.title.empty()
115 ? web_contents()->GetTitle() 151 ? web_contents()->GetTitle()
(...skipping 21 matching lines...) Expand all
137 case WebApplicationInfo::MOBILE_CAPABLE_UNSPECIFIED: 173 case WebApplicationInfo::MOBILE_CAPABLE_UNSPECIFIED:
138 base::RecordAction( 174 base::RecordAction(
139 base::UserMetricsAction("webapps.AddShortcut.Bookmark")); 175 base::UserMetricsAction("webapps.AddShortcut.Bookmark"));
140 break; 176 break;
141 } 177 }
142 178
143 // Kick off a timeout for downloading data. If we haven't finished within the 179 // Kick off a timeout for downloading data. If we haven't finished within the
144 // timeout, fall back to using a dynamically-generated launcher icon. 180 // timeout, fall back to using a dynamically-generated launcher icon.
145 data_timeout_timer_.Start( 181 data_timeout_timer_.Start(
146 FROM_HERE, base::TimeDelta::FromMilliseconds(data_timeout_ms_), 182 FROM_HERE, base::TimeDelta::FromMilliseconds(data_timeout_ms_),
147 base::Bind(&AddToHomescreenDataFetcher::OnDataTimedout, this)); 183 base::Bind(&AddToHomescreenDataFetcher::OnDataTimedout,
184 weak_ptr_factory_.GetWeakPtr()));
148 185
149 installable_manager_->GetData( 186 installable_manager_->GetData(
150 ParamsToPerformManifestAndIconFetch( 187 ParamsToPerformManifestAndIconFetch(
151 ideal_icon_size_in_px_, minimum_icon_size_in_px_, badge_size_in_px_, 188 ideal_icon_size_in_px_, minimum_icon_size_in_px_, badge_size_in_px_,
152 check_webapk_compatibility_), 189 check_webapk_compatibility_),
153 base::Bind(&AddToHomescreenDataFetcher::OnDidGetManifestAndIcons, this)); 190 base::Bind(&AddToHomescreenDataFetcher::OnDidGetManifestAndIcons,
154 } 191 weak_ptr_factory_.GetWeakPtr()));
155
156 AddToHomescreenDataFetcher::~AddToHomescreenDataFetcher() {
157 DCHECK(!weak_observer_);
158 } 192 }
159 193
160 bool AddToHomescreenDataFetcher::OnMessageReceived( 194 bool AddToHomescreenDataFetcher::OnMessageReceived(
161 const IPC::Message& message, 195 const IPC::Message& message,
162 content::RenderFrameHost* sender) { 196 content::RenderFrameHost* sender) {
163 if (!is_waiting_for_web_application_info_) 197 if (!is_waiting_for_web_application_info_)
164 return false; 198 return false;
165 199
166 bool handled = true; 200 bool handled = true;
167 201
168 IPC_BEGIN_MESSAGE_MAP(AddToHomescreenDataFetcher, message) 202 IPC_BEGIN_MESSAGE_MAP(AddToHomescreenDataFetcher, message)
169 IPC_MESSAGE_HANDLER(ChromeFrameHostMsg_DidGetWebApplicationInfo, 203 IPC_MESSAGE_HANDLER(ChromeFrameHostMsg_DidGetWebApplicationInfo,
170 OnDidGetWebApplicationInfo) 204 OnDidGetWebApplicationInfo)
171 IPC_MESSAGE_UNHANDLED(handled = false) 205 IPC_MESSAGE_UNHANDLED(handled = false)
172 IPC_END_MESSAGE_MAP() 206 IPC_END_MESSAGE_MAP()
173 207
174 return handled; 208 return handled;
175 } 209 }
176 210
177 void AddToHomescreenDataFetcher::OnDataTimedout() { 211 void AddToHomescreenDataFetcher::OnDataTimedout() {
178 if (!web_contents() || !weak_observer_) 212 weak_ptr_factory_.InvalidateWeakPtrs();
213
214 if (!web_contents())
179 return; 215 return;
180 216
181 if (!is_installable_check_complete_) { 217 if (check_webapk_compatibility_)
182 is_installable_check_complete_ = true; 218 observer_->OnDidDetermineWebApkCompatibility(false);
183 if (check_webapk_compatibility_) 219 observer_->OnUserTitleAvailable(shortcut_info_.user_title);
184 weak_observer_->OnDidDetermineWebApkCompatibility(false);
185 weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title);
186 }
187 220
188 CreateLauncherIcon(raw_primary_icon_); 221 CreateLauncherIcon(raw_primary_icon_);
189 } 222 }
190 223
191 void AddToHomescreenDataFetcher::OnDidGetManifestAndIcons( 224 void AddToHomescreenDataFetcher::OnDidGetManifestAndIcons(
192 const InstallableData& data) { 225 const InstallableData& data) {
193 if (!web_contents() || !weak_observer_ || is_installable_check_complete_) 226 if (!web_contents())
194 return; 227 return;
195 228
196 if (!data.manifest.IsEmpty()) { 229 if (!data.manifest.IsEmpty()) {
197 base::RecordAction(base::UserMetricsAction("webapps.AddShortcut.Manifest")); 230 base::RecordAction(base::UserMetricsAction("webapps.AddShortcut.Manifest"));
198 shortcut_info_.UpdateFromManifest(data.manifest); 231 shortcut_info_.UpdateFromManifest(data.manifest);
199 shortcut_info_.manifest_url = data.manifest_url; 232 shortcut_info_.manifest_url = data.manifest_url;
200 } 233 }
201 234
202 // Do this after updating from the manifest for the case where a site has 235 // Do this after updating from the manifest for the case where a site has
203 // a manifest with name and standalone specified, but no icons. 236 // a manifest with name and standalone specified, but no icons.
204 if (data.manifest.IsEmpty() || !data.primary_icon) { 237 if (data.manifest.IsEmpty() || !data.primary_icon) {
205 if (check_webapk_compatibility_) 238 if (check_webapk_compatibility_)
206 weak_observer_->OnDidDetermineWebApkCompatibility(false); 239 observer_->OnDidDetermineWebApkCompatibility(false);
207 weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title); 240 observer_->OnUserTitleAvailable(shortcut_info_.user_title);
208 data_timeout_timer_.Stop(); 241 data_timeout_timer_.Stop();
209 FetchFavicon(); 242 FetchFavicon();
210 return; 243 return;
211 } 244 }
212 245
213 raw_primary_icon_ = *data.primary_icon; 246 raw_primary_icon_ = *data.primary_icon;
214 shortcut_info_.best_primary_icon_url = data.primary_icon_url; 247 shortcut_info_.best_primary_icon_url = data.primary_icon_url;
215 248
216 // Save the splash screen URL for the later download. 249 // Save the splash screen URL for the later download.
217 shortcut_info_.splash_image_url = 250 shortcut_info_.splash_image_url =
218 content::ManifestIconSelector::FindBestMatchingIcon( 251 content::ManifestIconSelector::FindBestMatchingIcon(
219 data.manifest.icons, ideal_splash_image_size_in_px_, 252 data.manifest.icons, ideal_splash_image_size_in_px_,
220 minimum_splash_image_size_in_px_, 253 minimum_splash_image_size_in_px_,
221 content::Manifest::Icon::IconPurpose::ANY); 254 content::Manifest::Icon::IconPurpose::ANY);
222 shortcut_info_.ideal_splash_image_size_in_px = ideal_splash_image_size_in_px_; 255 shortcut_info_.ideal_splash_image_size_in_px = ideal_splash_image_size_in_px_;
223 shortcut_info_.minimum_splash_image_size_in_px = 256 shortcut_info_.minimum_splash_image_size_in_px =
224 minimum_splash_image_size_in_px_; 257 minimum_splash_image_size_in_px_;
225 if (data.badge_icon) { 258 if (data.badge_icon) {
226 shortcut_info_.best_badge_icon_url = data.badge_icon_url; 259 shortcut_info_.best_badge_icon_url = data.badge_icon_url;
227 badge_icon_ = *data.badge_icon; 260 badge_icon_ = *data.badge_icon;
228 } 261 }
229 262
230 installable_manager_->GetData( 263 installable_manager_->GetData(
231 ParamsToPerformInstallableCheck(check_webapk_compatibility_), 264 ParamsToPerformInstallableCheck(check_webapk_compatibility_),
232 base::Bind(&AddToHomescreenDataFetcher::OnDidPerformInstallableCheck, 265 base::Bind(&AddToHomescreenDataFetcher::OnDidPerformInstallableCheck,
233 this)); 266 weak_ptr_factory_.GetWeakPtr()));
234 } 267 }
235 268
236 void AddToHomescreenDataFetcher::OnDidPerformInstallableCheck( 269 void AddToHomescreenDataFetcher::OnDidPerformInstallableCheck(
237 const InstallableData& data) { 270 const InstallableData& data) {
238 data_timeout_timer_.Stop(); 271 data_timeout_timer_.Stop();
239 272
240 if (!web_contents() || !weak_observer_ || is_installable_check_complete_) 273 if (!web_contents())
241 return; 274 return;
242 275
243 is_installable_check_complete_ = true;
244
245 bool webapk_compatible = false; 276 bool webapk_compatible = false;
246 if (check_webapk_compatibility_) { 277 if (check_webapk_compatibility_) {
247 webapk_compatible = 278 webapk_compatible =
248 (data.error_code == NO_ERROR_DETECTED && data.is_installable && 279 (data.error_code == NO_ERROR_DETECTED && data.is_installable &&
249 AreWebManifestUrlsWebApkCompatible(data.manifest)); 280 AreWebManifestUrlsWebApkCompatible(data.manifest));
250 weak_observer_->OnDidDetermineWebApkCompatibility(webapk_compatible); 281 observer_->OnDidDetermineWebApkCompatibility(webapk_compatible);
251 } 282 }
252 283
253 weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title); 284 observer_->OnUserTitleAvailable(shortcut_info_.user_title);
254 if (webapk_compatible) { 285 if (webapk_compatible) {
255 shortcut_info_.UpdateSource(ShortcutInfo::SOURCE_ADD_TO_HOMESCREEN_PWA); 286 shortcut_info_.UpdateSource(ShortcutInfo::SOURCE_ADD_TO_HOMESCREEN_PWA);
256 NotifyObserver(raw_primary_icon_); 287 NotifyObserver(std::make_pair(raw_primary_icon_, false /* is_generated */));
257 } else { 288 } else {
258 CreateLauncherIcon(raw_primary_icon_); 289 CreateLauncherIcon(raw_primary_icon_);
259 } 290 }
260 } 291 }
261 292
262 void AddToHomescreenDataFetcher::FetchFavicon() { 293 void AddToHomescreenDataFetcher::FetchFavicon() {
263 if (!web_contents() || !weak_observer_) 294 if (!web_contents())
264 return; 295 return;
265 296
266 // Grab the best, largest icon we can find to represent this bookmark. 297 // Grab the best, largest icon we can find to represent this bookmark.
267 // TODO(dfalcantara): Try combining with the new BookmarksHandler once its 298 // TODO(dfalcantara): Try combining with the new BookmarksHandler once its
268 // rewrite is further along. 299 // rewrite is further along.
269 std::vector<int> icon_types{ 300 std::vector<int> icon_types{
270 favicon_base::WEB_MANIFEST_ICON, favicon_base::FAVICON, 301 favicon_base::WEB_MANIFEST_ICON, favicon_base::FAVICON,
271 favicon_base::TOUCH_PRECOMPOSED_ICON | favicon_base::TOUCH_ICON}; 302 favicon_base::TOUCH_PRECOMPOSED_ICON | favicon_base::TOUCH_ICON};
272 303
273 favicon::FaviconService* favicon_service = 304 favicon::FaviconService* favicon_service =
274 FaviconServiceFactory::GetForProfile( 305 FaviconServiceFactory::GetForProfile(
275 Profile::FromBrowserContext(web_contents()->GetBrowserContext()), 306 Profile::FromBrowserContext(web_contents()->GetBrowserContext()),
276 ServiceAccessType::EXPLICIT_ACCESS); 307 ServiceAccessType::EXPLICIT_ACCESS);
277 308
278 // Using favicon if its size is not smaller than platform required size, 309 // Using favicon if its size is not smaller than platform required size,
279 // otherwise using the largest icon among all avaliable icons. 310 // otherwise using the largest icon among all avaliable icons.
280 int threshold_to_get_any_largest_icon = ideal_icon_size_in_px_ - 1; 311 int threshold_to_get_any_largest_icon = ideal_icon_size_in_px_ - 1;
281 favicon_service->GetLargestRawFaviconForPageURL( 312 favicon_service->GetLargestRawFaviconForPageURL(
282 shortcut_info_.url, icon_types, threshold_to_get_any_largest_icon, 313 shortcut_info_.url, icon_types, threshold_to_get_any_largest_icon,
283 base::Bind(&AddToHomescreenDataFetcher::OnFaviconFetched, this), 314 base::Bind(&AddToHomescreenDataFetcher::OnFaviconFetched,
315 weak_ptr_factory_.GetWeakPtr()),
284 &favicon_task_tracker_); 316 &favicon_task_tracker_);
285 } 317 }
286 318
287 void AddToHomescreenDataFetcher::OnFaviconFetched( 319 void AddToHomescreenDataFetcher::OnFaviconFetched(
288 const favicon_base::FaviconRawBitmapResult& bitmap_result) { 320 const favicon_base::FaviconRawBitmapResult& bitmap_result) {
289 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 321 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
290 322
291 if (!web_contents() || !weak_observer_) 323 if (!web_contents())
292 return; 324 return;
293 325
326 shortcut_info_.best_primary_icon_url = bitmap_result.icon_url;
327
294 // The user is waiting for the icon to be processed before they can proceed 328 // The user is waiting for the icon to be processed before they can proceed
295 // with add to homescreen. But if we shut down, there's no point starting the 329 // with add to homescreen. But if we shut down, there's no point starting the
296 // image processing. Use USER_VISIBLE with MayBlock and SKIP_ON_SHUTDOWN. 330 // image processing. Use USER_VISIBLE with MayBlock and SKIP_ON_SHUTDOWN.
297 base::PostTaskWithTraitsAndReplyWithResult( 331 base::PostTaskWithTraitsAndReplyWithResult(
298 FROM_HERE, 332 FROM_HERE,
299 {base::MayBlock(), base::TaskPriority::USER_VISIBLE, 333 {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
300 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, 334 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
301 base::BindOnce(&AddToHomescreenDataFetcher:: 335 base::BindOnce(&CreateLauncherIconFromFaviconInBackground,
302 CreateLauncherIconFromFaviconInBackground, 336 shortcut_info_.url, bitmap_result),
303 base::Unretained(this), bitmap_result),
304 base::BindOnce(&AddToHomescreenDataFetcher::NotifyObserver, 337 base::BindOnce(&AddToHomescreenDataFetcher::NotifyObserver,
305 base::RetainedRef(this))); 338 weak_ptr_factory_.GetWeakPtr()));
306 }
307
308 SkBitmap AddToHomescreenDataFetcher::CreateLauncherIconFromFaviconInBackground(
309 const favicon_base::FaviconRawBitmapResult& bitmap_result) {
310 base::ThreadRestrictions::AssertIOAllowed();
311
312 if (bitmap_result.is_valid()) {
313 gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(),
314 bitmap_result.bitmap_data->size(),
315 &raw_primary_icon_);
316 }
317
318 shortcut_info_.best_primary_icon_url = bitmap_result.icon_url;
319 return CreateLauncherIconInBackground(raw_primary_icon_);
320 } 339 }
321 340
322 void AddToHomescreenDataFetcher::CreateLauncherIcon(const SkBitmap& icon) { 341 void AddToHomescreenDataFetcher::CreateLauncherIcon(const SkBitmap& icon) {
323 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 342 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
324 343
325 // The user is waiting for the icon to be processed before they can proceed 344 // The user is waiting for the icon to be processed before they can proceed
326 // with add to homescreen. But if we shut down, there's no point starting the 345 // with add to homescreen. But if we shut down, there's no point starting the
327 // image processing. Use USER_VISIBLE with MayBlock and SKIP_ON_SHUTDOWN. 346 // image processing. Use USER_VISIBLE with MayBlock and SKIP_ON_SHUTDOWN.
328 base::PostTaskWithTraitsAndReplyWithResult( 347 base::PostTaskWithTraitsAndReplyWithResult(
329 FROM_HERE, 348 FROM_HERE,
330 {base::MayBlock(), base::TaskPriority::USER_VISIBLE, 349 {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
331 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, 350 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
332 base::BindOnce( 351 base::BindOnce(&CreateLauncherIconInBackground, shortcut_info_.url, icon),
333 &AddToHomescreenDataFetcher::CreateLauncherIconInBackground,
334 base::Unretained(this), icon),
335 base::BindOnce(&AddToHomescreenDataFetcher::NotifyObserver, 352 base::BindOnce(&AddToHomescreenDataFetcher::NotifyObserver,
336 base::RetainedRef(this))); 353 weak_ptr_factory_.GetWeakPtr()));
337 } 354 }
338 355
339 SkBitmap AddToHomescreenDataFetcher::CreateLauncherIconInBackground( 356 void AddToHomescreenDataFetcher::NotifyObserver(
340 const SkBitmap& icon) { 357 const std::pair<SkBitmap, bool /*is_generated*/>& primary_icon) {
341 base::ThreadRestrictions::AssertIOAllowed();
342
343 SkBitmap primary_icon;
344 bool is_generated = false;
345 if (weak_observer_) {
346 primary_icon = weak_observer_->FinalizeLauncherIconInBackground(
347 icon, shortcut_info_.url, &is_generated);
348 }
349
350 if (is_generated)
351 shortcut_info_.best_primary_icon_url = GURL();
352
353 return primary_icon;
354 }
355
356 void AddToHomescreenDataFetcher::NotifyObserver(const SkBitmap& primary_icon) {
357 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 358 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
358 if (!web_contents() || !weak_observer_) 359 if (!web_contents())
359 return; 360 return;
360 361
361 primary_icon_ = primary_icon; 362 primary_icon_ = primary_icon.first;
362 weak_observer_->OnDataAvailable(shortcut_info_, primary_icon_, badge_icon_); 363 if (primary_icon.second)
364 shortcut_info_.best_primary_icon_url = GURL();
365 observer_->OnDataAvailable(shortcut_info_, primary_icon_, badge_icon_);
363 } 366 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698