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> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 // Don't start a redundant banner request. Otherwise, if one is running, | 71 // Don't start a redundant banner request. Otherwise, if one is running, |
72 // invalidate our weak pointers so it terminates. | 72 // invalidate our weak pointers so it terminates. |
73 if (is_active()) { | 73 if (is_active()) { |
74 if (URLsAreForTheSamePage(validated_url, contents->GetLastCommittedURL())) | 74 if (URLsAreForTheSamePage(validated_url, contents->GetLastCommittedURL())) |
75 return; | 75 return; |
76 else | 76 else |
77 weak_factory_.InvalidateWeakPtrs(); | 77 weak_factory_.InvalidateWeakPtrs(); |
78 } | 78 } |
79 | 79 |
80 UpdateState(State::ACTIVE); | 80 UpdateState(State::ACTIVE); |
81 is_debug_mode_ = is_debug_mode; | 81 triggered_by_devtools_ = is_debug_mode; |
82 page_requested_prompt_ = false; | 82 page_requested_prompt_ = false; |
83 | 83 |
84 // We only need to call ReportStatus if we aren't in debug mode (this avoids | 84 // We only need to call ReportStatus if we aren't in debug mode (this avoids |
85 // skew from testing). | 85 // skew from testing). |
86 DCHECK(!need_to_log_status_); | 86 DCHECK(!need_to_log_status_); |
87 need_to_log_status_ = !IsDebugMode(); | 87 need_to_log_status_ = !IsDebugMode(); |
88 | 88 |
89 // Exit if this is an incognito window, non-main frame, or insecure context. | 89 // Exit if this is an incognito window, non-main frame, or insecure context. |
90 InstallableStatusCode code = NO_ERROR_DETECTED; | 90 InstallableStatusCode code = NO_ERROR_DETECTED; |
91 if (Profile::FromBrowserContext(contents->GetBrowserContext()) | 91 if (Profile::FromBrowserContext(contents->GetBrowserContext()) |
(...skipping 11 matching lines...) Expand all Loading... |
103 return; | 103 return; |
104 } | 104 } |
105 | 105 |
106 if (validated_url_.is_empty()) | 106 if (validated_url_.is_empty()) |
107 validated_url_ = validated_url; | 107 validated_url_ = validated_url; |
108 | 108 |
109 // Any existing binding is invalid when we request a new banner. | 109 // Any existing binding is invalid when we request a new banner. |
110 if (binding_.is_bound()) | 110 if (binding_.is_bound()) |
111 binding_.Close(); | 111 binding_.Close(); |
112 | 112 |
| 113 UpdateState(State::PENDING_MANIFEST); |
113 manager_->GetData( | 114 manager_->GetData( |
114 ParamsToGetManifest(), | 115 ParamsToGetManifest(), |
115 base::Bind(&AppBannerManager::OnDidGetManifest, GetWeakPtr())); | 116 base::Bind(&AppBannerManager::OnDidGetManifest, GetWeakPtr())); |
116 } | 117 } |
117 | 118 |
118 void AppBannerManager::OnInstall() { | 119 void AppBannerManager::OnInstall() { |
119 blink::mojom::InstallationServicePtr installation_service; | 120 blink::mojom::InstallationServicePtr installation_service; |
120 web_contents()->GetMainFrame()->GetRemoteInterfaces()->GetInterface( | 121 web_contents()->GetMainFrame()->GetRemoteInterfaces()->GetInterface( |
121 mojo::MakeRequest(&installation_service)); | 122 mojo::MakeRequest(&installation_service)); |
122 DCHECK(installation_service); | 123 DCHECK(installation_service); |
(...skipping 24 matching lines...) Expand all Loading... |
147 : content::WebContentsObserver(web_contents), | 148 : content::WebContentsObserver(web_contents), |
148 SiteEngagementObserver(SiteEngagementService::Get( | 149 SiteEngagementObserver(SiteEngagementService::Get( |
149 Profile::FromBrowserContext(web_contents->GetBrowserContext()))), | 150 Profile::FromBrowserContext(web_contents->GetBrowserContext()))), |
150 state_(State::INACTIVE), | 151 state_(State::INACTIVE), |
151 manager_(nullptr), | 152 manager_(nullptr), |
152 event_request_id_(-1), | 153 event_request_id_(-1), |
153 binding_(this), | 154 binding_(this), |
154 has_sufficient_engagement_(false), | 155 has_sufficient_engagement_(false), |
155 load_finished_(false), | 156 load_finished_(false), |
156 page_requested_prompt_(false), | 157 page_requested_prompt_(false), |
157 is_debug_mode_(false), | 158 triggered_by_devtools_(false), |
158 need_to_log_status_(false), | 159 need_to_log_status_(false), |
159 weak_factory_(this) { | 160 weak_factory_(this) { |
160 // Ensure the InstallableManager exists since we have a hard dependency on it. | 161 // Ensure the InstallableManager exists since we have a hard dependency on it. |
161 InstallableManager::CreateForWebContents(web_contents); | 162 InstallableManager::CreateForWebContents(web_contents); |
162 manager_ = InstallableManager::FromWebContents(web_contents); | 163 manager_ = InstallableManager::FromWebContents(web_contents); |
163 DCHECK(manager_); | 164 DCHECK(manager_); |
164 | 165 |
165 AppBannerSettingsHelper::UpdateFromFieldTrial(); | 166 AppBannerSettingsHelper::UpdateFromFieldTrial(); |
166 } | 167 } |
167 | 168 |
(...skipping 18 matching lines...) Expand all Loading... |
186 | 187 |
187 int AppBannerManager::GetIdealPrimaryIconSizeInPx() { | 188 int AppBannerManager::GetIdealPrimaryIconSizeInPx() { |
188 return InstallableManager::GetMinimumIconSizeInPx(); | 189 return InstallableManager::GetMinimumIconSizeInPx(); |
189 } | 190 } |
190 | 191 |
191 int AppBannerManager::GetMinimumPrimaryIconSizeInPx() { | 192 int AppBannerManager::GetMinimumPrimaryIconSizeInPx() { |
192 return InstallableManager::GetMinimumIconSizeInPx(); | 193 return InstallableManager::GetMinimumIconSizeInPx(); |
193 } | 194 } |
194 | 195 |
195 bool AppBannerManager::IsDebugMode() const { | 196 bool AppBannerManager::IsDebugMode() const { |
196 return is_debug_mode_ || | 197 return triggered_by_devtools_ || |
197 base::CommandLine::ForCurrentProcess()->HasSwitch( | 198 base::CommandLine::ForCurrentProcess()->HasSwitch( |
198 switches::kBypassAppBannerEngagementChecks); | 199 switches::kBypassAppBannerEngagementChecks); |
199 } | 200 } |
200 | 201 |
201 bool AppBannerManager::IsWebAppInstalled( | 202 bool AppBannerManager::IsWebAppInstalled( |
202 content::BrowserContext* browser_context, | 203 content::BrowserContext* browser_context, |
203 const GURL& start_url, | 204 const GURL& start_url, |
204 const GURL& manifest_url) { | 205 const GURL& manifest_url) { |
205 return false; | 206 return false; |
206 } | 207 } |
207 | 208 |
208 void AppBannerManager::OnDidGetManifest(const InstallableData& data) { | 209 void AppBannerManager::OnDidGetManifest(const InstallableData& data) { |
| 210 UpdateState(State::ACTIVE); |
209 if (data.error_code != NO_ERROR_DETECTED) { | 211 if (data.error_code != NO_ERROR_DETECTED) { |
210 ReportStatus(web_contents(), data.error_code); | 212 ReportStatus(web_contents(), data.error_code); |
211 Stop(); | 213 Stop(); |
212 } | 214 } |
213 | 215 |
214 if (!is_active()) | 216 if (!is_active()) |
215 return; | 217 return; |
216 | 218 |
217 DCHECK(!data.manifest_url.is_empty()); | 219 DCHECK(!data.manifest_url.is_empty()); |
218 DCHECK(!data.manifest.IsEmpty()); | 220 DCHECK(!data.manifest.IsEmpty()); |
(...skipping 11 matching lines...) Expand all Loading... |
230 PerformInstallableCheck(); | 232 PerformInstallableCheck(); |
231 } | 233 } |
232 | 234 |
233 InstallableParams AppBannerManager::ParamsToPerformInstallableCheck() { | 235 InstallableParams AppBannerManager::ParamsToPerformInstallableCheck() { |
234 InstallableParams params; | 236 InstallableParams params; |
235 params.ideal_primary_icon_size_in_px = GetIdealPrimaryIconSizeInPx(); | 237 params.ideal_primary_icon_size_in_px = GetIdealPrimaryIconSizeInPx(); |
236 params.minimum_primary_icon_size_in_px = GetMinimumPrimaryIconSizeInPx(); | 238 params.minimum_primary_icon_size_in_px = GetMinimumPrimaryIconSizeInPx(); |
237 params.check_installable = true; | 239 params.check_installable = true; |
238 params.fetch_valid_primary_icon = true; | 240 params.fetch_valid_primary_icon = true; |
239 | 241 |
| 242 // Don't wait for the service worker if this was triggered from devtools. |
| 243 params.wait_for_worker = !triggered_by_devtools_; |
| 244 |
240 return params; | 245 return params; |
241 } | 246 } |
242 | 247 |
243 void AppBannerManager::PerformInstallableCheck() { | 248 void AppBannerManager::PerformInstallableCheck() { |
244 if (!CheckIfShouldShowBanner()) | 249 if (!CheckIfShouldShowBanner()) |
245 return; | 250 return; |
246 | 251 |
247 // Fetch and verify the other required information. | 252 // Fetch and verify the other required information. |
| 253 UpdateState(State::PENDING_INSTALLABLE_CHECK); |
248 manager_->GetData(ParamsToPerformInstallableCheck(), | 254 manager_->GetData(ParamsToPerformInstallableCheck(), |
249 base::Bind(&AppBannerManager::OnDidPerformInstallableCheck, | 255 base::Bind(&AppBannerManager::OnDidPerformInstallableCheck, |
250 GetWeakPtr())); | 256 GetWeakPtr())); |
251 } | 257 } |
252 | 258 |
253 void AppBannerManager::OnDidPerformInstallableCheck( | 259 void AppBannerManager::OnDidPerformInstallableCheck( |
254 const InstallableData& data) { | 260 const InstallableData& data) { |
| 261 UpdateState(State::ACTIVE); |
255 if (data.is_installable) | 262 if (data.is_installable) |
256 TrackDisplayEvent(DISPLAY_EVENT_WEB_APP_BANNER_REQUESTED); | 263 TrackDisplayEvent(DISPLAY_EVENT_WEB_APP_BANNER_REQUESTED); |
257 | 264 |
258 if (data.error_code != NO_ERROR_DETECTED) { | 265 if (data.error_code != NO_ERROR_DETECTED) { |
259 if (data.error_code == NO_MATCHING_SERVICE_WORKER) | 266 if (data.error_code == NO_MATCHING_SERVICE_WORKER) |
260 TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER); | 267 TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER); |
261 | 268 |
262 ReportStatus(web_contents(), data.error_code); | 269 ReportStatus(web_contents(), data.error_code); |
263 Stop(); | 270 Stop(); |
264 } | 271 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 | 319 |
313 void AppBannerManager::ResetCurrentPageData() { | 320 void AppBannerManager::ResetCurrentPageData() { |
314 active_media_players_.clear(); | 321 active_media_players_.clear(); |
315 manifest_ = content::Manifest(); | 322 manifest_ = content::Manifest(); |
316 manifest_url_ = GURL(); | 323 manifest_url_ = GURL(); |
317 validated_url_ = GURL(); | 324 validated_url_ = GURL(); |
318 referrer_.erase(); | 325 referrer_.erase(); |
319 } | 326 } |
320 | 327 |
321 void AppBannerManager::Stop() { | 328 void AppBannerManager::Stop() { |
322 if (state_ == State::PENDING_EVENT && !page_requested_prompt_) { | 329 // Record the status if we are currently waiting for data. |
323 TrackBeforeInstallEvent( | 330 InstallableStatusCode code = NO_ERROR_DETECTED; |
324 BEFORE_INSTALL_EVENT_PROMPT_NOT_CALLED_AFTER_PREVENT_DEFAULT); | 331 switch (state_) { |
325 ReportStatus(web_contents(), RENDERER_CANCELLED); | 332 case State::PENDING_EVENT: |
326 } else if (state_ == State::PENDING_ENGAGEMENT && | 333 if (!page_requested_prompt_) { |
327 !has_sufficient_engagement_) { | 334 TrackBeforeInstallEvent( |
328 TrackDisplayEvent(DISPLAY_EVENT_NOT_VISITED_ENOUGH); | 335 BEFORE_INSTALL_EVENT_PROMPT_NOT_CALLED_AFTER_PREVENT_DEFAULT); |
329 ReportStatus(web_contents(), INSUFFICIENT_ENGAGEMENT); | 336 code = RENDERER_CANCELLED; |
| 337 } |
| 338 break; |
| 339 case State::PENDING_ENGAGEMENT: |
| 340 if (!has_sufficient_engagement_) { |
| 341 TrackDisplayEvent(DISPLAY_EVENT_NOT_VISITED_ENOUGH); |
| 342 code = INSUFFICIENT_ENGAGEMENT; |
| 343 } |
| 344 break; |
| 345 case State::PENDING_MANIFEST: |
| 346 code = WAITING_FOR_MANIFEST; |
| 347 break; |
| 348 case State::PENDING_INSTALLABLE_CHECK: |
| 349 code = WAITING_FOR_INSTALLABLE_CHECK; |
| 350 break; |
| 351 case State::ACTIVE: |
| 352 case State::INACTIVE: |
| 353 case State::COMPLETE: |
| 354 break; |
330 } | 355 } |
331 | 356 |
| 357 if (code != NO_ERROR_DETECTED) |
| 358 ReportStatus(web_contents(), code); |
| 359 |
332 // In every non-debug run through the banner pipeline, we should have called | 360 // In every non-debug run through the banner pipeline, we should have called |
333 // ReportStatus() and set need_to_log_status_ to false. The only case where | 361 // ReportStatus() and set need_to_log_status_ to false. The only case where |
334 // we don't is if we're still active and waiting for a callback from the | 362 // we don't is if we're still active and waiting for native app data, which is |
335 // InstallableManager (e.g. the renderer crashes or the browser is shutting | 363 // explicitly not logged. |
336 // down). These situations are explicitly not logged. | |
337 DCHECK(!need_to_log_status_ || is_active()); | 364 DCHECK(!need_to_log_status_ || is_active()); |
338 | 365 |
339 weak_factory_.InvalidateWeakPtrs(); | 366 weak_factory_.InvalidateWeakPtrs(); |
340 binding_.Close(); | 367 binding_.Close(); |
341 controller_.reset(); | 368 controller_.reset(); |
342 event_.reset(); | 369 event_.reset(); |
343 | 370 |
344 UpdateState(State::COMPLETE); | 371 UpdateState(State::COMPLETE); |
345 need_to_log_status_ = false; | 372 need_to_log_status_ = false; |
346 has_sufficient_engagement_ = false; | 373 has_sufficient_engagement_ = false; |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 if (is_pending_event()) { | 587 if (is_pending_event()) { |
561 // Simulate a non-canceled OnBannerPromptReply to show the delayed banner. | 588 // Simulate a non-canceled OnBannerPromptReply to show the delayed banner. |
562 OnBannerPromptReply(blink::mojom::AppBannerPromptReply::NONE, referrer_); | 589 OnBannerPromptReply(blink::mojom::AppBannerPromptReply::NONE, referrer_); |
563 } else { | 590 } else { |
564 // Log that the prompt request was made for when we get the prompt reply. | 591 // Log that the prompt request was made for when we get the prompt reply. |
565 page_requested_prompt_ = true; | 592 page_requested_prompt_ = true; |
566 } | 593 } |
567 } | 594 } |
568 | 595 |
569 } // namespace banners | 596 } // namespace banners |
OLD | NEW |