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

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

Issue 2949993002: Don't ignore manifest icons for sites that don't have a service worker. (Closed)
Patch Set: Fix up icon handling Created 3 years, 6 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"
(...skipping 30 matching lines...) Expand all
41 const int kDataTimeoutInMilliseconds = 4000; 41 const int kDataTimeoutInMilliseconds = 4000;
42 42
43 // Looks up the original, online URL of the site requested. The URL from the 43 // Looks up the original, online URL of the site requested. The URL from the
44 // WebContents may be a distilled article which is not appropriate for a home 44 // WebContents may be a distilled article which is not appropriate for a home
45 // screen shortcut. 45 // screen shortcut.
46 GURL GetShortcutUrl(content::BrowserContext* browser_context, 46 GURL GetShortcutUrl(content::BrowserContext* browser_context,
47 const GURL& actual_url) { 47 const GURL& actual_url) {
48 return dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl(actual_url); 48 return dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl(actual_url);
49 } 49 }
50 50
51 InstallableParams ParamsToPerformManifestAndIconFetch(
52 int ideal_icon_size_in_px,
53 int minimum_icon_size_in_px) {
54 InstallableParams params;
55 params.ideal_primary_icon_size_in_px = ideal_icon_size_in_px;
56 params.minimum_primary_icon_size_in_px = minimum_icon_size_in_px;
57 params.fetch_valid_primary_icon = true;
58 return params;
59 }
60
51 InstallableParams ParamsToPerformInstallableCheck( 61 InstallableParams ParamsToPerformInstallableCheck(
52 int ideal_icon_size_in_px, 62 int ideal_icon_size_in_px,
53 int minimum_icon_size_in_px, 63 int minimum_icon_size_in_px,
54 int badge_size_in_px, 64 int badge_size_in_px,
55 bool check_webapk_compatibility) { 65 bool check_webapk_compatibility) {
56 InstallableParams params; 66 InstallableParams params = ParamsToPerformManifestAndIconFetch(
57 params.ideal_primary_icon_size_in_px = ideal_icon_size_in_px; 67 ideal_icon_size_in_px, minimum_icon_size_in_px);
58 params.minimum_primary_icon_size_in_px = minimum_icon_size_in_px;
59 params.check_installable = check_webapk_compatibility;
60 params.fetch_valid_primary_icon = true;
61 if (check_webapk_compatibility) { 68 if (check_webapk_compatibility) {
69 params.check_installable = check_webapk_compatibility;
62 params.ideal_badge_icon_size_in_px = badge_size_in_px; 70 params.ideal_badge_icon_size_in_px = badge_size_in_px;
63 params.minimum_badge_icon_size_in_px = badge_size_in_px; 71 params.minimum_badge_icon_size_in_px = badge_size_in_px;
64 params.fetch_valid_badge_icon = true; 72 params.fetch_valid_badge_icon = true;
65 } 73 }
66 return params; 74 return params;
67 } 75 }
68 76
69 } // namespace 77 } // namespace
70 78
71 AddToHomescreenDataFetcher::AddToHomescreenDataFetcher( 79 AddToHomescreenDataFetcher::AddToHomescreenDataFetcher(
72 content::WebContents* web_contents, 80 content::WebContents* web_contents,
73 int ideal_icon_size_in_px, 81 int ideal_icon_size_in_px,
74 int minimum_icon_size_in_px, 82 int minimum_icon_size_in_px,
75 int ideal_splash_image_size_in_px, 83 int ideal_splash_image_size_in_px,
76 int minimum_splash_image_size_in_px, 84 int minimum_splash_image_size_in_px,
77 int badge_size_in_px, 85 int badge_size_in_px,
78 bool check_webapk_compatibility, 86 bool check_webapk_compatibility,
79 Observer* observer) 87 Observer* observer)
80 : WebContentsObserver(web_contents), 88 : WebContentsObserver(web_contents),
81 background_task_runner_( 89 background_task_runner_(
82 content::BrowserThread::GetBlockingPool() 90 content::BrowserThread::GetBlockingPool()
83 ->GetTaskRunnerWithShutdownBehavior( 91 ->GetTaskRunnerWithShutdownBehavior(
84 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), 92 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
93 installable_manager_(InstallableManager::FromWebContents(web_contents)),
85 weak_observer_(observer), 94 weak_observer_(observer),
86 shortcut_info_(GetShortcutUrl(web_contents->GetBrowserContext(), 95 shortcut_info_(GetShortcutUrl(web_contents->GetBrowserContext(),
87 web_contents->GetLastCommittedURL())), 96 web_contents->GetLastCommittedURL())),
88 ideal_icon_size_in_px_(ideal_icon_size_in_px), 97 ideal_icon_size_in_px_(ideal_icon_size_in_px),
89 minimum_icon_size_in_px_(minimum_icon_size_in_px), 98 minimum_icon_size_in_px_(minimum_icon_size_in_px),
90 ideal_splash_image_size_in_px_(ideal_splash_image_size_in_px), 99 ideal_splash_image_size_in_px_(ideal_splash_image_size_in_px),
91 minimum_splash_image_size_in_px_(minimum_splash_image_size_in_px), 100 minimum_splash_image_size_in_px_(minimum_splash_image_size_in_px),
92 badge_size_in_px_(badge_size_in_px), 101 badge_size_in_px_(badge_size_in_px),
93 check_webapk_compatibility_(check_webapk_compatibility), 102 check_webapk_compatibility_(check_webapk_compatibility),
94 is_waiting_for_web_application_info_(true), 103 is_waiting_for_web_application_info_(true),
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 case WebApplicationInfo::MOBILE_CAPABLE_APPLE: 146 case WebApplicationInfo::MOBILE_CAPABLE_APPLE:
138 base::RecordAction( 147 base::RecordAction(
139 base::UserMetricsAction("webapps.AddShortcut.AppShortcutApple")); 148 base::UserMetricsAction("webapps.AddShortcut.AppShortcutApple"));
140 break; 149 break;
141 case WebApplicationInfo::MOBILE_CAPABLE_UNSPECIFIED: 150 case WebApplicationInfo::MOBILE_CAPABLE_UNSPECIFIED:
142 base::RecordAction( 151 base::RecordAction(
143 base::UserMetricsAction("webapps.AddShortcut.Bookmark")); 152 base::UserMetricsAction("webapps.AddShortcut.Bookmark"));
144 break; 153 break;
145 } 154 }
146 155
147 InstallableManager::CreateForWebContents(web_contents());
148 InstallableManager* manager =
149 InstallableManager::FromWebContents(web_contents());
150 DCHECK(manager);
151
152 // Kick off a timeout for downloading data. If we haven't finished within the 156 // Kick off a timeout for downloading data. If we haven't finished within the
153 // timeout, fall back to using a dynamically-generated launcher icon. 157 // timeout, fall back to using a dynamically-generated launcher icon.
154 data_timeout_timer_.Start( 158 data_timeout_timer_.Start(
155 FROM_HERE, base::TimeDelta::FromMilliseconds(kDataTimeoutInMilliseconds), 159 FROM_HERE, base::TimeDelta::FromMilliseconds(kDataTimeoutInMilliseconds),
156 base::Bind(&AddToHomescreenDataFetcher::OnDataTimedout, this)); 160 base::Bind(&AddToHomescreenDataFetcher::OnDataTimedout, this));
157 161
158 manager->GetData( 162 installable_manager_->GetData(
159 ParamsToPerformInstallableCheck(ideal_icon_size_in_px_, 163 ParamsToPerformManifestAndIconFetch(ideal_icon_size_in_px_,
160 minimum_icon_size_in_px_, 164 minimum_icon_size_in_px_),
161 badge_size_in_px_, 165 base::Bind(&AddToHomescreenDataFetcher::OnDidGetManifestAndIcon, this));
162 check_webapk_compatibility_),
163 base::Bind(&AddToHomescreenDataFetcher::OnDidPerformInstallableCheck,
164 this));
165 } 166 }
166 167
167 AddToHomescreenDataFetcher::~AddToHomescreenDataFetcher() { 168 AddToHomescreenDataFetcher::~AddToHomescreenDataFetcher() {
168 DCHECK(!weak_observer_); 169 DCHECK(!weak_observer_);
169 } 170 }
170 171
171 bool AddToHomescreenDataFetcher::OnMessageReceived( 172 bool AddToHomescreenDataFetcher::OnMessageReceived(
172 const IPC::Message& message, 173 const IPC::Message& message,
173 content::RenderFrameHost* sender) { 174 content::RenderFrameHost* sender) {
174 if (!is_waiting_for_web_application_info_) 175 if (!is_waiting_for_web_application_info_)
(...skipping 15 matching lines...) Expand all
190 return; 191 return;
191 192
192 if (!is_installable_check_complete_) { 193 if (!is_installable_check_complete_) {
193 is_installable_check_complete_ = true; 194 is_installable_check_complete_ = true;
194 if (check_webapk_compatibility_) 195 if (check_webapk_compatibility_)
195 weak_observer_->OnDidDetermineWebApkCompatibility(false); 196 weak_observer_->OnDidDetermineWebApkCompatibility(false);
196 weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title); 197 weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title);
197 } 198 }
198 199
199 badge_icon_.reset(); 200 badge_icon_.reset();
200 CreateLauncherIcon(SkBitmap()); 201 CreateLauncherIcon(raw_icon_);
pkotwicz 2017/06/22 17:49:27 We should probably rename |raw_icon_| to |primary_
dominickn 2017/06/23 01:52:03 Done.
202 }
203
204 void AddToHomescreenDataFetcher::OnDidGetManifestAndIcon(
205 const InstallableData& data) {
206 if (!web_contents() || !weak_observer_ || is_installable_check_complete_)
207 return;
208
209 if (!data.manifest.IsEmpty()) {
210 base::RecordAction(base::UserMetricsAction("webapps.AddShortcut.Manifest"));
211 shortcut_info_.UpdateFromManifest(data.manifest);
212 shortcut_info_.manifest_url = data.manifest_url;
213
214 if (data.primary_icon && !data.primary_icon->drawsNothing()) {
pkotwicz 2017/06/22 17:49:27 Nit: Based on InstallableManager::OnIconFetched(),
dominickn 2017/06/23 01:52:03 Good point, can't even remember code that I wrote.
215 raw_icon_ = *data.primary_icon;
216 shortcut_info_.best_primary_icon_url = data.primary_icon_url;
217
218 // Save the splash screen URL for the later download.
219 shortcut_info_.splash_image_url =
220 content::ManifestIconSelector::FindBestMatchingIcon(
221 data.manifest.icons, ideal_splash_image_size_in_px_,
222 minimum_splash_image_size_in_px_,
223 content::Manifest::Icon::IconPurpose::ANY);
224 shortcut_info_.ideal_splash_image_size_in_px =
225 ideal_splash_image_size_in_px_;
226 shortcut_info_.minimum_splash_image_size_in_px =
227 minimum_splash_image_size_in_px_;
228 }
229 }
230
231 installable_manager_->GetData(
232 ParamsToPerformInstallableCheck(
233 ideal_icon_size_in_px_, minimum_icon_size_in_px_, badge_size_in_px_,
234 check_webapk_compatibility_),
235 base::Bind(&AddToHomescreenDataFetcher::OnDidPerformInstallableCheck,
236 this));
201 } 237 }
202 238
203 void AddToHomescreenDataFetcher::OnDidPerformInstallableCheck( 239 void AddToHomescreenDataFetcher::OnDidPerformInstallableCheck(
204 const InstallableData& data) { 240 const InstallableData& data) {
205 data_timeout_timer_.Stop(); 241 data_timeout_timer_.Stop();
206 badge_icon_.reset(); 242 badge_icon_.reset();
207 243
208 if (!web_contents() || !weak_observer_ || is_installable_check_complete_) 244 if (!web_contents() || !weak_observer_ || is_installable_check_complete_)
209 return; 245 return;
210 246
211 is_installable_check_complete_ = true; 247 is_installable_check_complete_ = true;
212 248
213 bool webapk_compatible = false; 249 bool webapk_compatible = false;
214 if (check_webapk_compatibility_) { 250 if (check_webapk_compatibility_) {
215 webapk_compatible = (data.error_code == NO_ERROR_DETECTED && 251 webapk_compatible = (data.error_code == NO_ERROR_DETECTED &&
216 AreWebManifestUrlsWebApkCompatible(data.manifest)); 252 AreWebManifestUrlsWebApkCompatible(data.manifest));
pkotwicz 2017/06/22 17:49:27 I think that it might be more intuitive if ParamsT
dominickn 2017/06/23 01:52:04 That won't work: setting check_installable to true
pkotwicz 2017/06/23 19:23:18 Sorry for the confusion. I meant it would be more
pkotwicz 2017/06/23 19:30:45 Oh, I see you have in fact made this change :)
dominickn 2017/06/26 02:39:16 When WebAPKs are enabled by default we'll always w
217 weak_observer_->OnDidDetermineWebApkCompatibility(webapk_compatible); 253 weak_observer_->OnDidDetermineWebApkCompatibility(webapk_compatible);
254 }
218 255
219 if (webapk_compatible) { 256 if (webapk_compatible) {
220 // WebAPKs are wholly defined by the Web Manifest. Ignore the <meta> tag 257 shortcut_info_.UpdateSource(ShortcutInfo::SOURCE_ADD_TO_HOMESCREEN_PWA);
221 // data received in OnDidGetWebApplicationInfo(). 258
222 shortcut_info_ = ShortcutInfo(GURL()); 259 if (data.badge_icon && !data.badge_icon->drawsNothing()) {
260 shortcut_info_.best_badge_icon_url = data.badge_icon_url;
261 badge_icon_ = *data.badge_icon;
223 } 262 }
224 } 263 }
225 264
226 if (!data.manifest.IsEmpty()) {
227 base::RecordAction(base::UserMetricsAction("webapps.AddShortcut.Manifest"));
228 shortcut_info_.UpdateFromManifest(data.manifest);
229 shortcut_info_.manifest_url = data.manifest_url;
230
231 if (webapk_compatible) {
232 shortcut_info_.UpdateSource(ShortcutInfo::SOURCE_ADD_TO_HOMESCREEN_PWA);
233
234 if (data.badge_icon && !data.badge_icon->drawsNothing()) {
235 shortcut_info_.best_badge_icon_url = data.badge_icon_url;
236 badge_icon_ = *data.badge_icon;
237 }
238 }
239 }
240
241 // Save the splash screen URL for the later download.
242 shortcut_info_.splash_image_url =
243 content::ManifestIconSelector::FindBestMatchingIcon(
244 data.manifest.icons, ideal_splash_image_size_in_px_,
245 minimum_splash_image_size_in_px_,
246 content::Manifest::Icon::IconPurpose::ANY);
247 shortcut_info_.ideal_splash_image_size_in_px = ideal_splash_image_size_in_px_;
248 shortcut_info_.minimum_splash_image_size_in_px =
249 minimum_splash_image_size_in_px_;
250
251 weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title); 265 weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title);
252 266
253 if (data.primary_icon) { 267 if (!raw_icon_.drawsNothing()) {
254 shortcut_info_.best_primary_icon_url = data.primary_icon_url;
255
256 if (webapk_compatible) 268 if (webapk_compatible)
257 NotifyObserver(*data.primary_icon); 269 NotifyObserver(raw_icon_);
258 else 270 else
259 CreateLauncherIcon(*(data.primary_icon)); 271 CreateLauncherIcon(raw_icon_);
260 return; 272 return;
261 } 273 }
262 274
263 FetchFavicon(); 275 FetchFavicon();
264 } 276 }
265 277
266 void AddToHomescreenDataFetcher::FetchFavicon() { 278 void AddToHomescreenDataFetcher::FetchFavicon() {
267 if (!web_contents() || !weak_observer_) 279 if (!web_contents() || !weak_observer_)
268 return; 280 return;
269 281
(...skipping 29 matching lines...) Expand all
299 CreateLauncherIconFromFaviconInBackground, 311 CreateLauncherIconFromFaviconInBackground,
300 base::Unretained(this), bitmap_result), 312 base::Unretained(this), bitmap_result),
301 base::Bind(&AddToHomescreenDataFetcher::NotifyObserver, 313 base::Bind(&AddToHomescreenDataFetcher::NotifyObserver,
302 base::RetainedRef(this))); 314 base::RetainedRef(this)));
303 } 315 }
304 316
305 SkBitmap AddToHomescreenDataFetcher::CreateLauncherIconFromFaviconInBackground( 317 SkBitmap AddToHomescreenDataFetcher::CreateLauncherIconFromFaviconInBackground(
306 const favicon_base::FaviconRawBitmapResult& bitmap_result) { 318 const favicon_base::FaviconRawBitmapResult& bitmap_result) {
307 base::ThreadRestrictions::AssertIOAllowed(); 319 base::ThreadRestrictions::AssertIOAllowed();
308 320
309 SkBitmap raw_icon;
310 if (bitmap_result.is_valid()) { 321 if (bitmap_result.is_valid()) {
311 gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(), 322 gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(),
312 bitmap_result.bitmap_data->size(), &raw_icon); 323 bitmap_result.bitmap_data->size(), &raw_icon_);
313 } 324 }
314 325
315 shortcut_info_.best_primary_icon_url = bitmap_result.icon_url; 326 shortcut_info_.best_primary_icon_url = bitmap_result.icon_url;
316 return CreateLauncherIconInBackground(raw_icon); 327 return CreateLauncherIconInBackground(raw_icon_);
317 } 328 }
318 329
319 void AddToHomescreenDataFetcher::CreateLauncherIcon(const SkBitmap& raw_icon) { 330 void AddToHomescreenDataFetcher::CreateLauncherIcon(const SkBitmap& icon) {
320 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 331 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
321 base::PostTaskAndReplyWithResult( 332 base::PostTaskAndReplyWithResult(
322 background_task_runner_.get(), FROM_HERE, 333 background_task_runner_.get(), FROM_HERE,
323 base::Bind(&AddToHomescreenDataFetcher::CreateLauncherIconInBackground, 334 base::Bind(&AddToHomescreenDataFetcher::CreateLauncherIconInBackground,
324 base::Unretained(this), raw_icon), 335 base::Unretained(this), icon),
325 base::Bind(&AddToHomescreenDataFetcher::NotifyObserver, 336 base::Bind(&AddToHomescreenDataFetcher::NotifyObserver,
326 base::RetainedRef(this))); 337 base::RetainedRef(this)));
327 } 338 }
328 339
329 SkBitmap AddToHomescreenDataFetcher::CreateLauncherIconInBackground( 340 SkBitmap AddToHomescreenDataFetcher::CreateLauncherIconInBackground(
330 const SkBitmap& raw_icon) { 341 const SkBitmap& icon) {
331 base::ThreadRestrictions::AssertIOAllowed(); 342 base::ThreadRestrictions::AssertIOAllowed();
332 343
333 SkBitmap primary_icon; 344 SkBitmap primary_icon;
334 bool is_generated = false; 345 bool is_generated = false;
335 if (weak_observer_) { 346 if (weak_observer_) {
336 primary_icon = weak_observer_->FinalizeLauncherIconInBackground( 347 primary_icon = weak_observer_->FinalizeLauncherIconInBackground(
337 raw_icon, shortcut_info_.url, &is_generated); 348 icon, shortcut_info_.url, &is_generated);
338 } 349 }
339 350
340 if (is_generated) 351 if (is_generated)
341 shortcut_info_.best_primary_icon_url = GURL(); 352 shortcut_info_.best_primary_icon_url = GURL();
342 353
343 return primary_icon; 354 return primary_icon;
344 } 355 }
345 356
346 void AddToHomescreenDataFetcher::NotifyObserver(const SkBitmap& primary_icon) { 357 void AddToHomescreenDataFetcher::NotifyObserver(const SkBitmap& primary_icon) {
347 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 358 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
348 if (!web_contents() || !weak_observer_ || is_icon_saved_) 359 if (!web_contents() || !weak_observer_ || is_icon_saved_)
349 return; 360 return;
350 361
351 is_icon_saved_ = true; 362 is_icon_saved_ = true;
352 primary_icon_ = primary_icon; 363 primary_icon_ = primary_icon;
353 weak_observer_->OnDataAvailable(shortcut_info_, primary_icon_, badge_icon_); 364 weak_observer_->OnDataAvailable(shortcut_info_, primary_icon_, badge_icon_);
354 } 365 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698