OLD | NEW |
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" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "content/public/browser/render_frame_host.h" | 25 #include "content/public/browser/render_frame_host.h" |
26 #include "content/public/browser/web_contents.h" | 26 #include "content/public/browser/web_contents.h" |
27 #include "content/public/common/manifest.h" | 27 #include "content/public/common/manifest.h" |
28 #include "third_party/WebKit/public/platform/modules/screen_orientation/WebScree
nOrientationLockType.h" | 28 #include "third_party/WebKit/public/platform/modules/screen_orientation/WebScree
nOrientationLockType.h" |
29 #include "ui/gfx/codec/png_codec.h" | 29 #include "ui/gfx/codec/png_codec.h" |
30 #include "ui/gfx/favicon_size.h" | 30 #include "ui/gfx/favicon_size.h" |
31 #include "url/gurl.h" | 31 #include "url/gurl.h" |
32 | 32 |
33 namespace { | 33 namespace { |
34 | 34 |
35 // The default number of milliseconds to wait for the data download to complete. | |
36 const int kDataTimeoutInMilliseconds = 4000; | |
37 | |
38 // Looks up the original, online URL of the site requested. The URL from the | 35 // Looks up the original, online URL of the site requested. The URL from the |
39 // WebContents may be a distilled article which is not appropriate for a home | 36 // WebContents may be a distilled article which is not appropriate for a home |
40 // screen shortcut. | 37 // screen shortcut. |
41 GURL GetShortcutUrl(content::BrowserContext* browser_context, | 38 GURL GetShortcutUrl(content::BrowserContext* browser_context, |
42 const GURL& actual_url) { | 39 const GURL& actual_url) { |
43 return dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl(actual_url); | 40 return dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl(actual_url); |
44 } | 41 } |
45 | 42 |
46 InstallableParams ParamsToPerformInstallableCheck( | 43 InstallableParams ParamsToPerformManifestAndIconFetch( |
47 int ideal_icon_size_in_px, | 44 int ideal_icon_size_in_px, |
48 int minimum_icon_size_in_px, | 45 int minimum_icon_size_in_px, |
49 int badge_size_in_px, | 46 int badge_size_in_px, |
50 bool check_webapk_compatibility) { | 47 bool check_webapk_compatibility) { |
51 InstallableParams params; | 48 InstallableParams params; |
52 params.ideal_primary_icon_size_in_px = ideal_icon_size_in_px; | 49 params.ideal_primary_icon_size_in_px = ideal_icon_size_in_px; |
53 params.minimum_primary_icon_size_in_px = minimum_icon_size_in_px; | 50 params.minimum_primary_icon_size_in_px = minimum_icon_size_in_px; |
54 params.check_installable = check_webapk_compatibility; | |
55 params.fetch_valid_primary_icon = true; | 51 params.fetch_valid_primary_icon = true; |
56 if (check_webapk_compatibility) { | 52 if (check_webapk_compatibility) { |
| 53 params.fetch_valid_badge_icon = true; |
57 params.ideal_badge_icon_size_in_px = badge_size_in_px; | 54 params.ideal_badge_icon_size_in_px = badge_size_in_px; |
58 params.minimum_badge_icon_size_in_px = badge_size_in_px; | 55 params.minimum_badge_icon_size_in_px = badge_size_in_px; |
59 params.fetch_valid_badge_icon = true; | |
60 } | 56 } |
61 return params; | 57 return params; |
62 } | 58 } |
63 | 59 |
| 60 InstallableParams ParamsToPerformInstallableCheck( |
| 61 bool check_webapk_compatibility) { |
| 62 InstallableParams params; |
| 63 params.check_installable = check_webapk_compatibility; |
| 64 return params; |
| 65 } |
| 66 |
64 } // namespace | 67 } // namespace |
65 | 68 |
66 AddToHomescreenDataFetcher::AddToHomescreenDataFetcher( | 69 AddToHomescreenDataFetcher::AddToHomescreenDataFetcher( |
67 content::WebContents* web_contents, | 70 content::WebContents* web_contents, |
68 int ideal_icon_size_in_px, | 71 int ideal_icon_size_in_px, |
69 int minimum_icon_size_in_px, | 72 int minimum_icon_size_in_px, |
70 int ideal_splash_image_size_in_px, | 73 int ideal_splash_image_size_in_px, |
71 int minimum_splash_image_size_in_px, | 74 int minimum_splash_image_size_in_px, |
72 int badge_size_in_px, | 75 int badge_size_in_px, |
| 76 int data_timeout_ms, |
73 bool check_webapk_compatibility, | 77 bool check_webapk_compatibility, |
74 Observer* observer) | 78 Observer* observer) |
75 : content::WebContentsObserver(web_contents), | 79 : content::WebContentsObserver(web_contents), |
| 80 installable_manager_(InstallableManager::FromWebContents(web_contents)), |
76 weak_observer_(observer), | 81 weak_observer_(observer), |
77 shortcut_info_(GetShortcutUrl(web_contents->GetBrowserContext(), | 82 shortcut_info_(GetShortcutUrl(web_contents->GetBrowserContext(), |
78 web_contents->GetLastCommittedURL())), | 83 web_contents->GetLastCommittedURL())), |
79 ideal_icon_size_in_px_(ideal_icon_size_in_px), | 84 ideal_icon_size_in_px_(ideal_icon_size_in_px), |
80 minimum_icon_size_in_px_(minimum_icon_size_in_px), | 85 minimum_icon_size_in_px_(minimum_icon_size_in_px), |
81 ideal_splash_image_size_in_px_(ideal_splash_image_size_in_px), | 86 ideal_splash_image_size_in_px_(ideal_splash_image_size_in_px), |
82 minimum_splash_image_size_in_px_(minimum_splash_image_size_in_px), | 87 minimum_splash_image_size_in_px_(minimum_splash_image_size_in_px), |
83 badge_size_in_px_(badge_size_in_px), | 88 badge_size_in_px_(badge_size_in_px), |
| 89 data_timeout_ms_(data_timeout_ms), |
84 check_webapk_compatibility_(check_webapk_compatibility), | 90 check_webapk_compatibility_(check_webapk_compatibility), |
85 is_waiting_for_web_application_info_(true), | 91 is_waiting_for_web_application_info_(true), |
86 is_installable_check_complete_(false), | 92 is_installable_check_complete_(false) { |
87 is_icon_saved_(false) { | |
88 DCHECK(minimum_icon_size_in_px <= ideal_icon_size_in_px); | 93 DCHECK(minimum_icon_size_in_px <= ideal_icon_size_in_px); |
89 DCHECK(minimum_splash_image_size_in_px <= ideal_splash_image_size_in_px); | 94 DCHECK(minimum_splash_image_size_in_px <= ideal_splash_image_size_in_px); |
90 | 95 |
91 // Send a message to the renderer to retrieve information about the page. | 96 // Send a message to the renderer to retrieve information about the page. |
92 content::RenderFrameHost* main_frame = web_contents->GetMainFrame(); | 97 content::RenderFrameHost* main_frame = web_contents->GetMainFrame(); |
93 main_frame->Send( | 98 main_frame->Send( |
94 new ChromeFrameMsg_GetWebApplicationInfo(main_frame->GetRoutingID())); | 99 new ChromeFrameMsg_GetWebApplicationInfo(main_frame->GetRoutingID())); |
95 } | 100 } |
96 | 101 |
97 void AddToHomescreenDataFetcher::OnDidGetWebApplicationInfo( | 102 void AddToHomescreenDataFetcher::OnDidGetWebApplicationInfo( |
(...skipping 30 matching lines...) Expand all Loading... |
128 case WebApplicationInfo::MOBILE_CAPABLE_APPLE: | 133 case WebApplicationInfo::MOBILE_CAPABLE_APPLE: |
129 base::RecordAction( | 134 base::RecordAction( |
130 base::UserMetricsAction("webapps.AddShortcut.AppShortcutApple")); | 135 base::UserMetricsAction("webapps.AddShortcut.AppShortcutApple")); |
131 break; | 136 break; |
132 case WebApplicationInfo::MOBILE_CAPABLE_UNSPECIFIED: | 137 case WebApplicationInfo::MOBILE_CAPABLE_UNSPECIFIED: |
133 base::RecordAction( | 138 base::RecordAction( |
134 base::UserMetricsAction("webapps.AddShortcut.Bookmark")); | 139 base::UserMetricsAction("webapps.AddShortcut.Bookmark")); |
135 break; | 140 break; |
136 } | 141 } |
137 | 142 |
138 InstallableManager::CreateForWebContents(web_contents()); | |
139 InstallableManager* manager = | |
140 InstallableManager::FromWebContents(web_contents()); | |
141 DCHECK(manager); | |
142 | |
143 // Kick off a timeout for downloading data. If we haven't finished within the | 143 // 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. | 144 // timeout, fall back to using a dynamically-generated launcher icon. |
145 data_timeout_timer_.Start( | 145 data_timeout_timer_.Start( |
146 FROM_HERE, base::TimeDelta::FromMilliseconds(kDataTimeoutInMilliseconds), | 146 FROM_HERE, base::TimeDelta::FromMilliseconds(data_timeout_ms_), |
147 base::Bind(&AddToHomescreenDataFetcher::OnDataTimedout, this)); | 147 base::Bind(&AddToHomescreenDataFetcher::OnDataTimedout, this)); |
148 | 148 |
149 manager->GetData( | 149 installable_manager_->GetData( |
150 ParamsToPerformInstallableCheck(ideal_icon_size_in_px_, | 150 ParamsToPerformManifestAndIconFetch( |
151 minimum_icon_size_in_px_, | 151 ideal_icon_size_in_px_, minimum_icon_size_in_px_, badge_size_in_px_, |
152 badge_size_in_px_, | 152 check_webapk_compatibility_), |
153 check_webapk_compatibility_), | 153 base::Bind(&AddToHomescreenDataFetcher::OnDidGetManifestAndIcons, this)); |
154 base::Bind(&AddToHomescreenDataFetcher::OnDidPerformInstallableCheck, | |
155 this)); | |
156 } | 154 } |
157 | 155 |
158 AddToHomescreenDataFetcher::~AddToHomescreenDataFetcher() { | 156 AddToHomescreenDataFetcher::~AddToHomescreenDataFetcher() { |
159 DCHECK(!weak_observer_); | 157 DCHECK(!weak_observer_); |
160 } | 158 } |
161 | 159 |
162 bool AddToHomescreenDataFetcher::OnMessageReceived( | 160 bool AddToHomescreenDataFetcher::OnMessageReceived( |
163 const IPC::Message& message, | 161 const IPC::Message& message, |
164 content::RenderFrameHost* sender) { | 162 content::RenderFrameHost* sender) { |
165 if (!is_waiting_for_web_application_info_) | 163 if (!is_waiting_for_web_application_info_) |
(...skipping 14 matching lines...) Expand all Loading... |
180 if (!web_contents() || !weak_observer_) | 178 if (!web_contents() || !weak_observer_) |
181 return; | 179 return; |
182 | 180 |
183 if (!is_installable_check_complete_) { | 181 if (!is_installable_check_complete_) { |
184 is_installable_check_complete_ = true; | 182 is_installable_check_complete_ = true; |
185 if (check_webapk_compatibility_) | 183 if (check_webapk_compatibility_) |
186 weak_observer_->OnDidDetermineWebApkCompatibility(false); | 184 weak_observer_->OnDidDetermineWebApkCompatibility(false); |
187 weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title); | 185 weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title); |
188 } | 186 } |
189 | 187 |
190 badge_icon_.reset(); | 188 CreateLauncherIcon(raw_primary_icon_); |
191 CreateLauncherIcon(SkBitmap()); | |
192 } | 189 } |
193 | 190 |
194 void AddToHomescreenDataFetcher::OnDidPerformInstallableCheck( | 191 void AddToHomescreenDataFetcher::OnDidGetManifestAndIcons( |
195 const InstallableData& data) { | 192 const InstallableData& data) { |
196 data_timeout_timer_.Stop(); | |
197 badge_icon_.reset(); | |
198 | |
199 if (!web_contents() || !weak_observer_ || is_installable_check_complete_) | 193 if (!web_contents() || !weak_observer_ || is_installable_check_complete_) |
200 return; | 194 return; |
201 | 195 |
202 is_installable_check_complete_ = true; | |
203 | |
204 bool webapk_compatible = false; | |
205 if (check_webapk_compatibility_) { | |
206 webapk_compatible = (data.error_code == NO_ERROR_DETECTED && | |
207 AreWebManifestUrlsWebApkCompatible(data.manifest)); | |
208 weak_observer_->OnDidDetermineWebApkCompatibility(webapk_compatible); | |
209 | |
210 if (webapk_compatible) { | |
211 // WebAPKs are wholly defined by the Web Manifest. Ignore the <meta> tag | |
212 // data received in OnDidGetWebApplicationInfo(). | |
213 shortcut_info_ = ShortcutInfo(GURL()); | |
214 } | |
215 } | |
216 | |
217 if (!data.manifest.IsEmpty()) { | 196 if (!data.manifest.IsEmpty()) { |
218 base::RecordAction(base::UserMetricsAction("webapps.AddShortcut.Manifest")); | 197 base::RecordAction(base::UserMetricsAction("webapps.AddShortcut.Manifest")); |
219 shortcut_info_.UpdateFromManifest(data.manifest); | 198 shortcut_info_.UpdateFromManifest(data.manifest); |
220 shortcut_info_.manifest_url = data.manifest_url; | 199 shortcut_info_.manifest_url = data.manifest_url; |
| 200 } |
221 | 201 |
222 if (webapk_compatible) { | 202 // Do this after updating from the manifest for the case where a site has |
223 shortcut_info_.UpdateSource(ShortcutInfo::SOURCE_ADD_TO_HOMESCREEN_PWA); | 203 // a manifest with name and standalone specified, but no icons. |
| 204 if (data.manifest.IsEmpty() || !data.primary_icon) { |
| 205 if (check_webapk_compatibility_) |
| 206 weak_observer_->OnDidDetermineWebApkCompatibility(false); |
| 207 weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title); |
| 208 data_timeout_timer_.Stop(); |
| 209 FetchFavicon(); |
| 210 return; |
| 211 } |
224 | 212 |
225 if (data.badge_icon && !data.badge_icon->drawsNothing()) { | 213 raw_primary_icon_ = *data.primary_icon; |
226 shortcut_info_.best_badge_icon_url = data.badge_icon_url; | 214 shortcut_info_.best_primary_icon_url = data.primary_icon_url; |
227 badge_icon_ = *data.badge_icon; | |
228 } | |
229 } | |
230 } | |
231 | 215 |
232 // Save the splash screen URL for the later download. | 216 // Save the splash screen URL for the later download. |
233 shortcut_info_.splash_image_url = | 217 shortcut_info_.splash_image_url = |
234 content::ManifestIconSelector::FindBestMatchingIcon( | 218 content::ManifestIconSelector::FindBestMatchingIcon( |
235 data.manifest.icons, ideal_splash_image_size_in_px_, | 219 data.manifest.icons, ideal_splash_image_size_in_px_, |
236 minimum_splash_image_size_in_px_, | 220 minimum_splash_image_size_in_px_, |
237 content::Manifest::Icon::IconPurpose::ANY); | 221 content::Manifest::Icon::IconPurpose::ANY); |
238 shortcut_info_.ideal_splash_image_size_in_px = ideal_splash_image_size_in_px_; | 222 shortcut_info_.ideal_splash_image_size_in_px = ideal_splash_image_size_in_px_; |
239 shortcut_info_.minimum_splash_image_size_in_px = | 223 shortcut_info_.minimum_splash_image_size_in_px = |
240 minimum_splash_image_size_in_px_; | 224 minimum_splash_image_size_in_px_; |
| 225 if (data.badge_icon) { |
| 226 shortcut_info_.best_badge_icon_url = data.badge_icon_url; |
| 227 badge_icon_ = *data.badge_icon; |
| 228 } |
| 229 |
| 230 installable_manager_->GetData( |
| 231 ParamsToPerformInstallableCheck(check_webapk_compatibility_), |
| 232 base::Bind(&AddToHomescreenDataFetcher::OnDidPerformInstallableCheck, |
| 233 this)); |
| 234 } |
| 235 |
| 236 void AddToHomescreenDataFetcher::OnDidPerformInstallableCheck( |
| 237 const InstallableData& data) { |
| 238 data_timeout_timer_.Stop(); |
| 239 |
| 240 if (!web_contents() || !weak_observer_ || is_installable_check_complete_) |
| 241 return; |
| 242 |
| 243 is_installable_check_complete_ = true; |
| 244 |
| 245 bool webapk_compatible = false; |
| 246 if (check_webapk_compatibility_) { |
| 247 webapk_compatible = |
| 248 (data.error_code == NO_ERROR_DETECTED && data.is_installable && |
| 249 AreWebManifestUrlsWebApkCompatible(data.manifest)); |
| 250 weak_observer_->OnDidDetermineWebApkCompatibility(webapk_compatible); |
| 251 } |
241 | 252 |
242 weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title); | 253 weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title); |
243 | 254 if (webapk_compatible) { |
244 if (data.primary_icon) { | 255 shortcut_info_.UpdateSource(ShortcutInfo::SOURCE_ADD_TO_HOMESCREEN_PWA); |
245 shortcut_info_.best_primary_icon_url = data.primary_icon_url; | 256 NotifyObserver(raw_primary_icon_); |
246 | 257 } else { |
247 if (webapk_compatible) | 258 CreateLauncherIcon(raw_primary_icon_); |
248 NotifyObserver(*data.primary_icon); | |
249 else | |
250 CreateLauncherIcon(*(data.primary_icon)); | |
251 return; | |
252 } | 259 } |
253 | |
254 FetchFavicon(); | |
255 } | 260 } |
256 | 261 |
257 void AddToHomescreenDataFetcher::FetchFavicon() { | 262 void AddToHomescreenDataFetcher::FetchFavicon() { |
258 if (!web_contents() || !weak_observer_) | 263 if (!web_contents() || !weak_observer_) |
259 return; | 264 return; |
260 | 265 |
261 // Grab the best, largest icon we can find to represent this bookmark. | 266 // Grab the best, largest icon we can find to represent this bookmark. |
262 // TODO(dfalcantara): Try combining with the new BookmarksHandler once its | 267 // TODO(dfalcantara): Try combining with the new BookmarksHandler once its |
263 // rewrite is further along. | 268 // rewrite is further along. |
264 std::vector<int> icon_types{ | 269 std::vector<int> icon_types{ |
(...skipping 11 matching lines...) Expand all Loading... |
276 favicon_service->GetLargestRawFaviconForPageURL( | 281 favicon_service->GetLargestRawFaviconForPageURL( |
277 shortcut_info_.url, icon_types, threshold_to_get_any_largest_icon, | 282 shortcut_info_.url, icon_types, threshold_to_get_any_largest_icon, |
278 base::Bind(&AddToHomescreenDataFetcher::OnFaviconFetched, this), | 283 base::Bind(&AddToHomescreenDataFetcher::OnFaviconFetched, this), |
279 &favicon_task_tracker_); | 284 &favicon_task_tracker_); |
280 } | 285 } |
281 | 286 |
282 void AddToHomescreenDataFetcher::OnFaviconFetched( | 287 void AddToHomescreenDataFetcher::OnFaviconFetched( |
283 const favicon_base::FaviconRawBitmapResult& bitmap_result) { | 288 const favicon_base::FaviconRawBitmapResult& bitmap_result) { |
284 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 289 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
285 | 290 |
286 if (!web_contents() || !weak_observer_ || is_icon_saved_) | 291 if (!web_contents() || !weak_observer_) |
287 return; | 292 return; |
288 | 293 |
289 // The user is waiting for the icon to be processed before they can proceed | 294 // The user is waiting for the icon to be processed before they can proceed |
290 // with add to homescreen. But if we shut down, there's no point starting the | 295 // with add to homescreen. But if we shut down, there's no point starting the |
291 // image processing. Use USER_VISIBLE with MayBlock and SKIP_ON_SHUTDOWN. | 296 // image processing. Use USER_VISIBLE with MayBlock and SKIP_ON_SHUTDOWN. |
292 base::PostTaskWithTraitsAndReplyWithResult( | 297 base::PostTaskWithTraitsAndReplyWithResult( |
293 FROM_HERE, | 298 FROM_HERE, |
294 {base::MayBlock(), base::TaskPriority::USER_VISIBLE, | 299 {base::MayBlock(), base::TaskPriority::USER_VISIBLE, |
295 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, | 300 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, |
296 base::BindOnce(&AddToHomescreenDataFetcher:: | 301 base::BindOnce(&AddToHomescreenDataFetcher:: |
297 CreateLauncherIconFromFaviconInBackground, | 302 CreateLauncherIconFromFaviconInBackground, |
298 base::Unretained(this), bitmap_result), | 303 base::Unretained(this), bitmap_result), |
299 base::BindOnce(&AddToHomescreenDataFetcher::NotifyObserver, | 304 base::BindOnce(&AddToHomescreenDataFetcher::NotifyObserver, |
300 base::RetainedRef(this))); | 305 base::RetainedRef(this))); |
301 } | 306 } |
302 | 307 |
303 SkBitmap AddToHomescreenDataFetcher::CreateLauncherIconFromFaviconInBackground( | 308 SkBitmap AddToHomescreenDataFetcher::CreateLauncherIconFromFaviconInBackground( |
304 const favicon_base::FaviconRawBitmapResult& bitmap_result) { | 309 const favicon_base::FaviconRawBitmapResult& bitmap_result) { |
305 base::ThreadRestrictions::AssertIOAllowed(); | 310 base::ThreadRestrictions::AssertIOAllowed(); |
306 | 311 |
307 SkBitmap raw_icon; | |
308 if (bitmap_result.is_valid()) { | 312 if (bitmap_result.is_valid()) { |
309 gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(), | 313 gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(), |
310 bitmap_result.bitmap_data->size(), &raw_icon); | 314 bitmap_result.bitmap_data->size(), |
| 315 &raw_primary_icon_); |
311 } | 316 } |
312 | 317 |
313 shortcut_info_.best_primary_icon_url = bitmap_result.icon_url; | 318 shortcut_info_.best_primary_icon_url = bitmap_result.icon_url; |
314 return CreateLauncherIconInBackground(raw_icon); | 319 return CreateLauncherIconInBackground(raw_primary_icon_); |
315 } | 320 } |
316 | 321 |
317 void AddToHomescreenDataFetcher::CreateLauncherIcon(const SkBitmap& raw_icon) { | 322 void AddToHomescreenDataFetcher::CreateLauncherIcon(const SkBitmap& icon) { |
318 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 323 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
319 | 324 |
320 // The user is waiting for the icon to be processed before they can proceed | 325 // The user is waiting for the icon to be processed before they can proceed |
321 // with add to homescreen. But if we shut down, there's no point starting the | 326 // with add to homescreen. But if we shut down, there's no point starting the |
322 // image processing. Use USER_VISIBLE with MayBlock and SKIP_ON_SHUTDOWN. | 327 // image processing. Use USER_VISIBLE with MayBlock and SKIP_ON_SHUTDOWN. |
323 base::PostTaskWithTraitsAndReplyWithResult( | 328 base::PostTaskWithTraitsAndReplyWithResult( |
324 FROM_HERE, | 329 FROM_HERE, |
325 {base::MayBlock(), base::TaskPriority::USER_VISIBLE, | 330 {base::MayBlock(), base::TaskPriority::USER_VISIBLE, |
326 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, | 331 base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, |
327 base::BindOnce( | 332 base::BindOnce( |
328 &AddToHomescreenDataFetcher::CreateLauncherIconInBackground, | 333 &AddToHomescreenDataFetcher::CreateLauncherIconInBackground, |
329 base::Unretained(this), raw_icon), | 334 base::Unretained(this), icon), |
330 base::BindOnce(&AddToHomescreenDataFetcher::NotifyObserver, | 335 base::BindOnce(&AddToHomescreenDataFetcher::NotifyObserver, |
331 base::RetainedRef(this))); | 336 base::RetainedRef(this))); |
332 } | 337 } |
333 | 338 |
334 SkBitmap AddToHomescreenDataFetcher::CreateLauncherIconInBackground( | 339 SkBitmap AddToHomescreenDataFetcher::CreateLauncherIconInBackground( |
335 const SkBitmap& raw_icon) { | 340 const SkBitmap& icon) { |
336 base::ThreadRestrictions::AssertIOAllowed(); | 341 base::ThreadRestrictions::AssertIOAllowed(); |
337 | 342 |
338 SkBitmap primary_icon; | 343 SkBitmap primary_icon; |
339 bool is_generated = false; | 344 bool is_generated = false; |
340 if (weak_observer_) { | 345 if (weak_observer_) { |
341 primary_icon = weak_observer_->FinalizeLauncherIconInBackground( | 346 primary_icon = weak_observer_->FinalizeLauncherIconInBackground( |
342 raw_icon, shortcut_info_.url, &is_generated); | 347 icon, shortcut_info_.url, &is_generated); |
343 } | 348 } |
344 | 349 |
345 if (is_generated) | 350 if (is_generated) |
346 shortcut_info_.best_primary_icon_url = GURL(); | 351 shortcut_info_.best_primary_icon_url = GURL(); |
347 | 352 |
348 return primary_icon; | 353 return primary_icon; |
349 } | 354 } |
350 | 355 |
351 void AddToHomescreenDataFetcher::NotifyObserver(const SkBitmap& primary_icon) { | 356 void AddToHomescreenDataFetcher::NotifyObserver(const SkBitmap& primary_icon) { |
352 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 357 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
353 if (!web_contents() || !weak_observer_ || is_icon_saved_) | 358 if (!web_contents() || !weak_observer_) |
354 return; | 359 return; |
355 | 360 |
356 is_icon_saved_ = true; | |
357 primary_icon_ = primary_icon; | 361 primary_icon_ = primary_icon; |
358 weak_observer_->OnDataAvailable(shortcut_info_, primary_icon_, badge_icon_); | 362 weak_observer_->OnDataAvailable(shortcut_info_, primary_icon_, badge_icon_); |
359 } | 363 } |
OLD | NEW |