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_manager.h" | 5 #include "chrome/browser/banners/app_banner_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | |
| 8 | |
| 7 #include "base/bind.h" | 9 #include "base/bind.h" |
| 8 #include "base/callback.h" | 10 #include "base/callback.h" |
| 9 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/lazy_instance.h" | |
| 10 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 11 #include "base/time/time.h" | 14 #include "base/time/time.h" |
| 12 #include "chrome/browser/banners/app_banner_metrics.h" | 15 #include "chrome/browser/banners/app_banner_metrics.h" |
| 13 #include "chrome/browser/banners/app_banner_settings_helper.h" | 16 #include "chrome/browser/banners/app_banner_settings_helper.h" |
| 14 #include "chrome/browser/browser_process.h" | 17 #include "chrome/browser/browser_process.h" |
| 15 #include "chrome/browser/engagement/site_engagement_service.h" | 18 #include "chrome/browser/engagement/site_engagement_service.h" |
| 16 #include "chrome/browser/installable/installable_logging.h" | |
| 17 #include "chrome/browser/installable/installable_manager.h" | |
| 18 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/common/chrome_switches.h" | 20 #include "chrome/common/chrome_switches.h" |
| 20 #include "chrome/common/render_messages.h" | |
| 21 #include "components/rappor/rappor_utils.h" | 21 #include "components/rappor/rappor_utils.h" |
| 22 #include "content/public/browser/navigation_handle.h" | 22 #include "content/public/browser/navigation_handle.h" |
| 23 #include "content/public/browser/render_frame_host.h" | 23 #include "content/public/browser/render_frame_host.h" |
| 24 #include "content/public/browser/web_contents.h" | 24 #include "content/public/browser/web_contents.h" |
| 25 #include "content/public/common/origin_util.h" | 25 #include "content/public/common/origin_util.h" |
| 26 #include "third_party/WebKit/public/platform/modules/app_banner/WebAppBannerProm ptReply.h" | 26 #include "services/shell/public/cpp/interface_provider.h" |
| 27 #include "third_party/skia/include/core/SkBitmap.h" | 27 #include "third_party/skia/include/core/SkBitmap.h" |
| 28 #include "ui/display/display.h" | 28 #include "ui/display/display.h" |
| 29 #include "ui/display/screen.h" | 29 #include "ui/display/screen.h" |
| 30 | 30 |
| 31 namespace { | 31 namespace { |
| 32 | 32 |
| 33 bool gDisableSecureCheckForTesting = false; | 33 bool gDisableSecureCheckForTesting = false; |
| 34 int gCurrentRequestID = -1; | 34 int gCurrentRequestID = -1; |
| 35 base::LazyInstance<base::TimeDelta> gTimeDeltaForTesting = | 35 base::LazyInstance<base::TimeDelta> gTimeDeltaForTesting = |
|
benwells
2016/10/12 03:00:17
Unrelated nit: you could get rid of this LazyInsta
dominickn
2016/10/13 00:18:15
Done.
| |
| 36 LAZY_INSTANCE_INITIALIZER; | 36 LAZY_INSTANCE_INITIALIZER; |
| 37 | 37 |
| 38 // Returns |size_in_px| in dp, i.e. divided by the current device scale factor. | 38 // Returns |size_in_px| in dp, i.e. divided by the current device scale factor. |
| 39 int ConvertIconSizeFromPxToDp(int size_in_px) { | 39 int ConvertIconSizeFromPxToDp(int size_in_px) { |
| 40 return size_in_px / | 40 return size_in_px / |
| 41 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor(); | 41 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor(); |
| 42 } | 42 } |
| 43 | 43 |
| 44 InstallableParams ParamsToGetManifest() { | 44 InstallableParams ParamsToGetManifest() { |
| 45 return InstallableParams(); | 45 return InstallableParams(); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 if (!content::IsOriginSecure(validated_url) && | 122 if (!content::IsOriginSecure(validated_url) && |
| 123 !gDisableSecureCheckForTesting) { | 123 !gDisableSecureCheckForTesting) { |
| 124 ReportStatus(contents, NOT_FROM_SECURE_ORIGIN); | 124 ReportStatus(contents, NOT_FROM_SECURE_ORIGIN); |
| 125 Stop(); | 125 Stop(); |
| 126 return; | 126 return; |
| 127 } | 127 } |
| 128 | 128 |
| 129 if (validated_url_.is_empty()) | 129 if (validated_url_.is_empty()) |
| 130 validated_url_ = validated_url; | 130 validated_url_ = validated_url; |
| 131 | 131 |
| 132 // Any existing binding is invalid if we re-request the banner. | |
| 133 if (binding_.is_bound()) | |
|
benwells
2016/10/12 03:00:17
Why does the service have to be invalidated after
dominickn
2016/10/13 00:18:15
AppBannerManager only ever manages one in-flight r
| |
| 134 binding_.Close(); | |
| 135 | |
| 132 manager_->GetData( | 136 manager_->GetData( |
| 133 ParamsToGetManifest(), | 137 ParamsToGetManifest(), |
| 134 base::Bind(&AppBannerManager::OnDidGetManifest, GetWeakPtr())); | 138 base::Bind(&AppBannerManager::OnDidGetManifest, GetWeakPtr())); |
| 135 } | 139 } |
| 136 | 140 |
| 141 void AppBannerManager::SendBannerAccepted(int request_id) { | |
| 142 if (request_id != gCurrentRequestID) | |
| 143 return; | |
| 144 | |
| 145 DCHECK(event_.is_bound()); | |
| 146 event_->BannerAccepted(GetBannerType()); | |
| 147 } | |
| 148 | |
| 149 void AppBannerManager::SendBannerDismissed(int request_id) { | |
| 150 if (request_id != gCurrentRequestID) | |
| 151 return; | |
| 152 | |
| 153 DCHECK(event_.is_bound()); | |
| 154 event_->BannerDismissed(); | |
| 155 } | |
| 156 | |
| 137 base::Closure AppBannerManager::FetchWebappSplashScreenImageCallback( | 157 base::Closure AppBannerManager::FetchWebappSplashScreenImageCallback( |
| 138 const std::string& webapp_id) { | 158 const std::string& webapp_id) { |
| 139 return base::Closure(); | 159 return base::Closure(); |
| 140 } | 160 } |
| 141 | 161 |
| 142 AppBannerManager::AppBannerManager(content::WebContents* web_contents) | 162 AppBannerManager::AppBannerManager(content::WebContents* web_contents) |
| 143 : content::WebContentsObserver(web_contents), | 163 : content::WebContentsObserver(web_contents), |
| 144 SiteEngagementObserver(nullptr), | 164 SiteEngagementObserver(nullptr), |
| 145 manager_(nullptr), | 165 manager_(nullptr), |
| 146 event_request_id_(-1), | 166 event_request_id_(-1), |
| 167 binding_(this), | |
| 147 is_active_(false), | 168 is_active_(false), |
| 148 banner_request_queued_(false), | 169 banner_request_queued_(false), |
| 149 load_finished_(false), | 170 load_finished_(false), |
| 150 was_canceled_by_page_(false), | 171 was_canceled_by_page_(false), |
| 151 page_requested_prompt_(false), | 172 page_requested_prompt_(false), |
| 152 is_debug_mode_(false), | 173 is_debug_mode_(false), |
| 153 need_to_log_status_(false), | 174 need_to_log_status_(false), |
| 154 weak_factory_(this) { | 175 weak_factory_(this) { |
| 155 // Ensure the InstallableManager exists since we have a hard dependency on it. | 176 // Ensure the InstallableManager exists since we have a hard dependency on it. |
| 156 InstallableManager::CreateForWebContents(web_contents); | 177 InstallableManager::CreateForWebContents(web_contents); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 322 | 343 |
| 323 // Given all of the other checks that have been made, the only possible reason | 344 // Given all of the other checks that have been made, the only possible reason |
| 324 // for stopping now is that the app has been added to the homescreen. | 345 // for stopping now is that the app has been added to the homescreen. |
| 325 if (!IsDebugMode() && !CheckIfShouldShowBanner()) { | 346 if (!IsDebugMode() && !CheckIfShouldShowBanner()) { |
| 326 Stop(); | 347 Stop(); |
| 327 return; | 348 return; |
| 328 } | 349 } |
| 329 | 350 |
| 330 TrackBeforeInstallEvent(BEFORE_INSTALL_EVENT_CREATED); | 351 TrackBeforeInstallEvent(BEFORE_INSTALL_EVENT_CREATED); |
| 331 event_request_id_ = ++gCurrentRequestID; | 352 event_request_id_ = ++gCurrentRequestID; |
| 332 content::RenderFrameHost* frame = web_contents()->GetMainFrame(); | 353 |
| 333 frame->Send(new ChromeViewMsg_AppBannerPromptRequest( | 354 web_contents()->GetMainFrame()->GetRemoteInterfaces()->GetInterface( |
| 334 frame->GetRoutingID(), event_request_id_, GetBannerType())); | 355 mojo::GetProxy(&client_)); |
| 356 | |
| 357 client_->BannerPromptRequest( | |
| 358 binding_.CreateInterfacePtrAndBind(), mojo::GetProxy(&event_), | |
| 359 GetBannerType(), | |
| 360 base::Bind(&AppBannerManager::OnBannerPromptReply, GetWeakPtr())); | |
| 335 } | 361 } |
| 336 | 362 |
| 337 void AppBannerManager::DidStartNavigation(content::NavigationHandle* handle) { | 363 void AppBannerManager::DidStartNavigation(content::NavigationHandle* handle) { |
| 338 if (!handle->IsInMainFrame()) | 364 if (!handle->IsInMainFrame()) |
| 339 return; | 365 return; |
| 340 | 366 |
| 341 load_finished_ = false; | 367 load_finished_ = false; |
| 342 if (AppBannerSettingsHelper::ShouldUseSiteEngagementScore() && | 368 if (AppBannerSettingsHelper::ShouldUseSiteEngagementScore() && |
| 343 GetSiteEngagementService() == nullptr) { | 369 GetSiteEngagementService() == nullptr) { |
| 344 // Ensure that we are observing the site engagement service on navigation | 370 // Ensure that we are observing the site engagement service on navigation |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 453 } | 479 } |
| 454 | 480 |
| 455 // If we are in debug mode, AppBannerSettingsHelper::ShouldShowBanner must | 481 // If we are in debug mode, AppBannerSettingsHelper::ShouldShowBanner must |
| 456 // return NO_ERROR_DETECTED (bypass flag is set) or we must not have entered | 482 // return NO_ERROR_DETECTED (bypass flag is set) or we must not have entered |
| 457 // this method. | 483 // this method. |
| 458 DCHECK(!IsDebugMode()); | 484 DCHECK(!IsDebugMode()); |
| 459 ReportStatus(web_contents(), code); | 485 ReportStatus(web_contents(), code); |
| 460 return false; | 486 return false; |
| 461 } | 487 } |
| 462 | 488 |
| 463 bool AppBannerManager::OnMessageReceived( | |
| 464 const IPC::Message& message, | |
| 465 content::RenderFrameHost* render_frame_host) { | |
| 466 bool handled = true; | |
| 467 | |
| 468 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(AppBannerManager, message, render_frame_host) | |
| 469 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AppBannerPromptReply, | |
| 470 OnBannerPromptReply) | |
| 471 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_RequestShowAppBanner, | |
| 472 OnRequestShowAppBanner) | |
| 473 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 474 IPC_END_MESSAGE_MAP() | |
| 475 | |
| 476 return handled; | |
| 477 } | |
| 478 | |
| 479 void AppBannerManager::OnBannerPromptReply( | 489 void AppBannerManager::OnBannerPromptReply( |
| 480 content::RenderFrameHost* render_frame_host, | 490 blink::mojom::AppBannerPromptReply reply, |
| 481 int request_id, | 491 const std::string& referrer) { |
| 482 blink::WebAppBannerPromptReply reply, | |
| 483 std::string referrer) { | |
| 484 content::WebContents* contents = web_contents(); | 492 content::WebContents* contents = web_contents(); |
| 485 if (request_id != event_request_id_) | |
|
benwells
2016/10/12 03:00:17
I assume this check here was to guarantee somethin
dominickn
2016/10/13 00:18:15
This is implicitly handled because OnBannerPromptR
| |
| 486 return; | |
| 487 | |
| 488 // The renderer might have requested the prompt to be canceled. | 493 // The renderer might have requested the prompt to be canceled. |
| 489 // They may request that it is redisplayed later, so don't Stop() here. | 494 // They may request that it is redisplayed later, so don't Stop() here. |
| 490 // However, log that the cancelation was requested, so Stop() can be | 495 // However, log that the cancelation was requested, so Stop() can be |
| 491 // called if a redisplay isn't asked for. | 496 // called if a redisplay isn't asked for. |
| 492 // | 497 // |
| 493 // We use the additional page_requested_prompt_ variable because the redisplay | 498 // We use the additional page_requested_prompt_ variable because the redisplay |
| 494 // request may be received *before* the Cancel prompt reply (e.g. if redisplay | 499 // request may be received *before* the Cancel prompt reply (e.g. if redisplay |
| 495 // is requested in the beforeinstallprompt event handler). | 500 // is requested in the beforeinstallprompt event handler). |
| 496 referrer_ = referrer; | 501 referrer_ = referrer; |
| 497 if (reply == blink::WebAppBannerPromptReply::Cancel && | 502 if (reply == blink::mojom::AppBannerPromptReply::CANCEL && |
| 498 !page_requested_prompt_) { | 503 !page_requested_prompt_) { |
| 499 TrackBeforeInstallEvent(BEFORE_INSTALL_EVENT_PREVENT_DEFAULT_CALLED); | 504 TrackBeforeInstallEvent(BEFORE_INSTALL_EVENT_PREVENT_DEFAULT_CALLED); |
| 500 was_canceled_by_page_ = true; | 505 was_canceled_by_page_ = true; |
| 501 return; | 506 return; |
| 502 } | 507 } |
| 503 | 508 |
| 504 // If we haven't yet returned, but either of |was_canceled_by_page_| or | 509 // If we haven't yet returned, but either of |was_canceled_by_page_| or |
| 505 // |page_requested_prompt_| is true, the page has requested a delayed showing | 510 // |page_requested_prompt_| is true, the page has requested a delayed showing |
| 506 // of the prompt. Otherwise, the prompt was never canceled by the page. | 511 // of the prompt. Otherwise, the prompt was never canceled by the page. |
| 507 if (was_canceled_by_page_ || page_requested_prompt_) { | 512 if (was_canceled_by_page_ || page_requested_prompt_) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 518 DCHECK(!manifest_url_.is_empty()); | 523 DCHECK(!manifest_url_.is_empty()); |
| 519 DCHECK(!manifest_.IsEmpty()); | 524 DCHECK(!manifest_.IsEmpty()); |
| 520 DCHECK(!icon_url_.is_empty()); | 525 DCHECK(!icon_url_.is_empty()); |
| 521 DCHECK(icon_.get()); | 526 DCHECK(icon_.get()); |
| 522 | 527 |
| 523 TrackBeforeInstallEvent(BEFORE_INSTALL_EVENT_COMPLETE); | 528 TrackBeforeInstallEvent(BEFORE_INSTALL_EVENT_COMPLETE); |
| 524 ShowBanner(); | 529 ShowBanner(); |
| 525 is_active_ = false; | 530 is_active_ = false; |
| 526 } | 531 } |
| 527 | 532 |
| 528 void AppBannerManager::OnRequestShowAppBanner( | 533 void AppBannerManager::DisplayAppBanner() { |
| 529 content::RenderFrameHost* render_frame_host, | |
| 530 int request_id) { | |
| 531 if (was_canceled_by_page_) { | 534 if (was_canceled_by_page_) { |
| 532 // Simulate a non-canceled OnBannerPromptReply to show the delayed banner. | 535 // Simulate a non-canceled OnBannerPromptReply to show the delayed banner. |
| 533 // Don't reset |was_canceled_by_page_| yet for metrics purposes. | 536 // Don't reset |was_canceled_by_page_| yet for metrics purposes. |
| 534 OnBannerPromptReply(render_frame_host, request_id, | 537 OnBannerPromptReply(blink::mojom::AppBannerPromptReply::NONE, referrer_); |
| 535 blink::WebAppBannerPromptReply::None, referrer_); | |
| 536 } else { | 538 } else { |
| 537 // Log that the prompt request was made for when we get the prompt reply. | 539 // Log that the prompt request was made for when we get the prompt reply. |
| 538 page_requested_prompt_ = true; | 540 page_requested_prompt_ = true; |
| 539 } | 541 } |
| 540 } | 542 } |
| 541 | 543 |
| 542 } // namespace banners | 544 } // namespace banners |
| OLD | NEW |