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

Side by Side Diff: chrome/browser/banners/app_banner_manager.cc

Issue 2156113002: Replace AppBannerDataFetcher with InstallableManager. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@banner-refactor
Patch Set: Address comments Created 4 years, 4 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/banners/app_banner_manager.h" 5 #include "chrome/browser/banners/app_banner_manager.h"
6 6
7 #include "chrome/browser/banners/app_banner_data_fetcher.h" 7 #include "base/bind.h"
8 #include "chrome/browser/banners/app_banner_debug_log.h" 8 #include "base/callback.h"
9 #include "base/command_line.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/time/time.h"
12 #include "chrome/browser/banners/app_banner_metrics.h"
9 #include "chrome/browser/banners/app_banner_settings_helper.h" 13 #include "chrome/browser/banners/app_banner_settings_helper.h"
14 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/engagement/site_engagement_service.h" 15 #include "chrome/browser/engagement/site_engagement_service.h"
16 #include "chrome/browser/installable/installable_logging.h"
17 #include "chrome/browser/installable/installable_manager.h"
11 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/common/chrome_switches.h"
20 #include "chrome/common/render_messages.h"
21 #include "components/rappor/rappor_utils.h"
12 #include "content/public/browser/navigation_handle.h" 22 #include "content/public/browser/navigation_handle.h"
13 #include "content/public/browser/render_frame_host.h" 23 #include "content/public/browser/render_frame_host.h"
14 #include "content/public/browser/web_contents.h" 24 #include "content/public/browser/web_contents.h"
15 #include "content/public/common/frame_navigate_params.h"
16 #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"
27 #include "third_party/skia/include/core/SkBitmap.h"
28 #include "ui/display/display.h"
29 #include "ui/display/screen.h"
17 30
18 namespace { 31 namespace {
32
19 bool gDisableSecureCheckForTesting = false; 33 bool gDisableSecureCheckForTesting = false;
34 int gCurrentRequestID = -1;
35 base::LazyInstance<base::TimeDelta> gTimeDeltaForTesting =
36 LAZY_INSTANCE_INITIALIZER;
37
38 // Returns |size_in_px| in dp, i.e. divided by the current device scale factor.
39 int ConvertIconSizeFromPxToDp(int size_in_px) {
40 return size_in_px /
41 display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor();
42 }
43
44 // Returns an InstallableParams object that requests all checks necessary for
45 // a web app banner.
46 InstallableParams GetWebAppParams(int ideal_icon_size_in_dp,
47 int minimum_icon_size_in_dp) {
48 InstallableParams params;
49 params.ideal_icon_size_in_dp = ideal_icon_size_in_dp;
50 params.minimum_icon_size_in_dp = minimum_icon_size_in_dp;
51 params.check_installable = true;
52 params.fetch_valid_icon = true;
53
54 return params;
55 }
56
20 } // anonymous namespace 57 } // anonymous namespace
21 58
22 namespace banners { 59 namespace banners {
23 60
61 // static
24 void AppBannerManager::DisableSecureSchemeCheckForTesting() { 62 void AppBannerManager::DisableSecureSchemeCheckForTesting() {
25 gDisableSecureCheckForTesting = true; 63 gDisableSecureCheckForTesting = true;
26 } 64 }
27 65
66 // static
67 base::Time AppBannerManager::GetCurrentTime() {
benwells 2016/08/09 03:41:26 nit: If GetCurrentTime is only used for testing, c
dominickn 2016/08/09 08:28:57 It's not only used for testing - it's also used fo
benwells 2016/08/10 03:36:05 Acknowledged.
68 return base::Time::Now() + gTimeDeltaForTesting.Get();
69 }
70
71 // static
72 void AppBannerManager::SetTimeDeltaForTesting(int days) {
73 gTimeDeltaForTesting.Get() = base::TimeDelta::FromDays(days);
74 }
75
76 // static
28 void AppBannerManager::SetEngagementWeights(double direct_engagement, 77 void AppBannerManager::SetEngagementWeights(double direct_engagement,
29 double indirect_engagement) { 78 double indirect_engagement) {
30 AppBannerSettingsHelper::SetEngagementWeights(direct_engagement, 79 AppBannerSettingsHelper::SetEngagementWeights(direct_engagement,
31 indirect_engagement); 80 indirect_engagement);
32 } 81 }
33 82
83 // static
34 bool AppBannerManager::URLsAreForTheSamePage(const GURL& first, 84 bool AppBannerManager::URLsAreForTheSamePage(const GURL& first,
35 const GURL& second) { 85 const GURL& second) {
36 return first.GetWithEmptyPath() == second.GetWithEmptyPath() && 86 return first.GetWithEmptyPath() == second.GetWithEmptyPath() &&
37 first.path() == second.path() && first.query() == second.query(); 87 first.path() == second.path() && first.query() == second.query();
38 } 88 }
39 89
40 AppBannerManager::AppBannerManager(content::WebContents* web_contents)
41 : content::WebContentsObserver(web_contents),
42 SiteEngagementObserver(nullptr),
43 data_fetcher_(nullptr),
44 banner_request_queued_(false),
45 load_finished_(false),
46 weak_factory_(this) {
47 AppBannerSettingsHelper::UpdateFromFieldTrial();
48 }
49
50 AppBannerManager::~AppBannerManager() {
51 CancelActiveFetcher();
52 }
53
54 void AppBannerManager::ReplaceWebContents(content::WebContents* web_contents) {
55 content::WebContentsObserver::Observe(web_contents);
56 if (data_fetcher_.get())
57 data_fetcher_.get()->ReplaceWebContents(web_contents);
58 }
59
60 bool AppBannerManager::IsFetcherActive() {
61 return data_fetcher_ && data_fetcher_->is_active();
62 }
63
64 void AppBannerManager::RequestAppBanner(const GURL& validated_url, 90 void AppBannerManager::RequestAppBanner(const GURL& validated_url,
65 bool is_debug_mode) { 91 bool is_debug_mode) {
66 content::WebContents* contents = web_contents(); 92 content::WebContents* contents = web_contents();
67 if (contents->GetMainFrame()->GetParent()) { 93 if (contents->GetMainFrame()->GetParent()) {
68 OutputDeveloperNotShownMessage(contents, kNotLoadedInMainFrame, 94 ReportError(contents, NOT_IN_MAIN_FRAME);
69 is_debug_mode); 95 return;
70 return; 96 }
71 } 97
72 98 // Don't start a redundant banner request.
73 if (data_fetcher_.get() && data_fetcher_->is_active() && 99 if (is_active_ &&
74 URLsAreForTheSamePage(data_fetcher_->validated_url(), validated_url) && 100 URLsAreForTheSamePage(validated_url, contents->GetLastCommittedURL())) {
75 !is_debug_mode) {
76 return; 101 return;
77 } 102 }
78 103
79 // A secure origin is required to show banners, so exit early if we see the 104 // A secure origin is required to show banners, so exit early if we see the
80 // URL is invalid. 105 // URL is invalid.
81 if (!content::IsOriginSecure(validated_url) && 106 if (!content::IsOriginSecure(validated_url) &&
82 !gDisableSecureCheckForTesting) { 107 !gDisableSecureCheckForTesting) {
83 OutputDeveloperNotShownMessage(contents, kNotServedFromSecureOrigin, 108 ReportError(contents, NOT_FROM_SECURE_ORIGIN);
84 is_debug_mode); 109 return;
85 return; 110 }
86 } 111
87 112 is_debug_mode_ = is_debug_mode;
88 // Kick off the data retrieval pipeline. 113 is_active_ = true;
89 data_fetcher_ = 114
90 CreateAppBannerDataFetcher(weak_factory_.GetWeakPtr(), is_debug_mode); 115 // We start by requesting the manifest from the InstallableManager. The
91 data_fetcher_->Start(validated_url, last_transition_type_); 116 // default-constructed params will have all other fields as false.
92 } 117 InstallableParams params;
93 118 manager_->GetData(
benwells 2016/08/09 03:41:26 Now I've seen this API in use it seems a bit awkwa
dominickn 2016/08/09 08:28:57 Acknowledged. I'd like to defer bigger changes to
94 void AppBannerManager::DidStartNavigation( 119 params, base::Bind(&AppBannerManager::OnDidGetManifest, GetWeakPtr()));
95 content::NavigationHandle* navigation_handle) { 120 }
96 if (!navigation_handle->IsInMainFrame()) 121
122 base::Closure AppBannerManager::FetchWebappSplashScreenImageCallback(
123 const std::string& webapp_id) {
124 return base::Closure();
125 }
126
127 AppBannerManager::AppBannerManager(content::WebContents* web_contents)
128 : content::WebContentsObserver(web_contents),
129 SiteEngagementObserver(nullptr),
130 manager_(nullptr),
131 event_request_id_(-1),
132 is_active_(false),
133 banner_request_queued_(false),
134 load_finished_(false),
135 was_canceled_by_page_(false),
136 page_requested_prompt_(false),
137 is_debug_mode_(false),
138 weak_factory_(this) {
139 // Ensure the InstallableManager exists since we have a hard dependency on it.
140 InstallableManager::CreateForWebContents(web_contents);
141 manager_ = InstallableManager::FromWebContents(web_contents);
142 DCHECK(manager_);
143
144 AppBannerSettingsHelper::UpdateFromFieldTrial();
145 }
146
147 AppBannerManager::~AppBannerManager() { }
148
149 std::string AppBannerManager::GetAppIdentifier() {
150 DCHECK(!manifest_.IsEmpty());
151 return manifest_.start_url.spec();
152 }
153
154 std::string AppBannerManager::GetBannerType() {
155 return "web";
156 }
157
158 std::string AppBannerManager::GetErrorParam(InstallableErrorCode code) {
159 if (code == NO_ACCEPTABLE_ICON || code == MANIFEST_MISSING_SUITABLE_ICON) {
160 return base::IntToString(InstallableManager::GetMinimumIconSizeInPx());
161 }
162
163 return std::string();
164 }
165
166 int AppBannerManager::GetIdealIconSizeInDp() {
167 return ConvertIconSizeFromPxToDp(
168 InstallableManager::GetMinimumIconSizeInPx());
169 }
170
171 int AppBannerManager::GetMinimumIconSizeInDp() {
172 return ConvertIconSizeFromPxToDp(
173 InstallableManager::GetMinimumIconSizeInPx());
174 }
175
176 base::WeakPtr<AppBannerManager> AppBannerManager::GetWeakPtr() {
177 return weak_factory_.GetWeakPtr();
178 }
179
180 bool AppBannerManager::IsDebugMode() const {
181 return is_debug_mode_ ||
182 base::CommandLine::ForCurrentProcess()->HasSwitch(
183 switches::kBypassAppBannerEngagementChecks);
184 }
185
186 bool AppBannerManager::IsWebAppInstalled(
187 content::BrowserContext* browser_context,
188 const GURL& start_url) {
189 return false;
190 }
191
192 void AppBannerManager::OnDidGetManifest(const InstallableData& data) {
193 if (data.error_code != NO_ERROR_DETECTED) {
194 ReportError(web_contents(), data.error_code);
195 Stop();
196 }
197
198 if (!is_active_)
199 return;
200
201 DCHECK(!data.manifest_url.is_empty());
202 DCHECK(!data.manifest.IsEmpty());
203
204 manifest_url_ = data.manifest_url;
205 manifest_ = data.manifest;
206 app_title_ = (manifest_.name.is_null()) ? manifest_.short_name.string()
207 : manifest_.name.string();
208
209 ContinueInstallableCheck();
210 }
211
212 void AppBannerManager::ContinueInstallableCheck() {
213 if (IsWebAppInstalled(web_contents()->GetBrowserContext(),
214 manifest_.start_url) &&
215 !IsDebugMode()) {
216 Stop();
217 }
218
219 if (!is_active_)
220 return;
221
222 // Fetch and verify the other required information.
223 manager_->GetData(
224 GetWebAppParams(GetIdealIconSizeInDp(), GetMinimumIconSizeInDp()),
225 base::Bind(&AppBannerManager::OnDidFinishInstallableCheck, GetWeakPtr()));
226 }
227
228 void AppBannerManager::OnDidFinishInstallableCheck(
229 const InstallableData& data) {
230 if (data.is_installable)
231 TrackDisplayEvent(DISPLAY_EVENT_WEB_APP_BANNER_REQUESTED);
232
233 if (data.error_code != NO_ERROR_DETECTED) {
234 if (data.error_code == NO_MATCHING_SERVICE_WORKER)
235 TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER);
236
237 ReportError(web_contents(), data.error_code);
238 Stop();
239 }
240
241 if (!is_active_)
242 return;
243
244 DCHECK(data.is_installable);
245 DCHECK(!data.icon_url.is_empty());
246 DCHECK(data.icon);
247
248 icon_url_ = data.icon_url;
249 icon_.reset(new SkBitmap(*data.icon));
250
251 SendBannerPromptRequest();
252 }
253
254 void AppBannerManager::RecordDidShowBanner(const std::string& event_name) {
255 content::WebContents* contents = web_contents();
256 DCHECK(contents);
257
258 AppBannerSettingsHelper::RecordBannerEvent(
259 contents, validated_url_, GetAppIdentifier(),
260 AppBannerSettingsHelper::APP_BANNER_EVENT_DID_SHOW,
261 GetCurrentTime());
262 rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(),
263 event_name,
264 contents->GetLastCommittedURL());
265 }
266
267 void AppBannerManager::ReportError(content::WebContents* web_contents,
268 InstallableErrorCode code) {
269 if (IsDebugMode())
270 LogErrorToConsole(web_contents, code, GetErrorParam(code));
271 }
272
273 void AppBannerManager::Stop() {
274 if (was_canceled_by_page_ && !page_requested_prompt_) {
275 TrackBeforeInstallEvent(
276 BEFORE_INSTALL_EVENT_PROMPT_NOT_CALLED_AFTER_PREVENT_DEFAULT);
277 }
278
279 is_active_ = false;
280 was_canceled_by_page_ = false;
281 page_requested_prompt_ = false;
282 referrer_.erase();
283 }
284
285 void AppBannerManager::SendBannerPromptRequest() {
286 RecordCouldShowBanner();
287
288 // Given all of the other checks that have been made, the only possible reason
289 // for stopping now is that the app has been added to the homescreen.
290 if (!IsDebugMode() && !CheckIfShouldShowBanner())
291 Stop();
292
293 if (!is_active_)
294 return;
295
296 TrackBeforeInstallEvent(BEFORE_INSTALL_EVENT_CREATED);
297 event_request_id_ = ++gCurrentRequestID;
298 content::RenderFrameHost* frame = web_contents()->GetMainFrame();
299 frame->Send(new ChromeViewMsg_AppBannerPromptRequest(
300 frame->GetRoutingID(), event_request_id_, GetBannerType()));
301 }
302
303 void AppBannerManager::DidStartNavigation(content::NavigationHandle* handle) {
304 if (!handle->IsInMainFrame())
97 return; 305 return;
98 306
99 load_finished_ = false; 307 load_finished_ = false;
100 if (AppBannerSettingsHelper::ShouldUseSiteEngagementScore() && 308 if (AppBannerSettingsHelper::ShouldUseSiteEngagementScore() &&
101 GetSiteEngagementService() == nullptr) { 309 GetSiteEngagementService() == nullptr) {
102 // Ensure that we are observing the site engagement service on navigation 310 // Ensure that we are observing the site engagement service on navigation
103 // start. This may be the first navigation, or we may have stopped 311 // start. This may be the first navigation, or we may have stopped
104 // observing if the banner flow was triggered on the previous page. 312 // observing if the banner flow was triggered on the previous page.
105 SiteEngagementObserver::Observe(SiteEngagementService::Get( 313 SiteEngagementObserver::Observe(SiteEngagementService::Get(
106 Profile::FromBrowserContext(web_contents()->GetBrowserContext()))); 314 Profile::FromBrowserContext(web_contents()->GetBrowserContext())));
107 } 315 }
108 } 316 }
109 317
110 void AppBannerManager::DidFinishNavigation( 318 void AppBannerManager::DidFinishNavigation(content::NavigationHandle* handle) {
111 content::NavigationHandle* navigation_handle) { 319 if (handle->IsInMainFrame() && handle->HasCommitted()) {
112 if (navigation_handle->HasCommitted()) 320 last_transition_type_ = handle->GetPageTransition();
113 last_transition_type_ = navigation_handle->GetPageTransition(); 321 active_media_players_.clear();
322 if (is_active_)
323 Stop();
324 }
114 } 325 }
115 326
116 void AppBannerManager::DidFinishLoad( 327 void AppBannerManager::DidFinishLoad(
117 content::RenderFrameHost* render_frame_host, 328 content::RenderFrameHost* render_frame_host,
118 const GURL& validated_url) { 329 const GURL& validated_url) {
119 // Don't start the banner flow unless the main frame has finished loading. 330 // Don't start the banner flow unless the main frame has finished loading.
120 if (render_frame_host->GetParent()) 331 if (render_frame_host->GetParent())
121 return; 332 return;
122 333
123 load_finished_ = true; 334 load_finished_ = true;
335 validated_url_ = validated_url;
124 if (!AppBannerSettingsHelper::ShouldUseSiteEngagementScore() || 336 if (!AppBannerSettingsHelper::ShouldUseSiteEngagementScore() ||
125 banner_request_queued_) { 337 banner_request_queued_) {
126 banner_request_queued_ = false; 338 banner_request_queued_ = false;
127 339
128 // The third argument is the is_debug_mode boolean value, which is true only
129 // when it is triggered by the developer's action in DevTools.
130 RequestAppBanner(validated_url, false /* is_debug_mode */); 340 RequestAppBanner(validated_url, false /* is_debug_mode */);
131 } 341 }
132 } 342 }
133 343
134 void AppBannerManager::MediaStartedPlaying(const MediaPlayerId& id) { 344 void AppBannerManager::MediaStartedPlaying(const MediaPlayerId& id) {
135 active_media_players_.push_back(id); 345 active_media_players_.push_back(id);
136 } 346 }
137 347
138 void AppBannerManager::MediaStoppedPlaying(const MediaPlayerId& id) { 348 void AppBannerManager::MediaStoppedPlaying(const MediaPlayerId& id) {
139 active_media_players_.erase(std::remove(active_media_players_.begin(), 349 active_media_players_.erase(std::remove(active_media_players_.begin(),
140 active_media_players_.end(), id), 350 active_media_players_.end(), id),
141 active_media_players_.end()); 351 active_media_players_.end());
142 } 352 }
143 353
144 bool AppBannerManager::HandleNonWebApp(const std::string& platform, 354 void AppBannerManager::WebContentsDestroyed() {
145 const GURL& url, 355 Stop();
146 const std::string& id,
147 bool is_debug_mode) {
148 return false;
149 } 356 }
150 357
151 void AppBannerManager::OnEngagementIncreased(content::WebContents* contents, 358 void AppBannerManager::OnEngagementIncreased(content::WebContents* contents,
152 const GURL& url, 359 const GURL& url,
153 double score) { 360 double score) {
154 // Only trigger a banner using site engagement if: 361 // Only trigger a banner using site engagement if:
155 // 1. engagement increased for the web contents which we are attached to; and 362 // 1. engagement increased for the web contents which we are attached to; and
156 // 2. there are no currently active media players; and 363 // 2. there are no currently active media players; and
157 // 3. we have accumulated sufficient engagement. 364 // 3. we have accumulated sufficient engagement.
158 if (web_contents() == contents && active_media_players_.empty() && 365 if (web_contents() == contents && active_media_players_.empty() &&
159 AppBannerSettingsHelper::HasSufficientEngagement(score)) { 366 AppBannerSettingsHelper::HasSufficientEngagement(score)) {
160 // Stop observing so we don't double-trigger the banner. 367 // Stop observing so we don't double-trigger the banner.
161 SiteEngagementObserver::Observe(nullptr); 368 SiteEngagementObserver::Observe(nullptr);
162 369
163 if (!load_finished_) { 370 if (!load_finished_) {
164 // Wait until the main frame finishes loading before requesting a banner. 371 // Wait until the main frame finishes loading before requesting a banner.
165 banner_request_queued_ = true; 372 banner_request_queued_ = true;
166 } else { 373 } else {
167 // Requesting a banner performs some simple tests, creates a data fetcher, 374 // Requesting a banner performs some simple tests, creates a data fetcher,
168 // and starts some asynchronous checks to test installability. It should 375 // and starts some asynchronous checks to test installability. It should
169 // be safe to start this in response to user input. 376 // be safe to start this in response to user input.
170 RequestAppBanner(url, false /* is_debug_mode */); 377 RequestAppBanner(url, false /* is_debug_mode */);
171 } 378 }
172 } 379 }
173 } 380 }
174 381
175 void AppBannerManager::CancelActiveFetcher() { 382 void AppBannerManager::RecordCouldShowBanner() {
176 if (data_fetcher_) { 383 content::WebContents* contents = web_contents();
177 data_fetcher_->Cancel(); 384 DCHECK(contents);
178 data_fetcher_ = nullptr; 385
386 AppBannerSettingsHelper::RecordBannerCouldShowEvent(
387 contents, validated_url_, GetAppIdentifier(),
388 GetCurrentTime(), last_transition_type_);
389 }
390
391 bool AppBannerManager::CheckIfShouldShowBanner() {
392 content::WebContents* contents = web_contents();
393 DCHECK(contents);
394
395 return AppBannerSettingsHelper::ShouldShowBanner(
396 contents, validated_url_, GetAppIdentifier(), GetCurrentTime());
397 }
398
399 bool AppBannerManager::OnMessageReceived(
400 const IPC::Message& message,
401 content::RenderFrameHost* render_frame_host) {
402 bool handled = true;
403
404 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(AppBannerManager, message, render_frame_host)
405 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AppBannerPromptReply,
406 OnBannerPromptReply)
407 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_RequestShowAppBanner,
408 OnRequestShowAppBanner)
409 IPC_MESSAGE_UNHANDLED(handled = false)
410 IPC_END_MESSAGE_MAP()
411
412 return handled;
413 }
414
415 void AppBannerManager::OnBannerPromptReply(
416 content::RenderFrameHost* render_frame_host,
417 int request_id,
418 blink::WebAppBannerPromptReply reply,
419 std::string referrer) {
420 content::WebContents* contents = web_contents();
421 if (request_id != event_request_id_)
422 return;
423
424 // The renderer might have requested the prompt to be canceled.
425 // They may request that it is redisplayed later, so don't Stop() here.
426 // However, log that the cancelation was requested, so Stop() can be
427 // called if a redisplay isn't asked for.
428 //
429 // We use the additional page_requested_prompt_ variable because the redisplay
430 // request may be received *before* the Cancel prompt reply (e.g. if redisplay
431 // is requested in the beforeinstallprompt event handler).
432 referrer_ = referrer;
433 if (reply == blink::WebAppBannerPromptReply::Cancel &&
434 !page_requested_prompt_) {
435 TrackBeforeInstallEvent(BEFORE_INSTALL_EVENT_PREVENT_DEFAULT_CALLED);
436 was_canceled_by_page_ = true;
437 ReportError(contents, RENDERER_CANCELLED);
438 return;
439 }
440
441 // If we haven't yet returned, but either of |was_canceled_by_page_| or
442 // |page_requested_prompt_| is true, the page has requested a delayed showing
443 // of the prompt. Otherwise, the prompt was never canceled by the page.
444 if (was_canceled_by_page_ || page_requested_prompt_) {
445 TrackBeforeInstallEvent(
446 BEFORE_INSTALL_EVENT_PROMPT_CALLED_AFTER_PREVENT_DEFAULT);
447 was_canceled_by_page_ = false;
448 } else {
449 TrackBeforeInstallEvent(BEFORE_INSTALL_EVENT_NO_ACTION);
450 }
451
452 AppBannerSettingsHelper::RecordMinutesFromFirstVisitToShow(
453 contents, validated_url_, GetAppIdentifier(), GetCurrentTime());
454
455 DCHECK(!manifest_url_.is_empty());
456 DCHECK(!manifest_.IsEmpty());
457 DCHECK(!icon_url_.is_empty());
458 DCHECK(icon_.get());
459 TrackBeforeInstallEvent(BEFORE_INSTALL_EVENT_COMPLETE);
460 ShowBanner();
461 is_active_ = false;
462 }
463
464 void AppBannerManager::OnRequestShowAppBanner(
465 content::RenderFrameHost* render_frame_host,
466 int request_id) {
467 if (was_canceled_by_page_) {
468 // Simulate a non-canceled OnBannerPromptReply to show the delayed banner.
469 // Don't reset |was_canceled_by_page_| yet for metrics purposes.
470 OnBannerPromptReply(render_frame_host, request_id,
471 blink::WebAppBannerPromptReply::None, referrer_);
472 } else {
473 // Log that the prompt request was made for when we get the prompt reply.
474 page_requested_prompt_ = true;
179 } 475 }
180 } 476 }
181 477
182 } // namespace banners 478 } // namespace banners
OLDNEW
« no previous file with comments | « chrome/browser/banners/app_banner_manager.h ('k') | chrome/browser/banners/app_banner_manager_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698