| 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/banners/app_banner_data_fetcher.h" | 5 #include "chrome/browser/banners/app_banner_data_fetcher.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 // The redisplay request may be received before the Cancel prompt reply | 183 // The redisplay request may be received before the Cancel prompt reply |
| 184 // *after* if it is made before the beforeinstallprompt event handler | 184 // *after* if it is made before the beforeinstallprompt event handler |
| 185 // concludes (e.g. in the event handler itself), so allow the pipeline | 185 // concludes (e.g. in the event handler itself), so allow the pipeline |
| 186 // to continue in this case. | 186 // to continue in this case. |
| 187 // | 187 // |
| 188 // Stash the referrer for the case where the banner is redisplayed. | 188 // Stash the referrer for the case where the banner is redisplayed. |
| 189 if (reply == blink::WebAppBannerPromptReply::Cancel && | 189 if (reply == blink::WebAppBannerPromptReply::Cancel && |
| 190 !page_requested_prompt_) { | 190 !page_requested_prompt_) { |
| 191 was_canceled_by_page_ = true; | 191 was_canceled_by_page_ = true; |
| 192 referrer_ = referrer; | 192 referrer_ = referrer; |
| 193 OutputDeveloperNotShownMessage(web_contents, kRendererRequestCancel, | 193 OutputDeveloperNotShownMessage( |
| 194 is_debug_mode_); | 194 web_contents, OutputDeveloperMessageCode::kRendererRequestCancel, |
| 195 is_debug_mode_); |
| 195 return; | 196 return; |
| 196 } | 197 } |
| 197 | 198 |
| 198 AppBannerSettingsHelper::RecordMinutesFromFirstVisitToShow( | 199 AppBannerSettingsHelper::RecordMinutesFromFirstVisitToShow( |
| 199 web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime()); | 200 web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime()); |
| 200 | 201 |
| 201 // Definitely going to show the banner now. | 202 // Definitely going to show the banner now. |
| 202 FOR_EACH_OBSERVER(Observer, observer_list_, | 203 FOR_EACH_OBSERVER(Observer, observer_list_, |
| 203 OnDecidedWhetherToShow(this, true)); | 204 OnDecidedWhetherToShow(this, true)); |
| 204 | 205 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(), | 251 rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(), |
| 251 event_name, | 252 event_name, |
| 252 web_contents->GetURL()); | 253 web_contents->GetURL()); |
| 253 } | 254 } |
| 254 | 255 |
| 255 void AppBannerDataFetcher::OnDidHasManifest(bool has_manifest) { | 256 void AppBannerDataFetcher::OnDidHasManifest(bool has_manifest) { |
| 256 content::WebContents* web_contents = GetWebContents(); | 257 content::WebContents* web_contents = GetWebContents(); |
| 257 | 258 |
| 258 if (!CheckFetcherIsStillAlive(web_contents) || !has_manifest) { | 259 if (!CheckFetcherIsStillAlive(web_contents) || !has_manifest) { |
| 259 if (!has_manifest) | 260 if (!has_manifest) |
| 260 OutputDeveloperNotShownMessage(web_contents, kNoManifest, is_debug_mode_); | 261 OutputDeveloperNotShownMessage(web_contents, |
| 262 OutputDeveloperMessageCode::kNoManifest, |
| 263 is_debug_mode_); |
| 261 | 264 |
| 262 Cancel(); | 265 Cancel(); |
| 263 return; | 266 return; |
| 264 } | 267 } |
| 265 | 268 |
| 266 web_contents->GetManifest( | 269 web_contents->GetManifest( |
| 267 base::Bind(&AppBannerDataFetcher::OnDidGetManifest, this)); | 270 base::Bind(&AppBannerDataFetcher::OnDidGetManifest, this)); |
| 268 } | 271 } |
| 269 | 272 |
| 270 void AppBannerDataFetcher::OnDidGetManifest( | 273 void AppBannerDataFetcher::OnDidGetManifest( |
| 271 const GURL& manifest_url, | 274 const GURL& manifest_url, |
| 272 const content::Manifest& manifest) { | 275 const content::Manifest& manifest) { |
| 273 content::WebContents* web_contents = GetWebContents(); | 276 content::WebContents* web_contents = GetWebContents(); |
| 274 if (!CheckFetcherIsStillAlive(web_contents)) { | 277 if (!CheckFetcherIsStillAlive(web_contents)) { |
| 275 Cancel(); | 278 Cancel(); |
| 276 return; | 279 return; |
| 277 } | 280 } |
| 278 if (manifest.IsEmpty()) { | 281 if (manifest.IsEmpty()) { |
| 279 OutputDeveloperNotShownMessage(web_contents, kManifestEmpty, | 282 OutputDeveloperNotShownMessage(web_contents, |
| 283 OutputDeveloperMessageCode::kManifestEmpty, |
| 280 is_debug_mode_); | 284 is_debug_mode_); |
| 281 Cancel(); | 285 Cancel(); |
| 282 return; | 286 return; |
| 283 } | 287 } |
| 284 | 288 |
| 285 if (manifest.prefer_related_applications && | 289 if (manifest.prefer_related_applications && |
| 286 manifest.related_applications.size()) { | 290 manifest.related_applications.size()) { |
| 287 for (const auto& application : manifest.related_applications) { | 291 for (const auto& application : manifest.related_applications) { |
| 288 std::string platform = base::UTF16ToUTF8(application.platform.string()); | 292 std::string platform = base::UTF16ToUTF8(application.platform.string()); |
| 289 std::string id = base::UTF16ToUTF8(application.id.string()); | 293 std::string id = base::UTF16ToUTF8(application.id.string()); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 void AppBannerDataFetcher::OnDidCheckHasServiceWorker( | 336 void AppBannerDataFetcher::OnDidCheckHasServiceWorker( |
| 333 bool has_service_worker) { | 337 bool has_service_worker) { |
| 334 content::WebContents* web_contents = GetWebContents(); | 338 content::WebContents* web_contents = GetWebContents(); |
| 335 if (!CheckFetcherIsStillAlive(web_contents)) { | 339 if (!CheckFetcherIsStillAlive(web_contents)) { |
| 336 Cancel(); | 340 Cancel(); |
| 337 return; | 341 return; |
| 338 } | 342 } |
| 339 | 343 |
| 340 if (!has_service_worker) { | 344 if (!has_service_worker) { |
| 341 TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER); | 345 TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER); |
| 342 OutputDeveloperNotShownMessage(web_contents, kNoMatchingServiceWorker, | 346 OutputDeveloperNotShownMessage( |
| 343 is_debug_mode_); | 347 web_contents, OutputDeveloperMessageCode::kNoMatchingServiceWorker, |
| 348 is_debug_mode_); |
| 344 Cancel(); | 349 Cancel(); |
| 345 return; | 350 return; |
| 346 } | 351 } |
| 347 | 352 |
| 348 OnHasServiceWorker(web_contents); | 353 OnHasServiceWorker(web_contents); |
| 349 } | 354 } |
| 350 | 355 |
| 351 void AppBannerDataFetcher::OnHasServiceWorker( | 356 void AppBannerDataFetcher::OnHasServiceWorker( |
| 352 content::WebContents* web_contents) { | 357 content::WebContents* web_contents) { |
| 353 GURL icon_url = ManifestIconSelector::FindBestMatchingIcon( | 358 GURL icon_url = ManifestIconSelector::FindBestMatchingIcon( |
| 354 manifest_.icons, ideal_icon_size_in_dp_, minimum_icon_size_in_dp_); | 359 manifest_.icons, ideal_icon_size_in_dp_, minimum_icon_size_in_dp_); |
| 355 | 360 |
| 356 if (icon_url.is_empty()) { | 361 if (icon_url.is_empty()) { |
| 357 OutputDeveloperNotShownMessage( | 362 OutputDeveloperNotShownMessage( |
| 358 web_contents, | 363 web_contents, |
| 359 kNoIconMatchingRequirements, | 364 OutputDeveloperMessageCode::kNoIconMatchingRequirements, |
| 360 base::IntToString(ManifestIconSelector::ConvertIconSizeFromDpToPx( | 365 base::IntToString(ManifestIconSelector::ConvertIconSizeFromDpToPx( |
| 361 minimum_icon_size_in_dp_)), | 366 minimum_icon_size_in_dp_)), |
| 362 is_debug_mode_); | 367 is_debug_mode_); |
| 363 Cancel(); | 368 Cancel(); |
| 364 } else if (!FetchAppIcon(web_contents, icon_url)) { | 369 } else if (!FetchAppIcon(web_contents, icon_url)) { |
| 365 OutputDeveloperNotShownMessage(web_contents, kCannotDownloadIcon, | 370 OutputDeveloperNotShownMessage( |
| 366 is_debug_mode_); | 371 web_contents, OutputDeveloperMessageCode::kCannotDownloadIcon, |
| 372 is_debug_mode_); |
| 367 Cancel(); | 373 Cancel(); |
| 368 } | 374 } |
| 369 } | 375 } |
| 370 | 376 |
| 371 bool AppBannerDataFetcher::FetchAppIcon(content::WebContents* web_contents, | 377 bool AppBannerDataFetcher::FetchAppIcon(content::WebContents* web_contents, |
| 372 const GURL& icon_url) { | 378 const GURL& icon_url) { |
| 373 app_icon_url_ = icon_url; | 379 app_icon_url_ = icon_url; |
| 374 return ManifestIconDownloader::Download( | 380 return ManifestIconDownloader::Download( |
| 375 web_contents, icon_url, ideal_icon_size_in_dp_, minimum_icon_size_in_dp_, | 381 web_contents, icon_url, ideal_icon_size_in_dp_, minimum_icon_size_in_dp_, |
| 376 base::Bind(&AppBannerDataFetcher::OnAppIconFetched, this)); | 382 base::Bind(&AppBannerDataFetcher::OnAppIconFetched, this)); |
| 377 } | 383 } |
| 378 | 384 |
| 379 void AppBannerDataFetcher::OnAppIconFetched(const SkBitmap& bitmap) { | 385 void AppBannerDataFetcher::OnAppIconFetched(const SkBitmap& bitmap) { |
| 380 if (!is_active_) return; | 386 if (!is_active_) return; |
| 381 | 387 |
| 382 content::WebContents* web_contents = GetWebContents(); | 388 content::WebContents* web_contents = GetWebContents(); |
| 383 if (!CheckFetcherIsStillAlive(web_contents)) { | 389 if (!CheckFetcherIsStillAlive(web_contents)) { |
| 384 Cancel(); | 390 Cancel(); |
| 385 return; | 391 return; |
| 386 } | 392 } |
| 387 if (bitmap.drawsNothing()) { | 393 if (bitmap.drawsNothing()) { |
| 388 OutputDeveloperNotShownMessage(web_contents, kNoIconAvailable, | 394 OutputDeveloperNotShownMessage(web_contents, |
| 395 OutputDeveloperMessageCode::kNoIconAvailable, |
| 389 is_debug_mode_); | 396 is_debug_mode_); |
| 390 Cancel(); | 397 Cancel(); |
| 391 return; | 398 return; |
| 392 } | 399 } |
| 393 | 400 |
| 394 RecordCouldShowBanner(); | 401 RecordCouldShowBanner(); |
| 395 if (!is_debug_mode_ && !CheckIfShouldShowBanner()) { | 402 if (!is_debug_mode_ && !CheckIfShouldShowBanner()) { |
| 396 // At this point, the only possible case is that the banner has been added | 403 // At this point, the only possible case is that the banner has been added |
| 397 // to the homescreen, given all of the other checks that have been made. | 404 // to the homescreen, given all of the other checks that have been made. |
| 398 Cancel(); | 405 Cancel(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 428 DCHECK(web_contents); | 435 DCHECK(web_contents); |
| 429 | 436 |
| 430 return AppBannerSettingsHelper::ShouldShowBanner( | 437 return AppBannerSettingsHelper::ShouldShowBanner( |
| 431 web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime()); | 438 web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime()); |
| 432 } | 439 } |
| 433 | 440 |
| 434 bool AppBannerDataFetcher::CheckFetcherIsStillAlive( | 441 bool AppBannerDataFetcher::CheckFetcherIsStillAlive( |
| 435 content::WebContents* web_contents) { | 442 content::WebContents* web_contents) { |
| 436 if (!is_active_) { | 443 if (!is_active_) { |
| 437 OutputDeveloperNotShownMessage( | 444 OutputDeveloperNotShownMessage( |
| 438 web_contents, kUserNavigatedBeforeBannerShown, is_debug_mode_); | 445 web_contents, |
| 446 OutputDeveloperMessageCode::kUserNavigatedBeforeBannerShown, |
| 447 is_debug_mode_); |
| 439 return false; | 448 return false; |
| 440 } | 449 } |
| 441 if (!web_contents) { | 450 if (!web_contents) { |
| 442 return false; // We cannot show a message if |web_contents| is null | 451 return false; // We cannot show a message if |web_contents| is null |
| 443 } | 452 } |
| 444 return true; | 453 return true; |
| 445 } | 454 } |
| 446 | 455 |
| 447 // static | 456 // static |
| 448 bool AppBannerDataFetcher::IsManifestValidForWebApp( | 457 bool AppBannerDataFetcher::IsManifestValidForWebApp( |
| 449 const content::Manifest& manifest, | 458 const content::Manifest& manifest, |
| 450 content::WebContents* web_contents, | 459 content::WebContents* web_contents, |
| 451 bool is_debug_mode) { | 460 bool is_debug_mode) { |
| 452 if (manifest.IsEmpty()) { | 461 if (manifest.IsEmpty()) { |
| 453 OutputDeveloperNotShownMessage(web_contents, kManifestEmpty, is_debug_mode); | 462 OutputDeveloperNotShownMessage(web_contents, |
| 463 OutputDeveloperMessageCode::kManifestEmpty, |
| 464 is_debug_mode); |
| 454 return false; | 465 return false; |
| 455 } | 466 } |
| 456 if (!manifest.start_url.is_valid()) { | 467 if (!manifest.start_url.is_valid()) { |
| 457 OutputDeveloperNotShownMessage(web_contents, kStartURLNotValid, | 468 OutputDeveloperNotShownMessage( |
| 458 is_debug_mode); | 469 web_contents, OutputDeveloperMessageCode::kStartURLNotValid, |
| 470 is_debug_mode); |
| 459 return false; | 471 return false; |
| 460 } | 472 } |
| 461 if ((manifest.name.is_null() || manifest.name.string().empty()) && | 473 if ((manifest.name.is_null() || manifest.name.string().empty()) && |
| 462 (manifest.short_name.is_null() || manifest.short_name.string().empty())) { | 474 (manifest.short_name.is_null() || manifest.short_name.string().empty())) { |
| 463 OutputDeveloperNotShownMessage( | 475 OutputDeveloperNotShownMessage( |
| 464 web_contents, kManifestMissingNameOrShortName, is_debug_mode); | 476 web_contents, |
| 477 OutputDeveloperMessageCode::kManifestMissingNameOrShortName, |
| 478 is_debug_mode); |
| 465 return false; | 479 return false; |
| 466 } | 480 } |
| 467 | 481 |
| 468 // TODO(dominickn,mlamouri): when Chrome supports "minimal-ui", it should be | 482 // TODO(dominickn,mlamouri): when Chrome supports "minimal-ui", it should be |
| 469 // accepted. If we accept it today, it would fallback to "browser" and make | 483 // accepted. If we accept it today, it would fallback to "browser" and make |
| 470 // this check moot. See https://crbug.com/604390 | 484 // this check moot. See https://crbug.com/604390 |
| 471 if (manifest.display != blink::WebDisplayModeStandalone && | 485 if (manifest.display != blink::WebDisplayModeStandalone && |
| 472 manifest.display != blink::WebDisplayModeFullscreen) { | 486 manifest.display != blink::WebDisplayModeFullscreen) { |
| 473 OutputDeveloperNotShownMessage( | 487 OutputDeveloperNotShownMessage( |
| 474 web_contents, kManifestDisplayStandaloneFullscreen, is_debug_mode); | 488 web_contents, |
| 489 OutputDeveloperMessageCode::kManifestDisplayStandaloneFullscreen, |
| 490 is_debug_mode); |
| 475 return false; | 491 return false; |
| 476 } | 492 } |
| 477 | 493 |
| 478 if (!DoesManifestContainRequiredIcon(manifest)) { | 494 if (!DoesManifestContainRequiredIcon(manifest)) { |
| 479 OutputDeveloperNotShownMessage(web_contents, kManifestMissingSuitableIcon, | 495 OutputDeveloperNotShownMessage( |
| 480 is_debug_mode); | 496 web_contents, OutputDeveloperMessageCode::kManifestMissingSuitableIcon, |
| 497 is_debug_mode); |
| 481 return false; | 498 return false; |
| 482 } | 499 } |
| 483 return true; | 500 return true; |
| 484 } | 501 } |
| 485 | 502 |
| 486 } // namespace banners | 503 } // namespace banners |
| OLD | NEW |