| Index: chrome/browser/banners/app_banner_data_fetcher.cc | 
| diff --git a/chrome/browser/banners/app_banner_data_fetcher.cc b/chrome/browser/banners/app_banner_data_fetcher.cc | 
| deleted file mode 100644 | 
| index 3cc28110a712364b55f59d0882d320ef6c75e952..0000000000000000000000000000000000000000 | 
| --- a/chrome/browser/banners/app_banner_data_fetcher.cc | 
| +++ /dev/null | 
| @@ -1,496 +0,0 @@ | 
| -// Copyright 2015 The Chromium Authors. All rights reserved. | 
| -// Use of this source code is governed by a BSD-style license that can be | 
| -// found in the LICENSE file. | 
| - | 
| -#include "chrome/browser/banners/app_banner_data_fetcher.h" | 
| - | 
| -#include "base/bind.h" | 
| -#include "base/command_line.h" | 
| -#include "base/lazy_instance.h" | 
| -#include "base/strings/string_number_conversions.h" | 
| -#include "base/strings/string_util.h" | 
| -#include "base/strings/utf_string_conversions.h" | 
| -#include "chrome/browser/banners/app_banner_debug_log.h" | 
| -#include "chrome/browser/banners/app_banner_metrics.h" | 
| -#include "chrome/browser/banners/app_banner_settings_helper.h" | 
| -#include "chrome/browser/browser_process.h" | 
| -#include "chrome/browser/manifest/manifest_icon_downloader.h" | 
| -#include "chrome/browser/manifest/manifest_icon_selector.h" | 
| -#include "chrome/browser/profiles/profile.h" | 
| -#include "chrome/common/chrome_switches.h" | 
| -#include "chrome/common/render_messages.h" | 
| -#include "components/rappor/rappor_utils.h" | 
| -#include "content/public/browser/browser_context.h" | 
| -#include "content/public/browser/browser_thread.h" | 
| -#include "content/public/browser/navigation_details.h" | 
| -#include "content/public/browser/render_frame_host.h" | 
| -#include "content/public/browser/service_worker_context.h" | 
| -#include "content/public/browser/storage_partition.h" | 
| -#include "net/base/load_flags.h" | 
| -#include "third_party/WebKit/public/platform/WebDisplayMode.h" | 
| -#include "third_party/WebKit/public/platform/modules/app_banner/WebAppBannerPromptReply.h" | 
| - | 
| -namespace { | 
| - | 
| -base::LazyInstance<base::TimeDelta> gTimeDeltaForTesting = | 
| -    LAZY_INSTANCE_INITIALIZER; | 
| -int gCurrentRequestID = -1; | 
| -const char kPngExtension[] = ".png"; | 
| - | 
| -// The requirement for now is an image/png that is at least 144x144. | 
| -const int kIconMinimumSize = 144; | 
| -bool DoesManifestContainRequiredIcon(const content::Manifest& manifest) { | 
| -  for (const auto& icon : manifest.icons) { | 
| -    // The type field is optional. If it isn't present, fall back on checking | 
| -    // the src extension, and allow the icon if the extension ends with png. | 
| -    if (!base::EqualsASCII(icon.type.string(), "image/png") && | 
| -        !(icon.type.is_null() && | 
| -          base::EndsWith(icon.src.ExtractFileName(), kPngExtension, | 
| -                         base::CompareCase::INSENSITIVE_ASCII))) | 
| -      continue; | 
| - | 
| -    for (const auto& size : icon.sizes) { | 
| -      if (size.IsEmpty()) // "any" | 
| -        return true; | 
| -      if (size.width() >= kIconMinimumSize && size.height() >= kIconMinimumSize) | 
| -        return true; | 
| -    } | 
| -  } | 
| - | 
| -  return false; | 
| -} | 
| - | 
| -}  // anonymous namespace | 
| - | 
| -namespace banners { | 
| - | 
| -// static | 
| -base::Time AppBannerDataFetcher::GetCurrentTime() { | 
| -  return base::Time::Now() + gTimeDeltaForTesting.Get(); | 
| -} | 
| - | 
| -// static | 
| -void AppBannerDataFetcher::SetTimeDeltaForTesting(int days) { | 
| -  gTimeDeltaForTesting.Get() = base::TimeDelta::FromDays(days); | 
| -} | 
| - | 
| -AppBannerDataFetcher::AppBannerDataFetcher(content::WebContents* web_contents, | 
| -                                           base::WeakPtr<Delegate> delegate, | 
| -                                           int ideal_icon_size_in_dp, | 
| -                                           int minimum_icon_size_in_dp, | 
| -                                           bool is_debug_mode) | 
| -    : WebContentsObserver(web_contents), | 
| -      weak_delegate_(delegate), | 
| -      ideal_icon_size_in_dp_(ideal_icon_size_in_dp), | 
| -      minimum_icon_size_in_dp_(minimum_icon_size_in_dp), | 
| -      is_active_(false), | 
| -      was_canceled_by_page_(false), | 
| -      page_requested_prompt_(false), | 
| -      is_debug_mode_(is_debug_mode || | 
| -                     base::CommandLine::ForCurrentProcess()->HasSwitch( | 
| -                         switches::kBypassAppBannerEngagementChecks)), | 
| -      event_request_id_(-1) { | 
| -  DCHECK(minimum_icon_size_in_dp <= ideal_icon_size_in_dp); | 
| -} | 
| - | 
| -void AppBannerDataFetcher::Start(const GURL& validated_url, | 
| -                                 ui::PageTransition transition_type) { | 
| -  DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 
| - | 
| -  content::WebContents* web_contents = GetWebContents(); | 
| -  DCHECK(web_contents); | 
| - | 
| -  is_active_ = true; | 
| -  was_canceled_by_page_ = false; | 
| -  page_requested_prompt_ = false; | 
| -  transition_type_ = transition_type; | 
| -  validated_url_ = validated_url; | 
| -  referrer_.erase(); | 
| -  web_contents->GetManifest( | 
| -      base::Bind(&AppBannerDataFetcher::OnDidGetManifest, this)); | 
| -} | 
| - | 
| -void AppBannerDataFetcher::Cancel() { | 
| -  DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 
| -  if (is_active_) { | 
| -    FOR_EACH_OBSERVER(Observer, observer_list_, | 
| -                      OnDecidedWhetherToShow(this, false)); | 
| -    if (was_canceled_by_page_ && !page_requested_prompt_) { | 
| -      TrackBeforeInstallEvent( | 
| -          BEFORE_INSTALL_EVENT_PROMPT_NOT_CALLED_AFTER_PREVENT_DEFAULT); | 
| -    } | 
| - | 
| -    is_active_ = false; | 
| -    was_canceled_by_page_ = false; | 
| -    page_requested_prompt_ = false; | 
| -    referrer_.erase(); | 
| -  } | 
| -} | 
| - | 
| -void AppBannerDataFetcher::ReplaceWebContents( | 
| -    content::WebContents* web_contents) { | 
| -  Observe(web_contents); | 
| -} | 
| - | 
| -void AppBannerDataFetcher::AddObserverForTesting(Observer* observer) { | 
| -  observer_list_.AddObserver(observer); | 
| -} | 
| - | 
| -void AppBannerDataFetcher::RemoveObserverForTesting(Observer* observer) { | 
| -  observer_list_.RemoveObserver(observer); | 
| -} | 
| - | 
| -void AppBannerDataFetcher::WebContentsDestroyed() { | 
| -  Cancel(); | 
| -  Observe(nullptr); | 
| -} | 
| - | 
| -void AppBannerDataFetcher::DidNavigateMainFrame( | 
| -    const content::LoadCommittedDetails& details, | 
| -    const content::FrameNavigateParams& params) { | 
| -  if (!details.is_in_page) | 
| -    Cancel(); | 
| -} | 
| - | 
| -bool AppBannerDataFetcher::OnMessageReceived( | 
| -    const IPC::Message& message, content::RenderFrameHost* render_frame_host) { | 
| -  bool handled = true; | 
| - | 
| -  IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(AppBannerDataFetcher, message, | 
| -                                   render_frame_host) | 
| -    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_AppBannerPromptReply, | 
| -                        OnBannerPromptReply) | 
| -    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_RequestShowAppBanner, | 
| -                        OnRequestShowAppBanner) | 
| -    IPC_MESSAGE_UNHANDLED(handled = false) | 
| -  IPC_END_MESSAGE_MAP() | 
| - | 
| -  return handled; | 
| -} | 
| - | 
| -void AppBannerDataFetcher::OnBannerPromptReply( | 
| -    content::RenderFrameHost* render_frame_host, | 
| -    int request_id, | 
| -    blink::WebAppBannerPromptReply reply, | 
| -    std::string referrer) { | 
| -  content::WebContents* web_contents = GetWebContents(); | 
| -  if (!CheckFetcherIsStillAlive(web_contents) || | 
| -      request_id != event_request_id_) { | 
| -    Cancel(); | 
| -    return; | 
| -  } | 
| - | 
| -  // The renderer might have requested the prompt to be canceled. | 
| -  // They may request that it is redisplayed later, so don't Cancel() here. | 
| -  // However, log that the cancelation was requested, so Cancel() can be | 
| -  // called if a redisplay isn't asked for. | 
| -  // | 
| -  // The redisplay request may be received before the Cancel prompt reply | 
| -  // *after* if it is made before the beforeinstallprompt event handler | 
| -  // concludes (e.g. in the event handler itself), so allow the pipeline | 
| -  // to continue in this case. | 
| -  // | 
| -  // Stash the referrer for the case where the banner is redisplayed. | 
| -  if (reply == blink::WebAppBannerPromptReply::Cancel && | 
| -      !page_requested_prompt_) { | 
| -    TrackBeforeInstallEvent(BEFORE_INSTALL_EVENT_PREVENT_DEFAULT_CALLED); | 
| -    was_canceled_by_page_ = true; | 
| -    referrer_ = referrer; | 
| -    OutputDeveloperNotShownMessage(web_contents, kRendererRequestCancel, | 
| -                                   is_debug_mode_); | 
| -    return; | 
| -  } | 
| - | 
| -  // If we haven't yet returned, but either of |was_canceled_by_page_| or | 
| -  // |page_requested_prompt_| is true, the page has requested a delayed showing | 
| -  // of the prompt. Otherwise, the prompt was never canceled by the page. | 
| -  if (was_canceled_by_page_ || page_requested_prompt_) { | 
| -    TrackBeforeInstallEvent( | 
| -        BEFORE_INSTALL_EVENT_PROMPT_CALLED_AFTER_PREVENT_DEFAULT); | 
| -    was_canceled_by_page_ = false; | 
| -  } else { | 
| -    TrackBeforeInstallEvent(BEFORE_INSTALL_EVENT_NO_ACTION); | 
| -  } | 
| - | 
| -  AppBannerSettingsHelper::RecordMinutesFromFirstVisitToShow( | 
| -      web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime()); | 
| - | 
| -  // Definitely going to show the banner now. | 
| -  FOR_EACH_OBSERVER(Observer, observer_list_, | 
| -                    OnDecidedWhetherToShow(this, true)); | 
| - | 
| -  TrackBeforeInstallEvent(BEFORE_INSTALL_EVENT_COMPLETE); | 
| -  ShowBanner(app_icon_url_, app_icon_.get(), app_title_, referrer); | 
| -  is_active_ = false; | 
| -} | 
| - | 
| -void AppBannerDataFetcher::OnRequestShowAppBanner( | 
| -    content::RenderFrameHost* render_frame_host, | 
| -    int request_id) { | 
| -  if (was_canceled_by_page_) { | 
| -    // Simulate an "OK" from the website to restart the banner display pipeline. | 
| -    // Don't reset |was_canceled_by_page_| yet for metrics purposes. | 
| -    OnBannerPromptReply(render_frame_host, request_id, | 
| -                        blink::WebAppBannerPromptReply::None, referrer_); | 
| -  } else { | 
| -    // Log that the prompt request was made for when we get the prompt reply. | 
| -    page_requested_prompt_ = true; | 
| -  } | 
| -} | 
| - | 
| -AppBannerDataFetcher::~AppBannerDataFetcher() { | 
| -  FOR_EACH_OBSERVER(Observer, observer_list_, OnFetcherDestroyed(this)); | 
| -} | 
| - | 
| -std::string AppBannerDataFetcher::GetBannerType() { | 
| -  return "web"; | 
| -} | 
| - | 
| -content::WebContents* AppBannerDataFetcher::GetWebContents() { | 
| -  if (!web_contents() || web_contents()->IsBeingDestroyed()) | 
| -    return nullptr; | 
| -  return web_contents(); | 
| -} | 
| - | 
| -std::string AppBannerDataFetcher::GetAppIdentifier() { | 
| -  DCHECK(!manifest_.IsEmpty()); | 
| -  return manifest_.start_url.spec(); | 
| -} | 
| - | 
| -void AppBannerDataFetcher::RecordDidShowBanner(const std::string& event_name) { | 
| -  content::WebContents* web_contents = GetWebContents(); | 
| -  DCHECK(web_contents); | 
| - | 
| -  AppBannerSettingsHelper::RecordBannerEvent( | 
| -      web_contents, validated_url_, GetAppIdentifier(), | 
| -      AppBannerSettingsHelper::APP_BANNER_EVENT_DID_SHOW, | 
| -      GetCurrentTime()); | 
| -  rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(), | 
| -                                          event_name, | 
| -                                          web_contents->GetURL()); | 
| -} | 
| - | 
| -void AppBannerDataFetcher::OnDidGetManifest( | 
| -    const GURL& manifest_url, | 
| -    const content::Manifest& manifest) { | 
| -  content::WebContents* web_contents = GetWebContents(); | 
| -  if (!CheckFetcherIsStillAlive(web_contents)) { | 
| -    Cancel(); | 
| -    return; | 
| -  } | 
| -  if (manifest_url.is_empty()) { | 
| -    OutputDeveloperNotShownMessage(web_contents, kNoManifest, is_debug_mode_); | 
| -    Cancel(); | 
| -    return; | 
| -  } | 
| -  if (manifest.IsEmpty()) { | 
| -    OutputDeveloperNotShownMessage(web_contents, kManifestEmpty, | 
| -                                   is_debug_mode_); | 
| -    Cancel(); | 
| -    return; | 
| -  } | 
| - | 
| -  if (manifest.prefer_related_applications && | 
| -      manifest.related_applications.size()) { | 
| -    for (const auto& application : manifest.related_applications) { | 
| -      std::string platform = base::UTF16ToUTF8(application.platform.string()); | 
| -      std::string id = base::UTF16ToUTF8(application.id.string()); | 
| -      if (weak_delegate_->HandleNonWebApp(platform, application.url, id, | 
| -                                          is_debug_mode_)) | 
| -        return; | 
| -    } | 
| -  } | 
| - | 
| -  if (!IsManifestValidForWebApp(manifest, web_contents, is_debug_mode_)) { | 
| -    Cancel(); | 
| -    return; | 
| -  } | 
| - | 
| -  // Since the manifest is valid, one of short name or name must be non-null. | 
| -  // Prefer name if it isn't null. | 
| -  manifest_url_ = manifest_url; | 
| -  manifest_ = manifest; | 
| -  app_title_ = (manifest_.name.is_null()) ? manifest_.short_name.string() | 
| -                                          : manifest_.name.string(); | 
| - | 
| -  if (IsWebAppInstalled(web_contents->GetBrowserContext(), | 
| -                        manifest.start_url) && | 
| -      !is_debug_mode_) { | 
| -    Cancel(); | 
| -    return; | 
| -  } | 
| - | 
| -  banners::TrackDisplayEvent(DISPLAY_EVENT_WEB_APP_BANNER_REQUESTED); | 
| - | 
| -  // Check to see if there is a single service worker controlling this page | 
| -  // and the manifest's start url. | 
| -  Profile* profile = | 
| -      Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 
| -  content::StoragePartition* storage_partition = | 
| -      content::BrowserContext::GetStoragePartition( | 
| -          profile, web_contents->GetSiteInstance()); | 
| -  DCHECK(storage_partition); | 
| - | 
| -  storage_partition->GetServiceWorkerContext()->CheckHasServiceWorker( | 
| -      validated_url_, manifest.start_url, | 
| -      base::Bind(&AppBannerDataFetcher::OnDidCheckHasServiceWorker, | 
| -                 this)); | 
| -} | 
| - | 
| -void AppBannerDataFetcher::OnDidCheckHasServiceWorker( | 
| -    bool has_service_worker) { | 
| -  content::WebContents* web_contents = GetWebContents(); | 
| -  if (!CheckFetcherIsStillAlive(web_contents)) { | 
| -    Cancel(); | 
| -    return; | 
| -  } | 
| - | 
| -  if (!has_service_worker) { | 
| -    TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER); | 
| -    OutputDeveloperNotShownMessage(web_contents, kNoMatchingServiceWorker, | 
| -                                   is_debug_mode_); | 
| -    Cancel(); | 
| -    return; | 
| -  } | 
| - | 
| -  OnHasServiceWorker(web_contents); | 
| -} | 
| - | 
| -void AppBannerDataFetcher::OnHasServiceWorker( | 
| -    content::WebContents* web_contents) { | 
| -  GURL icon_url = ManifestIconSelector::FindBestMatchingIcon( | 
| -      manifest_.icons, ideal_icon_size_in_dp_, minimum_icon_size_in_dp_); | 
| - | 
| -  if (icon_url.is_empty()) { | 
| -    OutputDeveloperNotShownMessage( | 
| -        web_contents, | 
| -        kNoIconMatchingRequirements, | 
| -        base::IntToString(ManifestIconSelector::ConvertIconSizeFromDpToPx( | 
| -            minimum_icon_size_in_dp_)), | 
| -        is_debug_mode_); | 
| -    Cancel(); | 
| -  } else if (!FetchAppIcon(web_contents, icon_url)) { | 
| -    OutputDeveloperNotShownMessage(web_contents, kCannotDownloadIcon, | 
| -                                   is_debug_mode_); | 
| -    Cancel(); | 
| -  } | 
| -} | 
| - | 
| -bool AppBannerDataFetcher::FetchAppIcon(content::WebContents* web_contents, | 
| -                                        const GURL& icon_url) { | 
| -  app_icon_url_ = icon_url; | 
| -  return ManifestIconDownloader::Download( | 
| -      web_contents, icon_url, ideal_icon_size_in_dp_, minimum_icon_size_in_dp_, | 
| -      base::Bind(&AppBannerDataFetcher::OnAppIconFetched, this)); | 
| -} | 
| - | 
| -void AppBannerDataFetcher::OnAppIconFetched(const SkBitmap& bitmap) { | 
| -  if (!is_active_) return; | 
| - | 
| -  content::WebContents* web_contents = GetWebContents(); | 
| -  if (!CheckFetcherIsStillAlive(web_contents)) { | 
| -    Cancel(); | 
| -    return; | 
| -  } | 
| -  if (bitmap.drawsNothing()) { | 
| -    OutputDeveloperNotShownMessage(web_contents, kNoIconAvailable, | 
| -                                   is_debug_mode_); | 
| -    Cancel(); | 
| -    return; | 
| -  } | 
| - | 
| -  RecordCouldShowBanner(); | 
| -  if (!is_debug_mode_ && !CheckIfShouldShowBanner()) { | 
| -    // At this point, the only possible case is that the banner has been added | 
| -    // to the homescreen, given all of the other checks that have been made. | 
| -    Cancel(); | 
| -    return; | 
| -  } | 
| - | 
| -  app_icon_.reset(new SkBitmap(bitmap)); | 
| -  event_request_id_ = ++gCurrentRequestID; | 
| - | 
| -  TrackBeforeInstallEvent(BEFORE_INSTALL_EVENT_CREATED); | 
| -  web_contents->GetMainFrame()->Send( | 
| -      new ChromeViewMsg_AppBannerPromptRequest( | 
| -        web_contents->GetMainFrame()->GetRoutingID(), | 
| -        event_request_id_, | 
| -        GetBannerType())); | 
| -} | 
| - | 
| -bool AppBannerDataFetcher::IsWebAppInstalled( | 
| -    content::BrowserContext* browser_context, | 
| -    const GURL& start_url) { | 
| -  return false; | 
| -} | 
| - | 
| -void AppBannerDataFetcher::RecordCouldShowBanner() { | 
| -  content::WebContents* web_contents = GetWebContents(); | 
| -  DCHECK(web_contents); | 
| - | 
| -  AppBannerSettingsHelper::RecordBannerCouldShowEvent( | 
| -      web_contents, validated_url_, GetAppIdentifier(), | 
| -      GetCurrentTime(), transition_type_); | 
| -} | 
| - | 
| -bool AppBannerDataFetcher::CheckIfShouldShowBanner() { | 
| -  content::WebContents* web_contents = GetWebContents(); | 
| -  DCHECK(web_contents); | 
| - | 
| -  return AppBannerSettingsHelper::ShouldShowBanner( | 
| -      web_contents, validated_url_, GetAppIdentifier(), GetCurrentTime()); | 
| -} | 
| - | 
| -bool AppBannerDataFetcher::CheckFetcherIsStillAlive( | 
| -    content::WebContents* web_contents) { | 
| -  if (!is_active_) { | 
| -    OutputDeveloperNotShownMessage( | 
| -        web_contents, kUserNavigatedBeforeBannerShown, is_debug_mode_); | 
| -    return false; | 
| -  } | 
| -  if (!web_contents) { | 
| -    return false; // We cannot show a message if |web_contents| is null | 
| -  } | 
| -  return true; | 
| -} | 
| - | 
| -// static | 
| -bool AppBannerDataFetcher::IsManifestValidForWebApp( | 
| -    const content::Manifest& manifest, | 
| -    content::WebContents* web_contents, | 
| -    bool is_debug_mode) { | 
| -  if (manifest.IsEmpty()) { | 
| -    OutputDeveloperNotShownMessage(web_contents, kManifestEmpty, is_debug_mode); | 
| -    return false; | 
| -  } | 
| -  if (!manifest.start_url.is_valid()) { | 
| -    OutputDeveloperNotShownMessage(web_contents, kStartURLNotValid, | 
| -                                   is_debug_mode); | 
| -    return false; | 
| -  } | 
| -  if ((manifest.name.is_null() || manifest.name.string().empty()) && | 
| -      (manifest.short_name.is_null() || manifest.short_name.string().empty())) { | 
| -    OutputDeveloperNotShownMessage( | 
| -        web_contents, kManifestMissingNameOrShortName, is_debug_mode); | 
| -    return false; | 
| -  } | 
| - | 
| -  // TODO(dominickn,mlamouri): when Chrome supports "minimal-ui", it should be | 
| -  // accepted. If we accept it today, it would fallback to "browser" and make | 
| -  // this check moot. See https://crbug.com/604390 | 
| -  if (manifest.display != blink::WebDisplayModeStandalone && | 
| -      manifest.display != blink::WebDisplayModeFullscreen) { | 
| -    OutputDeveloperNotShownMessage( | 
| -        web_contents, kManifestDisplayStandaloneFullscreen, is_debug_mode); | 
| -    return false; | 
| -  } | 
| - | 
| -  if (!DoesManifestContainRequiredIcon(manifest)) { | 
| -    OutputDeveloperNotShownMessage(web_contents, kManifestMissingSuitableIcon, | 
| -                                   is_debug_mode); | 
| -    return false; | 
| -  } | 
| -  return true; | 
| -} | 
| - | 
| -}  // namespace banners | 
|  |