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

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