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

Side by Side Diff: chrome/browser/installable/installable_manager.cc

Issue 2942513002: Allow banners to trigger on sites which don't register a service worker onload. (Closed)
Patch Set: Fix crashing Android test. Comments 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 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 "chrome/browser/installable/installable_manager.h" 5 #include "chrome/browser/installable/installable_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "chrome/browser/manifest/manifest_icon_downloader.h" 10 #include "chrome/browser/manifest/manifest_icon_downloader.h"
11 #include "chrome/browser/manifest/manifest_icon_selector.h" 11 #include "chrome/browser/manifest/manifest_icon_selector.h"
12 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ssl/security_state_tab_helper.h" 13 #include "chrome/browser/ssl/security_state_tab_helper.h"
14 #include "components/security_state/core/security_state.h" 14 #include "components/security_state/core/security_state.h"
15 #include "content/public/browser/browser_context.h" 15 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/navigation_handle.h" 17 #include "content/public/browser/navigation_handle.h"
18 #include "content/public/browser/service_worker_context.h"
19 #include "content/public/browser/storage_partition.h" 18 #include "content/public/browser/storage_partition.h"
20 #include "net/base/url_util.h" 19 #include "net/base/url_util.h"
21 #include "third_party/WebKit/public/platform/WebDisplayMode.h" 20 #include "third_party/WebKit/public/platform/WebDisplayMode.h"
22 21
23 using IconPurpose = content::Manifest::Icon::IconPurpose; 22 using IconPurpose = content::Manifest::Icon::IconPurpose;
24 23
25 namespace { 24 namespace {
26 25
27 const char kPngExtension[] = ".png"; 26 const char kPngExtension[] = ".png";
28 27
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 69
71 DEFINE_WEB_CONTENTS_USER_DATA_KEY(InstallableManager); 70 DEFINE_WEB_CONTENTS_USER_DATA_KEY(InstallableManager);
72 71
73 struct InstallableManager::ManifestProperty { 72 struct InstallableManager::ManifestProperty {
74 InstallableStatusCode error = NO_ERROR_DETECTED; 73 InstallableStatusCode error = NO_ERROR_DETECTED;
75 GURL url; 74 GURL url;
76 content::Manifest manifest; 75 content::Manifest manifest;
77 bool fetched = false; 76 bool fetched = false;
78 }; 77 };
79 78
80 struct InstallableManager::InstallableProperty { 79 struct InstallableManager::ValidManifestProperty {
81 InstallableStatusCode error = NO_ERROR_DETECTED; 80 InstallableStatusCode error = NO_ERROR_DETECTED;
82 bool installable = false; 81 bool is_valid = false;
83 bool fetched = false; 82 bool fetched = false;
84 }; 83 };
85 84
85 struct InstallableManager::ServiceWorkerProperty {
86 InstallableStatusCode error = NO_ERROR_DETECTED;
87 bool has_worker = false;
88 bool is_waiting = false;
89 bool fetched = false;
90 };
91
86 struct InstallableManager::IconProperty { 92 struct InstallableManager::IconProperty {
87 IconProperty() : 93 IconProperty() :
88 error(NO_ERROR_DETECTED), url(), icon(), fetched(false) { } 94 error(NO_ERROR_DETECTED), url(), icon(), fetched(false) { }
89 IconProperty(IconProperty&& other) = default; 95 IconProperty(IconProperty&& other) = default;
90 IconProperty& operator=(IconProperty&& other) = default; 96 IconProperty& operator=(IconProperty&& other) = default;
91 97
92 InstallableStatusCode error = NO_ERROR_DETECTED; 98 InstallableStatusCode error = NO_ERROR_DETECTED;
93 GURL url; 99 GURL url;
94 std::unique_ptr<SkBitmap> icon; 100 std::unique_ptr<SkBitmap> icon;
95 bool fetched; 101 bool fetched;
96 102
97 private: 103 private:
98 // This class contains a std::unique_ptr and therefore must be move-only. 104 // This class contains a std::unique_ptr and therefore must be move-only.
99 DISALLOW_COPY_AND_ASSIGN(IconProperty); 105 DISALLOW_COPY_AND_ASSIGN(IconProperty);
100 }; 106 };
101 107
102 InstallableManager::InstallableManager(content::WebContents* web_contents) 108 InstallableManager::InstallableManager(content::WebContents* web_contents)
103 : content::WebContentsObserver(web_contents), 109 : content::WebContentsObserver(web_contents),
104 manifest_(new ManifestProperty()), 110 manifest_(base::MakeUnique<ManifestProperty>()),
105 installable_(new InstallableProperty()), 111 valid_manifest_(base::MakeUnique<ValidManifestProperty>()),
112 worker_(base::MakeUnique<ServiceWorkerProperty>()),
113 service_worker_context_(nullptr),
106 page_status_(InstallabilityCheckStatus::NOT_STARTED), 114 page_status_(InstallabilityCheckStatus::NOT_STARTED),
107 menu_open_count_(0), 115 menu_open_count_(0),
108 menu_item_add_to_homescreen_count_(0), 116 menu_item_add_to_homescreen_count_(0),
109 is_active_(false), 117 is_active_(false),
110 is_pwa_check_complete_(false), 118 is_pwa_check_complete_(false),
111 weak_factory_(this) {} 119 weak_factory_(this) {
120 // This is null in unit tests.
121 if (web_contents) {
122 content::StoragePartition* storage_partition =
123 content::BrowserContext::GetStoragePartition(
124 Profile::FromBrowserContext(web_contents->GetBrowserContext()),
125 web_contents->GetSiteInstance());
126 DCHECK(storage_partition);
112 127
113 InstallableManager::~InstallableManager() = default; 128 service_worker_context_ = storage_partition->GetServiceWorkerContext();
129 service_worker_context_->AddObserver(this);
130 }
131 }
132
133 InstallableManager::~InstallableManager() {
134 // Null in unit tests.
135 if (service_worker_context_)
136 service_worker_context_->RemoveObserver(this);
137 }
114 138
115 // static 139 // static
116 bool InstallableManager::IsContentSecure(content::WebContents* web_contents) { 140 bool InstallableManager::IsContentSecure(content::WebContents* web_contents) {
117 if (!web_contents) 141 if (!web_contents)
118 return false; 142 return false;
119 143
120 // Whitelist localhost. Check the VisibleURL to match what the 144 // Whitelist localhost. Check the VisibleURL to match what the
121 // SecurityStateTabHelper looks at. 145 // SecurityStateTabHelper looks at.
122 if (net::IsLocalhost(web_contents->GetVisibleURL().HostNoBrackets())) 146 if (net::IsLocalhost(web_contents->GetVisibleURL().HostNoBrackets()))
123 return true; 147 return true;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 246
223 void InstallableManager::SetIconFetched(const IconParams& params) { 247 void InstallableManager::SetIconFetched(const IconParams& params) {
224 icons_[params].fetched = true; 248 icons_[params].fetched = true;
225 } 249 }
226 250
227 InstallableStatusCode InstallableManager::GetErrorCode( 251 InstallableStatusCode InstallableManager::GetErrorCode(
228 const InstallableParams& params) { 252 const InstallableParams& params) {
229 if (manifest_->error != NO_ERROR_DETECTED) 253 if (manifest_->error != NO_ERROR_DETECTED)
230 return manifest_->error; 254 return manifest_->error;
231 255
232 if (params.check_installable && installable_->error != NO_ERROR_DETECTED) 256 if (params.check_installable) {
233 return installable_->error; 257 if (valid_manifest_->error != NO_ERROR_DETECTED)
258 return valid_manifest_->error;
259 if (worker_->error != NO_ERROR_DETECTED)
260 return worker_->error;
261 }
234 262
235 if (params.fetch_valid_primary_icon) { 263 if (params.fetch_valid_primary_icon) {
236 IconProperty& icon = icons_[ParamsForPrimaryIcon(params)]; 264 IconProperty& icon = icons_[ParamsForPrimaryIcon(params)];
237 if (icon.error != NO_ERROR_DETECTED) 265 if (icon.error != NO_ERROR_DETECTED)
238 return icon.error; 266 return icon.error;
239 } 267 }
240 268
241 if (params.fetch_valid_badge_icon) { 269 if (params.fetch_valid_badge_icon) {
242 IconProperty& icon = icons_[ParamsForBadgeIcon(params)]; 270 IconProperty& icon = icons_[ParamsForBadgeIcon(params)];
243 271
244 // If the error is NO_ACCEPTABLE_ICON, there is no icon suitable as a badge 272 // If the error is NO_ACCEPTABLE_ICON, there is no icon suitable as a badge
245 // in the manifest. Ignore this case since we only want to fail the check if 273 // in the manifest. Ignore this case since we only want to fail the check if
246 // there was a suitable badge icon specified and we couldn't fetch it. 274 // there was a suitable badge icon specified and we couldn't fetch it.
247 if (icon.error != NO_ERROR_DETECTED && icon.error != NO_ACCEPTABLE_ICON) 275 if (icon.error != NO_ERROR_DETECTED && icon.error != NO_ACCEPTABLE_ICON)
248 return icon.error; 276 return icon.error;
249 } 277 }
250 278
251 return NO_ERROR_DETECTED; 279 return NO_ERROR_DETECTED;
252 } 280 }
253 281
254 InstallableStatusCode InstallableManager::manifest_error() const { 282 InstallableStatusCode InstallableManager::manifest_error() const {
255 return manifest_->error; 283 return manifest_->error;
256 } 284 }
257 285
258 InstallableStatusCode InstallableManager::installable_error() const { 286 InstallableStatusCode InstallableManager::valid_manifest_error() const {
259 return installable_->error; 287 return valid_manifest_->error;
260 } 288 }
261 289
262 void InstallableManager::set_installable_error( 290 void InstallableManager::set_valid_manifest_error(
263 InstallableStatusCode error_code) { 291 InstallableStatusCode error_code) {
264 installable_->error = error_code; 292 valid_manifest_->error = error_code;
293 }
294
295 InstallableStatusCode InstallableManager::worker_error() const {
296 return worker_->error;
265 } 297 }
266 298
267 InstallableStatusCode InstallableManager::icon_error( 299 InstallableStatusCode InstallableManager::icon_error(
268 const IconParams& icon_params) { 300 const IconParams& icon_params) {
269 return icons_[icon_params].error; 301 return icons_[icon_params].error;
270 } 302 }
271 303
272 GURL& InstallableManager::icon_url(const IconParams& icon_params) { 304 GURL& InstallableManager::icon_url(const IconParams& icon_params) {
273 return icons_[icon_params].url; 305 return icons_[icon_params].url;
274 } 306 }
275 307
276 const SkBitmap* InstallableManager::icon(const IconParams& icon_params) { 308 const SkBitmap* InstallableManager::icon(const IconParams& icon_params) {
277 return icons_[icon_params].icon.get(); 309 return icons_[icon_params].icon.get();
278 } 310 }
279 311
280 content::WebContents* InstallableManager::GetWebContents() { 312 content::WebContents* InstallableManager::GetWebContents() {
281 content::WebContents* contents = web_contents(); 313 content::WebContents* contents = web_contents();
282 if (!contents || contents->IsBeingDestroyed()) 314 if (!contents || contents->IsBeingDestroyed())
283 return nullptr; 315 return nullptr;
284 return contents; 316 return contents;
285 } 317 }
286 318
287 bool InstallableManager::IsComplete(const InstallableParams& params) const { 319 bool InstallableManager::IsComplete(const InstallableParams& params) const {
288 // Returns true if for all resources: 320 // Returns true if for all resources:
289 // a. the params did not request it, OR 321 // a. the params did not request it, OR
290 // b. the resource has been fetched/checked. 322 // b. the resource has been fetched/checked.
291 return manifest_->fetched && 323 return manifest_->fetched &&
292 (!params.check_installable || installable_->fetched) && 324 (!params.check_installable ||
325 (valid_manifest_->fetched && worker_->fetched)) &&
293 (!params.fetch_valid_primary_icon || 326 (!params.fetch_valid_primary_icon ||
294 IsIconFetched(ParamsForPrimaryIcon(params))) && 327 IsIconFetched(ParamsForPrimaryIcon(params))) &&
295 (!params.fetch_valid_badge_icon || 328 (!params.fetch_valid_badge_icon ||
296 IsIconFetched(ParamsForBadgeIcon(params))); 329 IsIconFetched(ParamsForBadgeIcon(params)));
297 } 330 }
298 331
299 void InstallableManager::Reset() { 332 void InstallableManager::Reset() {
300 // Prevent any outstanding callbacks to or from this object from being called. 333 // Prevent any outstanding callbacks to or from this object from being called.
301 weak_factory_.InvalidateWeakPtrs(); 334 weak_factory_.InvalidateWeakPtrs();
302 tasks_.clear(); 335 tasks_.clear();
303 icons_.clear(); 336 icons_.clear();
304 337
305 // We may have reset prior to completion, in which case |menu_open_count_| or 338 // We may have reset prior to completion, in which case |menu_open_count_| or
306 // |menu_item_add_to_homescreen_count_| might be nonzero and |page_status_| is 339 // |menu_item_add_to_homescreen_count_| might be nonzero and |page_status_| is
307 // one of NOT_STARTED or NOT_COMPLETED. If we completed, then these values 340 // one of NOT_STARTED or NOT_COMPLETED. If we completed, then these values
308 // cannot be anything except 0. 341 // cannot be anything except 0.
309 is_pwa_check_complete_ = false; 342 is_pwa_check_complete_ = false;
310 343
311 for (; menu_open_count_ > 0; --menu_open_count_) 344 for (; menu_open_count_ > 0; --menu_open_count_)
312 InstallableMetrics::RecordMenuOpenHistogram(page_status_); 345 InstallableMetrics::RecordMenuOpenHistogram(page_status_);
313 346
314 for (; menu_item_add_to_homescreen_count_ > 0; 347 for (; menu_item_add_to_homescreen_count_ > 0;
315 --menu_item_add_to_homescreen_count_) { 348 --menu_item_add_to_homescreen_count_) {
316 InstallableMetrics::RecordMenuItemAddToHomescreenHistogram(page_status_); 349 InstallableMetrics::RecordMenuItemAddToHomescreenHistogram(page_status_);
317 } 350 }
318 351
319 page_status_ = InstallabilityCheckStatus::NOT_STARTED; 352 page_status_ = InstallabilityCheckStatus::NOT_STARTED;
320 manifest_.reset(new ManifestProperty()); 353 manifest_ = base::MakeUnique<ManifestProperty>();
321 installable_.reset(new InstallableProperty()); 354 valid_manifest_ = base::MakeUnique<ValidManifestProperty>();
355 worker_ = base::MakeUnique<ServiceWorkerProperty>();
322 356
323 is_active_ = false; 357 is_active_ = false;
324 } 358 }
325 359
326 void InstallableManager::SetManifestDependentTasksComplete() { 360 void InstallableManager::SetManifestDependentTasksComplete() {
327 DCHECK(!tasks_.empty()); 361 DCHECK(!tasks_.empty());
328 const InstallableParams& params = tasks_[0].first; 362 const InstallableParams& params = tasks_[0].first;
329 363
330 installable_->fetched = true; 364 valid_manifest_->fetched = true;
365 worker_->fetched = true;
331 SetIconFetched(ParamsForPrimaryIcon(params)); 366 SetIconFetched(ParamsForPrimaryIcon(params));
332 SetIconFetched(ParamsForBadgeIcon(params)); 367 SetIconFetched(ParamsForBadgeIcon(params));
333 } 368 }
334 369
335 void InstallableManager::RunCallback(const Task& task, 370 void InstallableManager::RunCallback(const Task& task,
336 InstallableStatusCode code) { 371 InstallableStatusCode code) {
337 const InstallableParams& params = task.first; 372 const InstallableParams& params = task.first;
338 IconProperty null_icon; 373 IconProperty null_icon;
339 IconProperty* primary_icon = &null_icon; 374 IconProperty* primary_icon = &null_icon;
340 IconProperty* badge_icon = &null_icon; 375 IconProperty* badge_icon = &null_icon;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 tasks_.erase(tasks_.begin()); 419 tasks_.erase(tasks_.begin());
385 StartNextTask(); 420 StartNextTask();
386 return; 421 return;
387 } 422 }
388 423
389 if (!manifest_->fetched) { 424 if (!manifest_->fetched) {
390 FetchManifest(); 425 FetchManifest();
391 } else if (params.fetch_valid_primary_icon && 426 } else if (params.fetch_valid_primary_icon &&
392 !IsIconFetched(ParamsForPrimaryIcon(params))) { 427 !IsIconFetched(ParamsForPrimaryIcon(params))) {
393 CheckAndFetchBestIcon(ParamsForPrimaryIcon(params)); 428 CheckAndFetchBestIcon(ParamsForPrimaryIcon(params));
394 } else if (params.check_installable && !installable_->fetched) { 429 } else if (params.check_installable && !valid_manifest_->fetched) {
395 CheckInstallable(); 430 CheckInstallable();
431 } else if (params.check_installable && !worker_->fetched) {
432 CheckServiceWorker();
396 } else if (params.fetch_valid_badge_icon && 433 } else if (params.fetch_valid_badge_icon &&
397 !IsIconFetched(ParamsForBadgeIcon(params))) { 434 !IsIconFetched(ParamsForBadgeIcon(params))) {
398 CheckAndFetchBestIcon(ParamsForBadgeIcon(params)); 435 CheckAndFetchBestIcon(ParamsForBadgeIcon(params));
399 } else { 436 } else {
400 NOTREACHED(); 437 NOTREACHED();
401 } 438 }
402 } 439 }
403 440
404 void InstallableManager::FetchManifest() { 441 void InstallableManager::FetchManifest() {
405 DCHECK(!manifest_->fetched); 442 DCHECK(!manifest_->fetched);
(...skipping 18 matching lines...) Expand all
424 SetManifestDependentTasksComplete(); 461 SetManifestDependentTasksComplete();
425 } 462 }
426 463
427 manifest_->url = manifest_url; 464 manifest_->url = manifest_url;
428 manifest_->manifest = manifest; 465 manifest_->manifest = manifest;
429 manifest_->fetched = true; 466 manifest_->fetched = true;
430 WorkOnTask(); 467 WorkOnTask();
431 } 468 }
432 469
433 void InstallableManager::CheckInstallable() { 470 void InstallableManager::CheckInstallable() {
434 DCHECK(!installable_->fetched); 471 DCHECK(!valid_manifest_->fetched);
435 DCHECK(!manifest().IsEmpty()); 472 DCHECK(!manifest().IsEmpty());
436 473
437 if (IsManifestValidForWebApp(manifest())) { 474 valid_manifest_->is_valid = IsManifestValidForWebApp(manifest());
438 CheckServiceWorker(); 475 valid_manifest_->fetched = true;
439 } else { 476 WorkOnTask();
440 installable_->installable = false;
441 installable_->fetched = true;
442 WorkOnTask();
443 }
444 } 477 }
445 478
446 bool InstallableManager::IsManifestValidForWebApp( 479 bool InstallableManager::IsManifestValidForWebApp(
447 const content::Manifest& manifest) { 480 const content::Manifest& manifest) {
448 if (manifest.IsEmpty()) { 481 if (manifest.IsEmpty()) {
449 installable_->error = MANIFEST_EMPTY; 482 valid_manifest_->error = MANIFEST_EMPTY;
450 return false; 483 return false;
451 } 484 }
452 485
453 if (!manifest.start_url.is_valid()) { 486 if (!manifest.start_url.is_valid()) {
454 installable_->error = START_URL_NOT_VALID; 487 valid_manifest_->error = START_URL_NOT_VALID;
455 return false; 488 return false;
456 } 489 }
457 490
458 if ((manifest.name.is_null() || manifest.name.string().empty()) && 491 if ((manifest.name.is_null() || manifest.name.string().empty()) &&
459 (manifest.short_name.is_null() || manifest.short_name.string().empty())) { 492 (manifest.short_name.is_null() || manifest.short_name.string().empty())) {
460 installable_->error = MANIFEST_MISSING_NAME_OR_SHORT_NAME; 493 valid_manifest_->error = MANIFEST_MISSING_NAME_OR_SHORT_NAME;
461 return false; 494 return false;
462 } 495 }
463 496
464 // TODO(dominickn,mlamouri): when Chrome supports "minimal-ui", it should be 497 // TODO(dominickn,mlamouri): when Chrome supports "minimal-ui", it should be
465 // accepted. If we accept it today, it would fallback to "browser" and make 498 // accepted. If we accept it today, it would fallback to "browser" and make
466 // this check moot. See https://crbug.com/604390. 499 // this check moot. See https://crbug.com/604390.
467 if (manifest.display != blink::kWebDisplayModeStandalone && 500 if (manifest.display != blink::kWebDisplayModeStandalone &&
468 manifest.display != blink::kWebDisplayModeFullscreen) { 501 manifest.display != blink::kWebDisplayModeFullscreen) {
469 installable_->error = MANIFEST_DISPLAY_NOT_SUPPORTED; 502 valid_manifest_->error = MANIFEST_DISPLAY_NOT_SUPPORTED;
470 return false; 503 return false;
471 } 504 }
472 505
473 if (!DoesManifestContainRequiredIcon(manifest)) { 506 if (!DoesManifestContainRequiredIcon(manifest)) {
474 installable_->error = MANIFEST_MISSING_SUITABLE_ICON; 507 valid_manifest_->error = MANIFEST_MISSING_SUITABLE_ICON;
475 return false; 508 return false;
476 } 509 }
477 510
478 return true; 511 return true;
479 } 512 }
480 513
481 void InstallableManager::CheckServiceWorker() { 514 void InstallableManager::CheckServiceWorker() {
482 DCHECK(!installable_->fetched); 515 DCHECK(!worker_->fetched);
483 DCHECK(!manifest().IsEmpty()); 516 DCHECK(!manifest().IsEmpty());
484 DCHECK(manifest().start_url.is_valid()); 517 DCHECK(manifest().start_url.is_valid());
485 518
486 content::WebContents* web_contents = GetWebContents();
487
488 // Check to see if there is a single service worker controlling this page 519 // Check to see if there is a single service worker controlling this page
489 // and the manifest's start url. 520 // and the manifest's start url.
490 content::StoragePartition* storage_partition = 521 service_worker_context_->CheckHasServiceWorker(
491 content::BrowserContext::GetStoragePartition( 522 GetWebContents()->GetLastCommittedURL(), manifest().start_url,
492 Profile::FromBrowserContext(web_contents->GetBrowserContext()),
493 web_contents->GetSiteInstance());
494 DCHECK(storage_partition);
495
496 storage_partition->GetServiceWorkerContext()->CheckHasServiceWorker(
497 web_contents->GetLastCommittedURL(), manifest().start_url,
498 base::Bind(&InstallableManager::OnDidCheckHasServiceWorker, 523 base::Bind(&InstallableManager::OnDidCheckHasServiceWorker,
499 weak_factory_.GetWeakPtr())); 524 weak_factory_.GetWeakPtr()));
500 } 525 }
501 526
502 void InstallableManager::OnDidCheckHasServiceWorker( 527 void InstallableManager::OnDidCheckHasServiceWorker(
503 content::ServiceWorkerCapability capability) { 528 content::ServiceWorkerCapability capability) {
504 if (!GetWebContents()) 529 if (!GetWebContents())
505 return; 530 return;
506 531
507 switch (capability) { 532 switch (capability) {
508 case content::ServiceWorkerCapability::SERVICE_WORKER_WITH_FETCH_HANDLER: 533 case content::ServiceWorkerCapability::SERVICE_WORKER_WITH_FETCH_HANDLER:
509 installable_->installable = true; 534 worker_->has_worker = true;
510 break; 535 break;
511 case content::ServiceWorkerCapability::SERVICE_WORKER_NO_FETCH_HANDLER: 536 case content::ServiceWorkerCapability::SERVICE_WORKER_NO_FETCH_HANDLER:
512 installable_->installable = false; 537 worker_->has_worker = false;
513 installable_->error = NOT_OFFLINE_CAPABLE; 538 worker_->error = NOT_OFFLINE_CAPABLE;
514 break; 539 break;
515 case content::ServiceWorkerCapability::NO_SERVICE_WORKER: 540 case content::ServiceWorkerCapability::NO_SERVICE_WORKER:
516 installable_->installable = false; 541 InstallableParams& params = tasks_[0].first;
517 installable_->error = NO_MATCHING_SERVICE_WORKER; 542 if (params.wait_for_worker) {
543 // Wait for ServiceWorkerContextObserver::OnRegistrationStored. Set the
544 // param |wait_for_worker| to false so we only wait once per task.
545 params.wait_for_worker = false;
546 worker_->is_waiting = true;
547 return;
548 }
549 worker_->has_worker = false;
550 worker_->error = NO_MATCHING_SERVICE_WORKER;
518 break; 551 break;
519 } 552 }
520 553
521 installable_->fetched = true; 554 worker_->fetched = true;
522 WorkOnTask(); 555 WorkOnTask();
523 } 556 }
524 557
525 void InstallableManager::CheckAndFetchBestIcon(const IconParams& params) { 558 void InstallableManager::CheckAndFetchBestIcon(const IconParams& params) {
526 DCHECK(!manifest().IsEmpty()); 559 DCHECK(!manifest().IsEmpty());
527 560
528 int ideal_icon_size_in_px = std::get<0>(params); 561 int ideal_icon_size_in_px = std::get<0>(params);
529 int minimum_icon_size_in_px = std::get<1>(params); 562 int minimum_icon_size_in_px = std::get<1>(params);
530 IconPurpose icon_purpose = std::get<2>(params); 563 IconPurpose icon_purpose = std::get<2>(params);
531 564
(...skipping 30 matching lines...) Expand all
562 if (bitmap.drawsNothing()) { 595 if (bitmap.drawsNothing()) {
563 icon.error = NO_ICON_AVAILABLE; 596 icon.error = NO_ICON_AVAILABLE;
564 } else { 597 } else {
565 icon.url = icon_url; 598 icon.url = icon_url;
566 icon.icon.reset(new SkBitmap(bitmap)); 599 icon.icon.reset(new SkBitmap(bitmap));
567 } 600 }
568 601
569 WorkOnTask(); 602 WorkOnTask();
570 } 603 }
571 604
605 void InstallableManager::OnRegistrationStored(const GURL& pattern) {
606 // If we aren't currently waiting, either:
607 // a) we've already failed the check, or
608 // b) we haven't yet called CheckHasServiceWorker.
609 // Otherwise if the scope doesn't match we keep waiting.
610 if (!worker_->is_waiting || !content::ServiceWorkerContext::ScopeMatches(
611 pattern, manifest().start_url)) {
612 return;
613 }
614
615 // This will call CheckHasServiceWorker to check whether the service worker
616 // controls the start_url and if it has a fetch handler.
617 worker_->is_waiting = false;
618 WorkOnTask();
619 }
620
572 void InstallableManager::DidFinishNavigation( 621 void InstallableManager::DidFinishNavigation(
573 content::NavigationHandle* handle) { 622 content::NavigationHandle* handle) {
574 if (handle->IsInMainFrame() && handle->HasCommitted() && 623 if (handle->IsInMainFrame() && handle->HasCommitted() &&
575 !handle->IsSameDocument()) { 624 !handle->IsSameDocument()) {
576 Reset(); 625 Reset();
577 } 626 }
578 } 627 }
579 628
580 void InstallableManager::WebContentsDestroyed() { 629 void InstallableManager::WebContentsDestroyed() {
581 Reset(); 630 Reset();
582 Observe(nullptr); 631 Observe(nullptr);
583 } 632 }
584 633
585 const GURL& InstallableManager::manifest_url() const { 634 const GURL& InstallableManager::manifest_url() const {
586 return manifest_->url; 635 return manifest_->url;
587 } 636 }
588 637
589 const content::Manifest& InstallableManager::manifest() const { 638 const content::Manifest& InstallableManager::manifest() const {
590 return manifest_->manifest; 639 return manifest_->manifest;
591 } 640 }
592 641
593 bool InstallableManager::is_installable() const { 642 bool InstallableManager::is_installable() const {
594 return installable_->installable; 643 return valid_manifest_->is_valid && worker_->has_worker;
595 } 644 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698