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

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

Issue 1569893003: Add "Request app banner" context menu in DevTools (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase on https://codereview.chromium.org/1571633002/ Created 4 years, 11 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_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
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 event_request_id_(-1) { 86 event_request_id_(-1),
87 is_debug_mode_(is_debug_mode) {
87 DCHECK(minimum_icon_size_in_dp <= ideal_icon_size_in_dp); 88 DCHECK(minimum_icon_size_in_dp <= ideal_icon_size_in_dp);
88 } 89 }
89 90
90 void AppBannerDataFetcher::Start(const GURL& validated_url, 91 void AppBannerDataFetcher::Start(const GURL& validated_url,
91 ui::PageTransition transition_type) { 92 ui::PageTransition transition_type) {
92 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 93 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
93 94
94 content::WebContents* web_contents = GetWebContents(); 95 content::WebContents* web_contents = GetWebContents();
95 DCHECK(web_contents); 96 DCHECK(web_contents);
96 97
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 // The redisplay request may be received before the Cancel prompt reply 178 // The redisplay request may be received before the Cancel prompt reply
178 // *after* if it is made before the beforeinstallprompt event handler 179 // *after* if it is made before the beforeinstallprompt event handler
179 // concludes (e.g. in the event handler itself), so allow the pipeline 180 // concludes (e.g. in the event handler itself), so allow the pipeline
180 // to continue in this case. 181 // to continue in this case.
181 // 182 //
182 // Stash the referrer for the case where the banner is redisplayed. 183 // Stash the referrer for the case where the banner is redisplayed.
183 if (reply == blink::WebAppBannerPromptReply::Cancel && 184 if (reply == blink::WebAppBannerPromptReply::Cancel &&
184 !page_requested_prompt_) { 185 !page_requested_prompt_) {
185 was_canceled_by_page_ = true; 186 was_canceled_by_page_ = true;
186 referrer_ = referrer; 187 referrer_ = referrer;
187 OutputDeveloperNotShownMessage(web_contents, kRendererRequestCancel); 188 OutputDeveloperNotShownMessage(web_contents, kRendererRequestCancel,
189 is_debug_mode_);
188 return; 190 return;
189 } 191 }
190 192
191 // Definitely going to show the banner now. 193 // Definitely going to show the banner now.
192 FOR_EACH_OBSERVER(Observer, observer_list_, 194 FOR_EACH_OBSERVER(Observer, observer_list_,
193 OnDecidedWhetherToShow(this, true)); 195 OnDecidedWhetherToShow(this, true));
194 196
195 ShowBanner(app_icon_.get(), app_title_, referrer); 197 ShowBanner(app_icon_.get(), app_title_, referrer);
196 is_active_ = false; 198 is_active_ = false;
197 } 199 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(), 242 rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(),
241 event_name, 243 event_name,
242 web_contents->GetURL()); 244 web_contents->GetURL());
243 } 245 }
244 246
245 void AppBannerDataFetcher::OnDidHasManifest(bool has_manifest) { 247 void AppBannerDataFetcher::OnDidHasManifest(bool has_manifest) {
246 content::WebContents* web_contents = GetWebContents(); 248 content::WebContents* web_contents = GetWebContents();
247 249
248 if (!CheckFetcherIsStillAlive(web_contents) || !has_manifest) { 250 if (!CheckFetcherIsStillAlive(web_contents) || !has_manifest) {
249 if (!has_manifest) 251 if (!has_manifest)
250 OutputDeveloperNotShownMessage(web_contents, kNoManifest); 252 OutputDeveloperNotShownMessage(web_contents, kNoManifest, is_debug_mode_);
251 253
252 Cancel(); 254 Cancel();
253 return; 255 return;
254 } 256 }
255 257
256 web_contents->GetManifest( 258 web_contents->GetManifest(
257 base::Bind(&AppBannerDataFetcher::OnDidGetManifest, this)); 259 base::Bind(&AppBannerDataFetcher::OnDidGetManifest, this));
258 } 260 }
259 261
260 void AppBannerDataFetcher::OnDidGetManifest( 262 void AppBannerDataFetcher::OnDidGetManifest(
261 const content::Manifest& manifest) { 263 const content::Manifest& manifest) {
262 content::WebContents* web_contents = GetWebContents(); 264 content::WebContents* web_contents = GetWebContents();
263 if (!CheckFetcherIsStillAlive(web_contents)) { 265 if (!CheckFetcherIsStillAlive(web_contents)) {
264 Cancel(); 266 Cancel();
265 return; 267 return;
266 } 268 }
267 if (manifest.IsEmpty()) { 269 if (manifest.IsEmpty()) {
268 OutputDeveloperNotShownMessage(web_contents, kManifestEmpty); 270 OutputDeveloperNotShownMessage(web_contents, kManifestEmpty,
271 is_debug_mode_);
269 Cancel(); 272 Cancel();
270 return; 273 return;
271 } 274 }
272 275
273 if (manifest.prefer_related_applications && 276 if (manifest.prefer_related_applications &&
274 manifest.related_applications.size()) { 277 manifest.related_applications.size()) {
275 for (const auto& application : manifest.related_applications) { 278 for (const auto& application : manifest.related_applications) {
276 std::string platform = base::UTF16ToUTF8(application.platform.string()); 279 std::string platform = base::UTF16ToUTF8(application.platform.string());
277 std::string id = base::UTF16ToUTF8(application.id.string()); 280 std::string id = base::UTF16ToUTF8(application.id.string());
278 if (weak_delegate_->HandleNonWebApp(platform, application.url, id)) 281 if (weak_delegate_->HandleNonWebApp(platform, application.url, id))
279 return; 282 return;
280 } 283 }
281 } 284 }
282 285
283 if (!IsManifestValidForWebApp(manifest, web_contents)) { 286 if (!IsManifestValidForWebApp(manifest, web_contents, is_debug_mode_)) {
284 Cancel(); 287 Cancel();
285 return; 288 return;
286 } 289 }
287 290
288 web_app_data_ = manifest; 291 web_app_data_ = manifest;
289 app_title_ = web_app_data_.name.string(); 292 app_title_ = web_app_data_.name.string();
290 293
291 if (IsWebAppInstalled(web_contents->GetBrowserContext(), 294 if (IsWebAppInstalled(web_contents->GetBrowserContext(),
292 manifest.start_url) && 295 manifest.start_url) &&
293 !base::CommandLine::ForCurrentProcess()->HasSwitch( 296 !base::CommandLine::ForCurrentProcess()->HasSwitch(
294 switches::kBypassAppBannerEngagementChecks)) { 297 switches::kBypassAppBannerEngagementChecks)) {
295 OutputDeveloperNotShownMessage(web_contents, kBannerAlreadyAdded); 298 OutputDeveloperNotShownMessage(web_contents, kBannerAlreadyAdded,
299 is_debug_mode_);
296 Cancel(); 300 Cancel();
297 return; 301 return;
298 } 302 }
299 303
300 banners::TrackDisplayEvent(DISPLAY_EVENT_WEB_APP_BANNER_REQUESTED); 304 banners::TrackDisplayEvent(DISPLAY_EVENT_WEB_APP_BANNER_REQUESTED);
301 305
302 // Check to see if there is a single service worker controlling this page 306 // Check to see if there is a single service worker controlling this page
303 // and the manifest's start url. 307 // and the manifest's start url.
304 Profile* profile = 308 Profile* profile =
305 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 309 Profile::FromBrowserContext(web_contents->GetBrowserContext());
(...skipping 11 matching lines...) Expand all
317 void AppBannerDataFetcher::OnDidCheckHasServiceWorker( 321 void AppBannerDataFetcher::OnDidCheckHasServiceWorker(
318 bool has_service_worker) { 322 bool has_service_worker) {
319 content::WebContents* web_contents = GetWebContents(); 323 content::WebContents* web_contents = GetWebContents();
320 if (!CheckFetcherIsStillAlive(web_contents)) { 324 if (!CheckFetcherIsStillAlive(web_contents)) {
321 Cancel(); 325 Cancel();
322 return; 326 return;
323 } 327 }
324 328
325 if (!has_service_worker) { 329 if (!has_service_worker) {
326 TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER); 330 TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER);
327 OutputDeveloperNotShownMessage(web_contents, kNoMatchingServiceWorker); 331 OutputDeveloperNotShownMessage(web_contents, kNoMatchingServiceWorker,
332 is_debug_mode_);
328 Cancel(); 333 Cancel();
329 return; 334 return;
330 } 335 }
331 336
332 OnHasServiceWorker(web_contents); 337 OnHasServiceWorker(web_contents);
333 } 338 }
334 339
335 void AppBannerDataFetcher::OnHasServiceWorker( 340 void AppBannerDataFetcher::OnHasServiceWorker(
336 content::WebContents* web_contents) { 341 content::WebContents* web_contents) {
337 GURL icon_url = 342 GURL icon_url =
338 ManifestIconSelector::FindBestMatchingIcon( 343 ManifestIconSelector::FindBestMatchingIcon(
339 web_app_data_.icons, 344 web_app_data_.icons,
340 ideal_icon_size_in_dp_, 345 ideal_icon_size_in_dp_,
341 minimum_icon_size_in_dp_, 346 minimum_icon_size_in_dp_,
342 gfx::Screen::GetScreenFor(web_contents->GetNativeView())); 347 gfx::Screen::GetScreenFor(web_contents->GetNativeView()));
343 348
344 if (!FetchAppIcon(web_contents, icon_url)) { 349 if (!FetchAppIcon(web_contents, icon_url)) {
345 OutputDeveloperNotShownMessage(web_contents, kCannotDetermineBestIcon); 350 OutputDeveloperNotShownMessage(web_contents, kCannotDetermineBestIcon,
351 is_debug_mode_);
346 Cancel(); 352 Cancel();
347 } 353 }
348 } 354 }
349 355
350 bool AppBannerDataFetcher::FetchAppIcon(content::WebContents* web_contents, 356 bool AppBannerDataFetcher::FetchAppIcon(content::WebContents* web_contents,
351 const GURL& icon_url) { 357 const GURL& icon_url) {
352 return ManifestIconDownloader::Download( 358 return ManifestIconDownloader::Download(
353 web_contents, 359 web_contents,
354 icon_url, 360 icon_url,
355 ideal_icon_size_in_dp_, 361 ideal_icon_size_in_dp_,
356 minimum_icon_size_in_dp_, 362 minimum_icon_size_in_dp_,
357 base::Bind(&AppBannerDataFetcher::OnAppIconFetched, 363 base::Bind(&AppBannerDataFetcher::OnAppIconFetched,
358 this)); 364 this));
359 } 365 }
360 366
361 void AppBannerDataFetcher::OnAppIconFetched(const SkBitmap& bitmap) { 367 void AppBannerDataFetcher::OnAppIconFetched(const SkBitmap& bitmap) {
362 if (!is_active_) return; 368 if (!is_active_) return;
363 369
364 content::WebContents* web_contents = GetWebContents(); 370 content::WebContents* web_contents = GetWebContents();
365 if (!CheckFetcherIsStillAlive(web_contents)) { 371 if (!CheckFetcherIsStillAlive(web_contents)) {
366 Cancel(); 372 Cancel();
367 return; 373 return;
368 } 374 }
369 if (bitmap.drawsNothing()) { 375 if (bitmap.drawsNothing()) {
370 OutputDeveloperNotShownMessage(web_contents, kNoIconAvailable); 376 OutputDeveloperNotShownMessage(web_contents, kNoIconAvailable,
377 is_debug_mode_);
371 Cancel(); 378 Cancel();
372 return; 379 return;
373 } 380 }
374 381
375 RecordCouldShowBanner(); 382 RecordCouldShowBanner();
376 if (!CheckIfShouldShowBanner()) { 383 if (!is_debug_mode_ && !CheckIfShouldShowBanner()) {
377 // At this point, the only possible case is that the banner has been added 384 // At this point, the only possible case is that the banner has been added
378 // to the homescreen, given all of the other checks that have been made. 385 // to the homescreen, given all of the other checks that have been made.
379 OutputDeveloperNotShownMessage(web_contents, kBannerAlreadyAdded); 386 OutputDeveloperNotShownMessage(web_contents, kBannerAlreadyAdded,
387 is_debug_mode_);
380 Cancel(); 388 Cancel();
381 return; 389 return;
382 } 390 }
383 391
384 app_icon_.reset(new SkBitmap(bitmap)); 392 app_icon_.reset(new SkBitmap(bitmap));
385 event_request_id_ = ++gCurrentRequestID; 393 event_request_id_ = ++gCurrentRequestID;
386 web_contents->GetMainFrame()->Send( 394 web_contents->GetMainFrame()->Send(
387 new ChromeViewMsg_AppBannerPromptRequest( 395 new ChromeViewMsg_AppBannerPromptRequest(
388 web_contents->GetMainFrame()->GetRoutingID(), 396 web_contents->GetMainFrame()->GetRoutingID(),
389 event_request_id_, 397 event_request_id_,
(...skipping 19 matching lines...) Expand all
409 content::WebContents* web_contents = GetWebContents(); 417 content::WebContents* web_contents = GetWebContents();
410 DCHECK(web_contents); 418 DCHECK(web_contents);
411 419
412 return AppBannerSettingsHelper::ShouldShowBanner( 420 return AppBannerSettingsHelper::ShouldShowBanner(
413 web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime()); 421 web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime());
414 } 422 }
415 423
416 bool AppBannerDataFetcher::CheckFetcherIsStillAlive( 424 bool AppBannerDataFetcher::CheckFetcherIsStillAlive(
417 content::WebContents* web_contents) { 425 content::WebContents* web_contents) {
418 if (!is_active_) { 426 if (!is_active_) {
419 OutputDeveloperNotShownMessage(web_contents, 427 OutputDeveloperNotShownMessage(
420 kUserNavigatedBeforeBannerShown); 428 web_contents, kUserNavigatedBeforeBannerShown, is_debug_mode_);
421 return false; 429 return false;
422 } 430 }
423 if (!web_contents) { 431 if (!web_contents) {
424 return false; // We cannot show a message if |web_contents| is null 432 return false; // We cannot show a message if |web_contents| is null
425 } 433 }
426 return true; 434 return true;
427 } 435 }
428 436
429 // static 437 // static
430 bool AppBannerDataFetcher::IsManifestValidForWebApp( 438 bool AppBannerDataFetcher::IsManifestValidForWebApp(
431 const content::Manifest& manifest, 439 const content::Manifest& manifest,
432 content::WebContents* web_contents) { 440 content::WebContents* web_contents,
441 bool is_debug_mode) {
433 if (manifest.IsEmpty()) { 442 if (manifest.IsEmpty()) {
434 OutputDeveloperNotShownMessage(web_contents, kManifestEmpty); 443 OutputDeveloperNotShownMessage(web_contents, kManifestEmpty, is_debug_mode);
435 return false; 444 return false;
436 } 445 }
437 if (!manifest.start_url.is_valid()) { 446 if (!manifest.start_url.is_valid()) {
438 OutputDeveloperNotShownMessage(web_contents, kStartURLNotValid); 447 OutputDeveloperNotShownMessage(web_contents, kStartURLNotValid,
448 is_debug_mode);
439 return false; 449 return false;
440 } 450 }
441 if (manifest.name.is_null() && manifest.short_name.is_null()) { 451 if (manifest.name.is_null() && manifest.short_name.is_null()) {
442 OutputDeveloperNotShownMessage(web_contents, 452 OutputDeveloperNotShownMessage(
443 kManifestMissingNameOrShortName); 453 web_contents, kManifestMissingNameOrShortName, is_debug_mode);
444 return false; 454 return false;
445 } 455 }
446 if (!DoesManifestContainRequiredIcon(manifest)) { 456 if (!DoesManifestContainRequiredIcon(manifest)) {
447 OutputDeveloperNotShownMessage(web_contents, kManifestMissingSuitableIcon); 457 OutputDeveloperNotShownMessage(web_contents, kManifestMissingSuitableIcon,
458 is_debug_mode);
448 return false; 459 return false;
449 } 460 }
450 return true; 461 return true;
451 } 462 }
452 463
453 } // namespace banners 464 } // namespace banners
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698