| 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 |