Chromium Code Reviews| 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/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 64 // static | 64 // static |
| 65 base::Time AppBannerDataFetcher::GetCurrentTime() { | 65 base::Time AppBannerDataFetcher::GetCurrentTime() { |
| 66 return base::Time::Now() + gTimeDeltaForTesting; | 66 return base::Time::Now() + gTimeDeltaForTesting; |
| 67 } | 67 } |
| 68 | 68 |
| 69 // static | 69 // static |
| 70 void AppBannerDataFetcher::SetTimeDeltaForTesting(int days) { | 70 void AppBannerDataFetcher::SetTimeDeltaForTesting(int days) { |
| 71 gTimeDeltaForTesting = base::TimeDelta::FromDays(days); | 71 gTimeDeltaForTesting = base::TimeDelta::FromDays(days); |
| 72 } | 72 } |
| 73 | 73 |
| 74 AppBannerDataFetcher::AppBannerDataFetcher( | 74 AppBannerDataFetcher::AppBannerDataFetcher(content::WebContents* web_contents, |
| 75 content::WebContents* web_contents, | 75 base::WeakPtr<Delegate> delegate, |
| 76 base::WeakPtr<Delegate> delegate, | 76 int ideal_icon_size_in_dp, |
| 77 int ideal_icon_size_in_dp, | 77 int minimum_icon_size_in_dp, |
| 78 int minimum_icon_size_in_dp) | 78 bool is_debug_mode) |
| 79 : WebContentsObserver(web_contents), | 79 : WebContentsObserver(web_contents), |
| 80 weak_delegate_(delegate), | 80 weak_delegate_(delegate), |
| 81 ideal_icon_size_in_dp_(ideal_icon_size_in_dp), | 81 ideal_icon_size_in_dp_(ideal_icon_size_in_dp), |
| 82 minimum_icon_size_in_dp_(minimum_icon_size_in_dp), | 82 minimum_icon_size_in_dp_(minimum_icon_size_in_dp), |
| 83 is_active_(false), | 83 is_active_(false), |
| 84 was_canceled_by_page_(false), | 84 was_canceled_by_page_(false), |
| 85 page_requested_prompt_(false), | 85 page_requested_prompt_(false), |
| 86 is_debug_mode_(is_debug_mode || | |
| 87 base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 88 switches::kBypassAppBannerEngagementChecks)), | |
| 86 event_request_id_(-1) { | 89 event_request_id_(-1) { |
| 87 DCHECK(minimum_icon_size_in_dp <= ideal_icon_size_in_dp); | 90 DCHECK(minimum_icon_size_in_dp <= ideal_icon_size_in_dp); |
| 88 } | 91 } |
| 89 | 92 |
| 90 void AppBannerDataFetcher::Start(const GURL& validated_url, | 93 void AppBannerDataFetcher::Start(const GURL& validated_url, |
| 91 ui::PageTransition transition_type) { | 94 ui::PageTransition transition_type) { |
| 92 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 95 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 93 | 96 |
| 94 content::WebContents* web_contents = GetWebContents(); | 97 content::WebContents* web_contents = GetWebContents(); |
| 95 DCHECK(web_contents); | 98 DCHECK(web_contents); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 177 // The redisplay request may be received before the Cancel prompt reply | 180 // The redisplay request may be received before the Cancel prompt reply |
| 178 // *after* if it is made before the beforeinstallprompt event handler | 181 // *after* if it is made before the beforeinstallprompt event handler |
| 179 // concludes (e.g. in the event handler itself), so allow the pipeline | 182 // concludes (e.g. in the event handler itself), so allow the pipeline |
| 180 // to continue in this case. | 183 // to continue in this case. |
| 181 // | 184 // |
| 182 // Stash the referrer for the case where the banner is redisplayed. | 185 // Stash the referrer for the case where the banner is redisplayed. |
| 183 if (reply == blink::WebAppBannerPromptReply::Cancel && | 186 if (reply == blink::WebAppBannerPromptReply::Cancel && |
| 184 !page_requested_prompt_) { | 187 !page_requested_prompt_) { |
| 185 was_canceled_by_page_ = true; | 188 was_canceled_by_page_ = true; |
| 186 referrer_ = referrer; | 189 referrer_ = referrer; |
| 187 OutputDeveloperNotShownMessage(web_contents, kRendererRequestCancel); | 190 OutputDeveloperNotShownMessage(web_contents, kRendererRequestCancel, |
| 191 is_debug_mode_); | |
| 188 return; | 192 return; |
| 189 } | 193 } |
| 190 | 194 |
| 191 AppBannerSettingsHelper::RecordMinutesFromFirstVisitToShow( | 195 AppBannerSettingsHelper::RecordMinutesFromFirstVisitToShow( |
| 192 web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime()); | 196 web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime()); |
| 193 | 197 |
| 194 // Definitely going to show the banner now. | 198 // Definitely going to show the banner now. |
| 195 FOR_EACH_OBSERVER(Observer, observer_list_, | 199 FOR_EACH_OBSERVER(Observer, observer_list_, |
| 196 OnDecidedWhetherToShow(this, true)); | 200 OnDecidedWhetherToShow(this, true)); |
| 197 | 201 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(), | 247 rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(), |
| 244 event_name, | 248 event_name, |
| 245 web_contents->GetURL()); | 249 web_contents->GetURL()); |
| 246 } | 250 } |
| 247 | 251 |
| 248 void AppBannerDataFetcher::OnDidHasManifest(bool has_manifest) { | 252 void AppBannerDataFetcher::OnDidHasManifest(bool has_manifest) { |
| 249 content::WebContents* web_contents = GetWebContents(); | 253 content::WebContents* web_contents = GetWebContents(); |
| 250 | 254 |
| 251 if (!CheckFetcherIsStillAlive(web_contents) || !has_manifest) { | 255 if (!CheckFetcherIsStillAlive(web_contents) || !has_manifest) { |
| 252 if (!has_manifest) | 256 if (!has_manifest) |
| 253 OutputDeveloperNotShownMessage(web_contents, kNoManifest); | 257 OutputDeveloperNotShownMessage(web_contents, kNoManifest, is_debug_mode_); |
| 254 | 258 |
| 255 Cancel(); | 259 Cancel(); |
| 256 return; | 260 return; |
| 257 } | 261 } |
| 258 | 262 |
| 259 web_contents->GetManifest( | 263 web_contents->GetManifest( |
| 260 base::Bind(&AppBannerDataFetcher::OnDidGetManifest, this)); | 264 base::Bind(&AppBannerDataFetcher::OnDidGetManifest, this)); |
| 261 } | 265 } |
| 262 | 266 |
| 263 void AppBannerDataFetcher::OnDidGetManifest( | 267 void AppBannerDataFetcher::OnDidGetManifest( |
| 264 const content::Manifest& manifest) { | 268 const content::Manifest& manifest) { |
| 265 content::WebContents* web_contents = GetWebContents(); | 269 content::WebContents* web_contents = GetWebContents(); |
| 266 if (!CheckFetcherIsStillAlive(web_contents)) { | 270 if (!CheckFetcherIsStillAlive(web_contents)) { |
| 267 Cancel(); | 271 Cancel(); |
| 268 return; | 272 return; |
| 269 } | 273 } |
| 270 if (manifest.IsEmpty()) { | 274 if (manifest.IsEmpty()) { |
| 271 OutputDeveloperNotShownMessage(web_contents, kManifestEmpty); | 275 OutputDeveloperNotShownMessage(web_contents, kManifestEmpty, |
| 276 is_debug_mode_); | |
| 272 Cancel(); | 277 Cancel(); |
| 273 return; | 278 return; |
| 274 } | 279 } |
| 275 | 280 |
| 276 if (manifest.prefer_related_applications && | 281 if (manifest.prefer_related_applications && |
| 277 manifest.related_applications.size()) { | 282 manifest.related_applications.size()) { |
| 278 for (const auto& application : manifest.related_applications) { | 283 for (const auto& application : manifest.related_applications) { |
| 279 std::string platform = base::UTF16ToUTF8(application.platform.string()); | 284 std::string platform = base::UTF16ToUTF8(application.platform.string()); |
| 280 std::string id = base::UTF16ToUTF8(application.id.string()); | 285 std::string id = base::UTF16ToUTF8(application.id.string()); |
| 281 if (weak_delegate_->HandleNonWebApp(platform, application.url, id)) | 286 if (weak_delegate_->HandleNonWebApp(platform, application.url, id, |
| 287 is_debug_mode_)) | |
| 282 return; | 288 return; |
| 283 } | 289 } |
| 284 } | 290 } |
| 285 | 291 |
| 286 if (!IsManifestValidForWebApp(manifest, web_contents)) { | 292 if (!IsManifestValidForWebApp(manifest, web_contents, is_debug_mode_)) { |
| 287 Cancel(); | 293 Cancel(); |
| 288 return; | 294 return; |
| 289 } | 295 } |
| 290 | 296 |
| 291 web_app_data_ = manifest; | 297 web_app_data_ = manifest; |
| 292 app_title_ = web_app_data_.name.string(); | 298 app_title_ = web_app_data_.name.string(); |
| 293 | 299 |
| 294 if (IsWebAppInstalled(web_contents->GetBrowserContext(), | 300 if (IsWebAppInstalled(web_contents->GetBrowserContext(), |
| 295 manifest.start_url) && | 301 manifest.start_url) && |
| 296 !base::CommandLine::ForCurrentProcess()->HasSwitch( | 302 !is_debug_mode_) { |
| 297 switches::kBypassAppBannerEngagementChecks)) { | 303 OutputDeveloperNotShownMessage(web_contents, kBannerAlreadyAdded, |
|
dominickn
2016/01/19 02:25:10
Looking at this again, printing an error message h
| |
| 298 OutputDeveloperNotShownMessage(web_contents, kBannerAlreadyAdded); | 304 is_debug_mode_); |
| 299 Cancel(); | 305 Cancel(); |
| 300 return; | 306 return; |
| 301 } | 307 } |
| 302 | 308 |
| 303 banners::TrackDisplayEvent(DISPLAY_EVENT_WEB_APP_BANNER_REQUESTED); | 309 banners::TrackDisplayEvent(DISPLAY_EVENT_WEB_APP_BANNER_REQUESTED); |
| 304 | 310 |
| 305 // Check to see if there is a single service worker controlling this page | 311 // Check to see if there is a single service worker controlling this page |
| 306 // and the manifest's start url. | 312 // and the manifest's start url. |
| 307 Profile* profile = | 313 Profile* profile = |
| 308 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 314 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 320 void AppBannerDataFetcher::OnDidCheckHasServiceWorker( | 326 void AppBannerDataFetcher::OnDidCheckHasServiceWorker( |
| 321 bool has_service_worker) { | 327 bool has_service_worker) { |
| 322 content::WebContents* web_contents = GetWebContents(); | 328 content::WebContents* web_contents = GetWebContents(); |
| 323 if (!CheckFetcherIsStillAlive(web_contents)) { | 329 if (!CheckFetcherIsStillAlive(web_contents)) { |
| 324 Cancel(); | 330 Cancel(); |
| 325 return; | 331 return; |
| 326 } | 332 } |
| 327 | 333 |
| 328 if (!has_service_worker) { | 334 if (!has_service_worker) { |
| 329 TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER); | 335 TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER); |
| 330 OutputDeveloperNotShownMessage(web_contents, kNoMatchingServiceWorker); | 336 OutputDeveloperNotShownMessage(web_contents, kNoMatchingServiceWorker, |
| 337 is_debug_mode_); | |
| 331 Cancel(); | 338 Cancel(); |
| 332 return; | 339 return; |
| 333 } | 340 } |
| 334 | 341 |
| 335 OnHasServiceWorker(web_contents); | 342 OnHasServiceWorker(web_contents); |
| 336 } | 343 } |
| 337 | 344 |
| 338 void AppBannerDataFetcher::OnHasServiceWorker( | 345 void AppBannerDataFetcher::OnHasServiceWorker( |
| 339 content::WebContents* web_contents) { | 346 content::WebContents* web_contents) { |
| 340 GURL icon_url = | 347 GURL icon_url = |
| 341 ManifestIconSelector::FindBestMatchingIcon( | 348 ManifestIconSelector::FindBestMatchingIcon( |
| 342 web_app_data_.icons, | 349 web_app_data_.icons, |
| 343 ideal_icon_size_in_dp_, | 350 ideal_icon_size_in_dp_, |
| 344 minimum_icon_size_in_dp_, | 351 minimum_icon_size_in_dp_, |
| 345 gfx::Screen::GetScreenFor(web_contents->GetNativeView())); | 352 gfx::Screen::GetScreenFor(web_contents->GetNativeView())); |
| 346 | 353 |
| 347 if (!FetchAppIcon(web_contents, icon_url)) { | 354 if (!FetchAppIcon(web_contents, icon_url)) { |
| 348 OutputDeveloperNotShownMessage(web_contents, kCannotDetermineBestIcon); | 355 OutputDeveloperNotShownMessage(web_contents, kCannotDetermineBestIcon, |
| 356 is_debug_mode_); | |
| 349 Cancel(); | 357 Cancel(); |
| 350 } | 358 } |
| 351 } | 359 } |
| 352 | 360 |
| 353 bool AppBannerDataFetcher::FetchAppIcon(content::WebContents* web_contents, | 361 bool AppBannerDataFetcher::FetchAppIcon(content::WebContents* web_contents, |
| 354 const GURL& icon_url) { | 362 const GURL& icon_url) { |
| 355 return ManifestIconDownloader::Download( | 363 return ManifestIconDownloader::Download( |
| 356 web_contents, | 364 web_contents, |
| 357 icon_url, | 365 icon_url, |
| 358 ideal_icon_size_in_dp_, | 366 ideal_icon_size_in_dp_, |
| 359 minimum_icon_size_in_dp_, | 367 minimum_icon_size_in_dp_, |
| 360 base::Bind(&AppBannerDataFetcher::OnAppIconFetched, | 368 base::Bind(&AppBannerDataFetcher::OnAppIconFetched, |
| 361 this)); | 369 this)); |
| 362 } | 370 } |
| 363 | 371 |
| 364 void AppBannerDataFetcher::OnAppIconFetched(const SkBitmap& bitmap) { | 372 void AppBannerDataFetcher::OnAppIconFetched(const SkBitmap& bitmap) { |
| 365 if (!is_active_) return; | 373 if (!is_active_) return; |
| 366 | 374 |
| 367 content::WebContents* web_contents = GetWebContents(); | 375 content::WebContents* web_contents = GetWebContents(); |
| 368 if (!CheckFetcherIsStillAlive(web_contents)) { | 376 if (!CheckFetcherIsStillAlive(web_contents)) { |
| 369 Cancel(); | 377 Cancel(); |
| 370 return; | 378 return; |
| 371 } | 379 } |
| 372 if (bitmap.drawsNothing()) { | 380 if (bitmap.drawsNothing()) { |
| 373 OutputDeveloperNotShownMessage(web_contents, kNoIconAvailable); | 381 OutputDeveloperNotShownMessage(web_contents, kNoIconAvailable, |
| 382 is_debug_mode_); | |
| 374 Cancel(); | 383 Cancel(); |
| 375 return; | 384 return; |
| 376 } | 385 } |
| 377 | 386 |
| 378 RecordCouldShowBanner(); | 387 RecordCouldShowBanner(); |
| 379 if (!CheckIfShouldShowBanner()) { | 388 if (!is_debug_mode_ && !CheckIfShouldShowBanner()) { |
| 380 // At this point, the only possible case is that the banner has been added | 389 // At this point, the only possible case is that the banner has been added |
| 381 // to the homescreen, given all of the other checks that have been made. | 390 // to the homescreen, given all of the other checks that have been made. |
| 382 OutputDeveloperNotShownMessage(web_contents, kBannerAlreadyAdded); | 391 OutputDeveloperNotShownMessage(web_contents, kBannerAlreadyAdded, |
| 392 is_debug_mode_); | |
| 383 Cancel(); | 393 Cancel(); |
| 384 return; | 394 return; |
| 385 } | 395 } |
| 386 | 396 |
| 387 app_icon_.reset(new SkBitmap(bitmap)); | 397 app_icon_.reset(new SkBitmap(bitmap)); |
| 388 event_request_id_ = ++gCurrentRequestID; | 398 event_request_id_ = ++gCurrentRequestID; |
| 389 web_contents->GetMainFrame()->Send( | 399 web_contents->GetMainFrame()->Send( |
| 390 new ChromeViewMsg_AppBannerPromptRequest( | 400 new ChromeViewMsg_AppBannerPromptRequest( |
| 391 web_contents->GetMainFrame()->GetRoutingID(), | 401 web_contents->GetMainFrame()->GetRoutingID(), |
| 392 event_request_id_, | 402 event_request_id_, |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 412 content::WebContents* web_contents = GetWebContents(); | 422 content::WebContents* web_contents = GetWebContents(); |
| 413 DCHECK(web_contents); | 423 DCHECK(web_contents); |
| 414 | 424 |
| 415 return AppBannerSettingsHelper::ShouldShowBanner( | 425 return AppBannerSettingsHelper::ShouldShowBanner( |
| 416 web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime()); | 426 web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime()); |
| 417 } | 427 } |
| 418 | 428 |
| 419 bool AppBannerDataFetcher::CheckFetcherIsStillAlive( | 429 bool AppBannerDataFetcher::CheckFetcherIsStillAlive( |
| 420 content::WebContents* web_contents) { | 430 content::WebContents* web_contents) { |
| 421 if (!is_active_) { | 431 if (!is_active_) { |
| 422 OutputDeveloperNotShownMessage(web_contents, | 432 OutputDeveloperNotShownMessage( |
| 423 kUserNavigatedBeforeBannerShown); | 433 web_contents, kUserNavigatedBeforeBannerShown, is_debug_mode_); |
| 424 return false; | 434 return false; |
| 425 } | 435 } |
| 426 if (!web_contents) { | 436 if (!web_contents) { |
| 427 return false; // We cannot show a message if |web_contents| is null | 437 return false; // We cannot show a message if |web_contents| is null |
| 428 } | 438 } |
| 429 return true; | 439 return true; |
| 430 } | 440 } |
| 431 | 441 |
| 432 // static | 442 // static |
| 433 bool AppBannerDataFetcher::IsManifestValidForWebApp( | 443 bool AppBannerDataFetcher::IsManifestValidForWebApp( |
| 434 const content::Manifest& manifest, | 444 const content::Manifest& manifest, |
| 435 content::WebContents* web_contents) { | 445 content::WebContents* web_contents, |
| 446 bool is_debug_mode) { | |
| 436 if (manifest.IsEmpty()) { | 447 if (manifest.IsEmpty()) { |
| 437 OutputDeveloperNotShownMessage(web_contents, kManifestEmpty); | 448 OutputDeveloperNotShownMessage(web_contents, kManifestEmpty, is_debug_mode); |
| 438 return false; | 449 return false; |
| 439 } | 450 } |
| 440 if (!manifest.start_url.is_valid()) { | 451 if (!manifest.start_url.is_valid()) { |
| 441 OutputDeveloperNotShownMessage(web_contents, kStartURLNotValid); | 452 OutputDeveloperNotShownMessage(web_contents, kStartURLNotValid, |
| 453 is_debug_mode); | |
| 442 return false; | 454 return false; |
| 443 } | 455 } |
| 444 if (manifest.name.is_null() && manifest.short_name.is_null()) { | 456 if (manifest.name.is_null() && manifest.short_name.is_null()) { |
| 445 OutputDeveloperNotShownMessage(web_contents, | 457 OutputDeveloperNotShownMessage( |
| 446 kManifestMissingNameOrShortName); | 458 web_contents, kManifestMissingNameOrShortName, is_debug_mode); |
| 447 return false; | 459 return false; |
| 448 } | 460 } |
| 449 if (!DoesManifestContainRequiredIcon(manifest)) { | 461 if (!DoesManifestContainRequiredIcon(manifest)) { |
| 450 OutputDeveloperNotShownMessage(web_contents, kManifestMissingSuitableIcon); | 462 OutputDeveloperNotShownMessage(web_contents, kManifestMissingSuitableIcon, |
| 463 is_debug_mode); | |
| 451 return false; | 464 return false; |
| 452 } | 465 } |
| 453 return true; | 466 return true; |
| 454 } | 467 } |
| 455 | 468 |
| 456 } // namespace banners | 469 } // namespace banners |
| OLD | NEW |