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

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: incorporated dominickn's comment 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 is_debug_mode_(is_debug_mode),
dominickn 2016/01/18 23:20:41 Change this to: is_debug_mode_(is_debug_mode || b
horo 2016/01/19 01:45:43 Done.
86 event_request_id_(-1) { 87 event_request_id_(-1) {
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);
(...skipping 81 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 AppBannerSettingsHelper::RecordMinutesFromFirstVisitToShow( 193 AppBannerSettingsHelper::RecordMinutesFromFirstVisitToShow(
192 web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime()); 194 web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime());
193 195
194 // Definitely going to show the banner now. 196 // Definitely going to show the banner now.
195 FOR_EACH_OBSERVER(Observer, observer_list_, 197 FOR_EACH_OBSERVER(Observer, observer_list_,
196 OnDecidedWhetherToShow(this, true)); 198 OnDecidedWhetherToShow(this, true));
197 199
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(), 245 rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(),
244 event_name, 246 event_name,
245 web_contents->GetURL()); 247 web_contents->GetURL());
246 } 248 }
247 249
248 void AppBannerDataFetcher::OnDidHasManifest(bool has_manifest) { 250 void AppBannerDataFetcher::OnDidHasManifest(bool has_manifest) {
249 content::WebContents* web_contents = GetWebContents(); 251 content::WebContents* web_contents = GetWebContents();
250 252
251 if (!CheckFetcherIsStillAlive(web_contents) || !has_manifest) { 253 if (!CheckFetcherIsStillAlive(web_contents) || !has_manifest) {
252 if (!has_manifest) 254 if (!has_manifest)
253 OutputDeveloperNotShownMessage(web_contents, kNoManifest); 255 OutputDeveloperNotShownMessage(web_contents, kNoManifest, is_debug_mode_);
254 256
255 Cancel(); 257 Cancel();
256 return; 258 return;
257 } 259 }
258 260
259 web_contents->GetManifest( 261 web_contents->GetManifest(
260 base::Bind(&AppBannerDataFetcher::OnDidGetManifest, this)); 262 base::Bind(&AppBannerDataFetcher::OnDidGetManifest, this));
261 } 263 }
262 264
263 void AppBannerDataFetcher::OnDidGetManifest( 265 void AppBannerDataFetcher::OnDidGetManifest(
264 const content::Manifest& manifest) { 266 const content::Manifest& manifest) {
265 content::WebContents* web_contents = GetWebContents(); 267 content::WebContents* web_contents = GetWebContents();
266 if (!CheckFetcherIsStillAlive(web_contents)) { 268 if (!CheckFetcherIsStillAlive(web_contents)) {
267 Cancel(); 269 Cancel();
268 return; 270 return;
269 } 271 }
270 if (manifest.IsEmpty()) { 272 if (manifest.IsEmpty()) {
271 OutputDeveloperNotShownMessage(web_contents, kManifestEmpty); 273 OutputDeveloperNotShownMessage(web_contents, kManifestEmpty,
274 is_debug_mode_);
272 Cancel(); 275 Cancel();
273 return; 276 return;
274 } 277 }
275 278
276 if (manifest.prefer_related_applications && 279 if (manifest.prefer_related_applications &&
277 manifest.related_applications.size()) { 280 manifest.related_applications.size()) {
278 for (const auto& application : manifest.related_applications) { 281 for (const auto& application : manifest.related_applications) {
279 std::string platform = base::UTF16ToUTF8(application.platform.string()); 282 std::string platform = base::UTF16ToUTF8(application.platform.string());
280 std::string id = base::UTF16ToUTF8(application.id.string()); 283 std::string id = base::UTF16ToUTF8(application.id.string());
281 if (weak_delegate_->HandleNonWebApp(platform, application.url, id)) 284 if (weak_delegate_->HandleNonWebApp(platform, application.url, id,
285 is_debug_mode_))
282 return; 286 return;
283 } 287 }
284 } 288 }
285 289
286 if (!IsManifestValidForWebApp(manifest, web_contents)) { 290 if (!IsManifestValidForWebApp(manifest, web_contents, is_debug_mode_)) {
287 Cancel(); 291 Cancel();
288 return; 292 return;
289 } 293 }
290 294
291 web_app_data_ = manifest; 295 web_app_data_ = manifest;
292 app_title_ = web_app_data_.name.string(); 296 app_title_ = web_app_data_.name.string();
293 297
294 if (IsWebAppInstalled(web_contents->GetBrowserContext(), 298 if (IsWebAppInstalled(web_contents->GetBrowserContext(),
295 manifest.start_url) && 299 manifest.start_url) &&
296 !base::CommandLine::ForCurrentProcess()->HasSwitch( 300 !base::CommandLine::ForCurrentProcess()->HasSwitch(
dominickn 2016/01/18 23:20:41 Replace: !base::CommandLine::ForCurrentProcess()-
horo 2016/01/19 01:45:43 Done.
297 switches::kBypassAppBannerEngagementChecks)) { 301 switches::kBypassAppBannerEngagementChecks)) {
298 OutputDeveloperNotShownMessage(web_contents, kBannerAlreadyAdded); 302 OutputDeveloperNotShownMessage(web_contents, kBannerAlreadyAdded,
303 is_debug_mode_);
299 Cancel(); 304 Cancel();
300 return; 305 return;
301 } 306 }
302 307
303 banners::TrackDisplayEvent(DISPLAY_EVENT_WEB_APP_BANNER_REQUESTED); 308 banners::TrackDisplayEvent(DISPLAY_EVENT_WEB_APP_BANNER_REQUESTED);
304 309
305 // Check to see if there is a single service worker controlling this page 310 // Check to see if there is a single service worker controlling this page
306 // and the manifest's start url. 311 // and the manifest's start url.
307 Profile* profile = 312 Profile* profile =
308 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 313 Profile::FromBrowserContext(web_contents->GetBrowserContext());
(...skipping 11 matching lines...) Expand all
320 void AppBannerDataFetcher::OnDidCheckHasServiceWorker( 325 void AppBannerDataFetcher::OnDidCheckHasServiceWorker(
321 bool has_service_worker) { 326 bool has_service_worker) {
322 content::WebContents* web_contents = GetWebContents(); 327 content::WebContents* web_contents = GetWebContents();
323 if (!CheckFetcherIsStillAlive(web_contents)) { 328 if (!CheckFetcherIsStillAlive(web_contents)) {
324 Cancel(); 329 Cancel();
325 return; 330 return;
326 } 331 }
327 332
328 if (!has_service_worker) { 333 if (!has_service_worker) {
329 TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER); 334 TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER);
330 OutputDeveloperNotShownMessage(web_contents, kNoMatchingServiceWorker); 335 OutputDeveloperNotShownMessage(web_contents, kNoMatchingServiceWorker,
336 is_debug_mode_);
331 Cancel(); 337 Cancel();
332 return; 338 return;
333 } 339 }
334 340
335 OnHasServiceWorker(web_contents); 341 OnHasServiceWorker(web_contents);
336 } 342 }
337 343
338 void AppBannerDataFetcher::OnHasServiceWorker( 344 void AppBannerDataFetcher::OnHasServiceWorker(
339 content::WebContents* web_contents) { 345 content::WebContents* web_contents) {
340 GURL icon_url = 346 GURL icon_url =
341 ManifestIconSelector::FindBestMatchingIcon( 347 ManifestIconSelector::FindBestMatchingIcon(
342 web_app_data_.icons, 348 web_app_data_.icons,
343 ideal_icon_size_in_dp_, 349 ideal_icon_size_in_dp_,
344 minimum_icon_size_in_dp_, 350 minimum_icon_size_in_dp_,
345 gfx::Screen::GetScreenFor(web_contents->GetNativeView())); 351 gfx::Screen::GetScreenFor(web_contents->GetNativeView()));
346 352
347 if (!FetchAppIcon(web_contents, icon_url)) { 353 if (!FetchAppIcon(web_contents, icon_url)) {
348 OutputDeveloperNotShownMessage(web_contents, kCannotDetermineBestIcon); 354 OutputDeveloperNotShownMessage(web_contents, kCannotDetermineBestIcon,
355 is_debug_mode_);
349 Cancel(); 356 Cancel();
350 } 357 }
351 } 358 }
352 359
353 bool AppBannerDataFetcher::FetchAppIcon(content::WebContents* web_contents, 360 bool AppBannerDataFetcher::FetchAppIcon(content::WebContents* web_contents,
354 const GURL& icon_url) { 361 const GURL& icon_url) {
355 return ManifestIconDownloader::Download( 362 return ManifestIconDownloader::Download(
356 web_contents, 363 web_contents,
357 icon_url, 364 icon_url,
358 ideal_icon_size_in_dp_, 365 ideal_icon_size_in_dp_,
359 minimum_icon_size_in_dp_, 366 minimum_icon_size_in_dp_,
360 base::Bind(&AppBannerDataFetcher::OnAppIconFetched, 367 base::Bind(&AppBannerDataFetcher::OnAppIconFetched,
361 this)); 368 this));
362 } 369 }
363 370
364 void AppBannerDataFetcher::OnAppIconFetched(const SkBitmap& bitmap) { 371 void AppBannerDataFetcher::OnAppIconFetched(const SkBitmap& bitmap) {
365 if (!is_active_) return; 372 if (!is_active_) return;
366 373
367 content::WebContents* web_contents = GetWebContents(); 374 content::WebContents* web_contents = GetWebContents();
368 if (!CheckFetcherIsStillAlive(web_contents)) { 375 if (!CheckFetcherIsStillAlive(web_contents)) {
369 Cancel(); 376 Cancel();
370 return; 377 return;
371 } 378 }
372 if (bitmap.drawsNothing()) { 379 if (bitmap.drawsNothing()) {
373 OutputDeveloperNotShownMessage(web_contents, kNoIconAvailable); 380 OutputDeveloperNotShownMessage(web_contents, kNoIconAvailable,
381 is_debug_mode_);
374 Cancel(); 382 Cancel();
375 return; 383 return;
376 } 384 }
377 385
378 RecordCouldShowBanner(); 386 RecordCouldShowBanner();
379 if (!CheckIfShouldShowBanner()) { 387 if (!is_debug_mode_ && !CheckIfShouldShowBanner()) {
380 // At this point, the only possible case is that the banner has been added 388 // At this point, the only possible case is that the banner has been added
381 // to the homescreen, given all of the other checks that have been made. 389 // to the homescreen, given all of the other checks that have been made.
382 OutputDeveloperNotShownMessage(web_contents, kBannerAlreadyAdded); 390 OutputDeveloperNotShownMessage(web_contents, kBannerAlreadyAdded,
391 is_debug_mode_);
383 Cancel(); 392 Cancel();
384 return; 393 return;
385 } 394 }
386 395
387 app_icon_.reset(new SkBitmap(bitmap)); 396 app_icon_.reset(new SkBitmap(bitmap));
388 event_request_id_ = ++gCurrentRequestID; 397 event_request_id_ = ++gCurrentRequestID;
389 web_contents->GetMainFrame()->Send( 398 web_contents->GetMainFrame()->Send(
390 new ChromeViewMsg_AppBannerPromptRequest( 399 new ChromeViewMsg_AppBannerPromptRequest(
391 web_contents->GetMainFrame()->GetRoutingID(), 400 web_contents->GetMainFrame()->GetRoutingID(),
392 event_request_id_, 401 event_request_id_,
(...skipping 19 matching lines...) Expand all
412 content::WebContents* web_contents = GetWebContents(); 421 content::WebContents* web_contents = GetWebContents();
413 DCHECK(web_contents); 422 DCHECK(web_contents);
414 423
415 return AppBannerSettingsHelper::ShouldShowBanner( 424 return AppBannerSettingsHelper::ShouldShowBanner(
416 web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime()); 425 web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime());
417 } 426 }
418 427
419 bool AppBannerDataFetcher::CheckFetcherIsStillAlive( 428 bool AppBannerDataFetcher::CheckFetcherIsStillAlive(
420 content::WebContents* web_contents) { 429 content::WebContents* web_contents) {
421 if (!is_active_) { 430 if (!is_active_) {
422 OutputDeveloperNotShownMessage(web_contents, 431 OutputDeveloperNotShownMessage(
423 kUserNavigatedBeforeBannerShown); 432 web_contents, kUserNavigatedBeforeBannerShown, is_debug_mode_);
424 return false; 433 return false;
425 } 434 }
426 if (!web_contents) { 435 if (!web_contents) {
427 return false; // We cannot show a message if |web_contents| is null 436 return false; // We cannot show a message if |web_contents| is null
428 } 437 }
429 return true; 438 return true;
430 } 439 }
431 440
432 // static 441 // static
433 bool AppBannerDataFetcher::IsManifestValidForWebApp( 442 bool AppBannerDataFetcher::IsManifestValidForWebApp(
434 const content::Manifest& manifest, 443 const content::Manifest& manifest,
435 content::WebContents* web_contents) { 444 content::WebContents* web_contents,
445 bool is_debug_mode) {
436 if (manifest.IsEmpty()) { 446 if (manifest.IsEmpty()) {
437 OutputDeveloperNotShownMessage(web_contents, kManifestEmpty); 447 OutputDeveloperNotShownMessage(web_contents, kManifestEmpty, is_debug_mode);
438 return false; 448 return false;
439 } 449 }
440 if (!manifest.start_url.is_valid()) { 450 if (!manifest.start_url.is_valid()) {
441 OutputDeveloperNotShownMessage(web_contents, kStartURLNotValid); 451 OutputDeveloperNotShownMessage(web_contents, kStartURLNotValid,
452 is_debug_mode);
442 return false; 453 return false;
443 } 454 }
444 if (manifest.name.is_null() && manifest.short_name.is_null()) { 455 if (manifest.name.is_null() && manifest.short_name.is_null()) {
445 OutputDeveloperNotShownMessage(web_contents, 456 OutputDeveloperNotShownMessage(
446 kManifestMissingNameOrShortName); 457 web_contents, kManifestMissingNameOrShortName, is_debug_mode);
447 return false; 458 return false;
448 } 459 }
449 if (!DoesManifestContainRequiredIcon(manifest)) { 460 if (!DoesManifestContainRequiredIcon(manifest)) {
450 OutputDeveloperNotShownMessage(web_contents, kManifestMissingSuitableIcon); 461 OutputDeveloperNotShownMessage(web_contents, kManifestMissingSuitableIcon,
462 is_debug_mode);
451 return false; 463 return false;
452 } 464 }
453 return true; 465 return true;
454 } 466 }
455 467
456 } // namespace banners 468 } // namespace banners
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698