// Copyright (c) 2012 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.
//
// Implementation of the SafeBrowsingBlockingPage class.

#include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"

#include <string>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/i18n/rtl.h"
#include "base/lazy_instance.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_preferences_util.h"
#include "chrome/browser/safe_browsing/malware_details.h"
#include "chrome/browser/safe_browsing/ui_manager.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "components/google/core/browser/google_util.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/interstitial_page.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/browser/web_contents.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "net/base/escape.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/webui/jstemplate_builder.h"
#include "ui/base/webui/web_ui_util.h"

using base::UserMetricsAction;
using content::BrowserThread;
using content::InterstitialPage;
using content::OpenURLParams;
using content::Referrer;
using content::WebContents;

namespace {

// For malware interstitial pages, we link the problematic URL to Google's
// diagnostic page.
#if defined(GOOGLE_CHROME_BUILD)
const char* const kSbDiagnosticUrl =
    "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%s&client=googlechrome";
#else
const char* const kSbDiagnosticUrl =
    "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%s&client=chromium";
#endif

const char kSbReportPhishingErrorUrl[] =
    "http://www.google.com/safebrowsing/report_error/";

// URL for the "Learn more" link on the multi threat malware blocking page.
const char kLearnMoreMalwareUrl[] =
    "https://www.google.com/support/bin/answer.py?answer=45449&topic=360"
    "&sa=X&oi=malwarewarninglink&resnum=1&ct=help";

// URL for malware and phishing, V2.
const char kLearnMoreMalwareUrlV2[] =
    "https://www.google.com/transparencyreport/safebrowsing/";
const char kLearnMorePhishingUrlV2[] =
    "https://www.google.com/transparencyreport/safebrowsing/";

// URL for the "Learn more" link on the phishing blocking page.
const char kLearnMorePhishingUrl[] =
    "https://www.google.com/support/bin/answer.py?answer=106318";

const char kPrivacyLinkHtml[] =
    "<a id=\"privacy-link\" href=\"\" onclick=\"sendCommand('showPrivacy'); "
    "return false;\" onmousedown=\"return false;\">%s</a>";

// After a malware interstitial where the user opted-in to the report
// but clicked "proceed anyway", we delay the call to
// MalwareDetails::FinishCollection() by this much time (in
// milliseconds).
const int64 kMalwareDetailsProceedDelayMilliSeconds = 3000;

// The commands returned by the page when the user performs an action.
const char kDoReportCommand[] = "doReport";
const char kDontReportCommand[] = "dontReport";
const char kExpandedSeeMoreCommand[] = "expandedSeeMore";
const char kLearnMoreCommand[] = "learnMore";
const char kLearnMoreCommandV2[] = "learnMore2";
const char kProceedCommand[] = "proceed";
const char kReportErrorCommand[] = "reportError";
const char kShowDiagnosticCommand[] = "showDiagnostic";
const char kShowPrivacyCommand[] = "showPrivacy";
const char kTakeMeBackCommand[] = "takeMeBack";
// Special command that we use when the user navigated away from the
// page.  E.g., closed the tab or the window.  This is only used by
// RecordUserReactionTime.
const char kNavigatedAwayMetaCommand[] = "closed";

// Other constants used to communicate with the JavaScript.
const char kBoxChecked[] = "boxchecked";
const char kDisplayCheckBox[] = "displaycheckbox";

base::LazyInstance<SafeBrowsingBlockingPage::UnsafeResourceMap>
    g_unsafe_resource_map = LAZY_INSTANCE_INITIALIZER;

// This enum is used for a histogram.  Don't reorder, delete, or insert
// elements.  New elements should be added before MAX_ACTION only.
enum DetailedDecision {
  MALWARE_SHOW_NEW_SITE = 0,
  MALWARE_PROCEED_NEW_SITE,
  MALWARE_SHOW_CROSS_SITE,
  MALWARE_PROCEED_CROSS_SITE,
  PHISHING_SHOW_NEW_SITE,
  PHISHING_PROCEED_NEW_SITE,
  PHISHING_SHOW_CROSS_SITE,
  PHISHING_PROCEED_CROSS_SITE,
  MAX_DETAILED_ACTION
};

void RecordDetailedUserAction(DetailedDecision decision) {
  UMA_HISTOGRAM_ENUMERATION("SB2.InterstitialActionDetails",
                            decision,
                            MAX_DETAILED_ACTION);
}

// Constants for the M37 Finch trial.
const char kV3StudyName[]         = "MalwareInterstitialVersion";
const char kCondV2[]              = "V2";
const char kCondV3[]              = "V3";
const char kCondV3Advice[]        = "V3Advice";
const char kCondV3Social[]        = "V3Social";
const char kCondV3NotRecommend[]  = "V3NotRecommend";
const char kCondV3History[]       = "V3History";

// Default to V3 unless a flag or field trial says otherwise. Flags override
// field trial settings.
const char* GetTrialCondition() {
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kMalwareInterstitialV2)) {
    return kCondV2;
  }
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kMalwareInterstitialV3)) {
    return kCondV3;
  }
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kMalwareInterstitialV3Advice)) {
    return kCondV3Advice;
  }
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kMalwareInterstitialV3Social)) {
    return kCondV3Social;
  }
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kMalwareInterstitialV3NotRecommend)) {
    return kCondV3NotRecommend;
  }
  if (CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kMalwareInterstitialV3History)) {
    return kCondV3History;
  }

  // Make sure that the return value is one of the expected types instead of
  // directly returning base::FieldTrialList::FindFullName.
  if (base::FieldTrialList::FindFullName(kV3StudyName) == kCondV2)
    return kCondV2;
  if (base::FieldTrialList::FindFullName(kV3StudyName) == kCondV3)
    return kCondV3;
  if (base::FieldTrialList::FindFullName(kV3StudyName) == kCondV3Advice)
    return kCondV3Advice;
  if (base::FieldTrialList::FindFullName(kV3StudyName) == kCondV3Social)
    return kCondV3Social;
  if (base::FieldTrialList::FindFullName(kV3StudyName) == kCondV3NotRecommend)
    return kCondV3NotRecommend;
  if (base::FieldTrialList::FindFullName(kV3StudyName) == kCondV3History)
    return kCondV3History;
  return kCondV3;
}

}  // namespace

// static
SafeBrowsingBlockingPageFactory* SafeBrowsingBlockingPage::factory_ = NULL;

// The default SafeBrowsingBlockingPageFactory.  Global, made a singleton so we
// don't leak it.
class SafeBrowsingBlockingPageFactoryImpl
    : public SafeBrowsingBlockingPageFactory {
 public:
  virtual SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
      SafeBrowsingUIManager* ui_manager,
      WebContents* web_contents,
      const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources)
      OVERRIDE {
    // Only use the V2 page if the interstitial is for a single malware or
    // phishing resource, the multi-threat interstitial has not been updated to
    // V2 yet.
    if (unsafe_resources.size() == 1 &&
        (unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_MALWARE ||
         unsafe_resources[0].threat_type ==
         SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL ||
         unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_PHISHING ||
         unsafe_resources[0].threat_type ==
         SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL)) {
      if (GetTrialCondition() == kCondV2) {
        return new SafeBrowsingBlockingPageV2(ui_manager, web_contents,
            unsafe_resources);
      } else {
        return new SafeBrowsingBlockingPageV3(ui_manager, web_contents,
            unsafe_resources);
      }
    }
    return new SafeBrowsingBlockingPageV1(ui_manager, web_contents,
                                          unsafe_resources);
  }

 private:
  friend struct base::DefaultLazyInstanceTraits<
      SafeBrowsingBlockingPageFactoryImpl>;

  SafeBrowsingBlockingPageFactoryImpl() { }

  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPageFactoryImpl);
};

static base::LazyInstance<SafeBrowsingBlockingPageFactoryImpl>
    g_safe_browsing_blocking_page_factory_impl = LAZY_INSTANCE_INITIALIZER;

SafeBrowsingBlockingPage::SafeBrowsingBlockingPage(
    SafeBrowsingUIManager* ui_manager,
    WebContents* web_contents,
    const UnsafeResourceList& unsafe_resources)
    : malware_details_proceed_delay_ms_(
          kMalwareDetailsProceedDelayMilliSeconds),
      ui_manager_(ui_manager),
      report_loop_(NULL),
      is_main_frame_load_blocked_(IsMainPageLoadBlocked(unsafe_resources)),
      unsafe_resources_(unsafe_resources),
      proceeded_(false),
      web_contents_(web_contents),
      url_(unsafe_resources[0].url),
      has_expanded_see_more_section_(false),
      reporting_checkbox_checked_(false),
      num_visits_(-1) {
  bool malware = false;
  bool phishing = false;
  for (UnsafeResourceList::const_iterator iter = unsafe_resources_.begin();
       iter != unsafe_resources_.end(); ++iter) {
    const UnsafeResource& resource = *iter;
    SBThreatType threat_type = resource.threat_type;
    if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
        threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
      malware = true;
    } else {
      DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
             threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
      phishing = true;
    }
  }
  DCHECK(phishing || malware);
  if (malware && phishing)
    interstitial_type_ = TYPE_MALWARE_AND_PHISHING;
  else if (malware)
    interstitial_type_ = TYPE_MALWARE;
  else
    interstitial_type_ = TYPE_PHISHING;

  RecordUserAction(SHOW);
  HistoryService* history_service = HistoryServiceFactory::GetForProfile(
          Profile::FromBrowserContext(web_contents->GetBrowserContext()),
          Profile::EXPLICIT_ACCESS);
  if (history_service) {
    history_service->GetVisibleVisitCountToHost(
        url_,
        base::Bind(&SafeBrowsingBlockingPage::OnGotHistoryCount,
                   base::Unretained(this)),
        &request_tracker_);
  }

  if (!is_main_frame_load_blocked_) {
    navigation_entry_index_to_remove_ =
        web_contents->GetController().GetLastCommittedEntryIndex();
  } else {
    navigation_entry_index_to_remove_ = -1;
  }

  // Start computing malware details. They will be sent only
  // if the user opts-in on the blocking page later.
  // If there's more than one malicious resources, it means the user
  // clicked through the first warning, so we don't prepare additional
  // reports.
  if (unsafe_resources.size() == 1 &&
      unsafe_resources[0].threat_type == SB_THREAT_TYPE_URL_MALWARE &&
      malware_details_.get() == NULL && CanShowMalwareDetailsOption()) {
    malware_details_ = MalwareDetails::NewMalwareDetails(
        ui_manager_, web_contents, unsafe_resources[0]);
  }

  interstitial_page_ = InterstitialPage::Create(
      web_contents, IsMainPageLoadBlocked(unsafe_resources), url_, this);
}

bool SafeBrowsingBlockingPage::CanShowMalwareDetailsOption() {
  return (!web_contents_->GetBrowserContext()->IsOffTheRecord() &&
          web_contents_->GetURL().SchemeIs(url::kHttpScheme));
}

SafeBrowsingBlockingPage::~SafeBrowsingBlockingPage() {
}

void SafeBrowsingBlockingPage::CommandReceived(const std::string& cmd) {
  std::string command(cmd);  // Make a local copy so we can modify it.
  // The Jasonified response has quotes, remove them.
  if (command.length() > 1 && command[0] == '"') {
    command = command.substr(1, command.length() - 2);
  }
  RecordUserReactionTime(command);
  if (command == kDoReportCommand) {
    SetReportingPreference(true);
    return;
  }

  if (command == kDontReportCommand) {
    SetReportingPreference(false);
    return;
  }

  if (command == kLearnMoreCommand) {
    // User pressed "Learn more".
    GURL url;
    SBThreatType threat_type = unsafe_resources_[0].threat_type;
    if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
        threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
      url = GURL(kLearnMoreMalwareUrl);
    } else if (threat_type == SB_THREAT_TYPE_URL_PHISHING ||
               threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
      url = GURL(kLearnMorePhishingUrl);
    } else {
      NOTREACHED();
    }

    OpenURLParams params(
        url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false);
    web_contents_->OpenURL(params);
    return;
  }

  if (command == kLearnMoreCommandV2) {
    // User pressed "Learn more".
    GURL url;
    SBThreatType threat_type = unsafe_resources_[0].threat_type;
    if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
        threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
      url = GURL(kLearnMoreMalwareUrlV2);
    } else if (threat_type == SB_THREAT_TYPE_URL_PHISHING ||
               threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
      url = GURL(kLearnMorePhishingUrlV2);
    } else {
      NOTREACHED();
    }

    OpenURLParams params(
        url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false);
    web_contents_->OpenURL(params);
    return;
  }

  if (command == kShowPrivacyCommand) {
    // User pressed "Safe Browsing privacy policy".
    GURL url(l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_URL));
    OpenURLParams params(
        url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false);
    web_contents_->OpenURL(params);
    return;
  }

  bool proceed_blocked = false;
  if (command == kProceedCommand) {
    if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)) {
      proceed_blocked = true;
    } else {
      interstitial_page_->Proceed();
      // |this| has been deleted after Proceed() returns.
      return;
    }
  }

  if (command == kTakeMeBackCommand || proceed_blocked) {
    if (is_main_frame_load_blocked_) {
      // If the load is blocked, we want to close the interstitial and discard
      // the pending entry.
      interstitial_page_->DontProceed();
      // |this| has been deleted after DontProceed() returns.
      return;
    }

    // Otherwise the offending entry has committed, and we need to go back or
    // to a safe page.  We will close the interstitial when that page commits.
    if (web_contents_->GetController().CanGoBack()) {
      web_contents_->GetController().GoBack();
    } else {
      web_contents_->GetController().LoadURL(
          GURL(chrome::kChromeUINewTabURL),
          content::Referrer(),
          content::PAGE_TRANSITION_AUTO_TOPLEVEL,
          std::string());
    }
    return;
  }

  // The "report error" and "show diagnostic" commands can have a number
  // appended to them, which is the index of the element they apply to.
  size_t element_index = 0;
  size_t colon_index = command.find(':');
  if (colon_index != std::string::npos) {
    DCHECK(colon_index < command.size() - 1);
    int result_int = 0;
    bool result = base::StringToInt(base::StringPiece(command.begin() +
                                                      colon_index + 1,
                                                      command.end()),
                                    &result_int);
    command = command.substr(0, colon_index);
    if (result)
      element_index = static_cast<size_t>(result_int);
  }

  if (element_index >= unsafe_resources_.size()) {
    NOTREACHED();
    return;
  }

  std::string bad_url_spec = unsafe_resources_[element_index].url.spec();
  if (command == kReportErrorCommand) {
    // User pressed "Report error" for a phishing site.
    // Note that we cannot just put a link in the interstitial at this point.
    // It is not OK to navigate in the context of an interstitial page.
    SBThreatType threat_type = unsafe_resources_[element_index].threat_type;
    DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
           threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
    GURL report_url =
        safe_browsing_util::GeneratePhishingReportUrl(
            kSbReportPhishingErrorUrl,
            bad_url_spec,
            threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
    OpenURLParams params(
        report_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK,
        false);
    web_contents_->OpenURL(params);
    return;
  }

  if (command == kShowDiagnosticCommand) {
    // We're going to take the user to Google's SafeBrowsing diagnostic page.
    std::string diagnostic =
        base::StringPrintf(kSbDiagnosticUrl,
            net::EscapeQueryParamValue(bad_url_spec, true).c_str());
    GURL diagnostic_url(diagnostic);
    diagnostic_url = google_util::AppendGoogleLocaleParam(
        diagnostic_url, g_browser_process->GetApplicationLocale());
    DCHECK(unsafe_resources_[element_index].threat_type ==
           SB_THREAT_TYPE_URL_MALWARE ||
           unsafe_resources_[element_index].threat_type ==
           SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL);
    OpenURLParams params(
        diagnostic_url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK,
        false);
    web_contents_->OpenURL(params);
    return;
  }

  if (command == kExpandedSeeMoreCommand) {
    // User expanded the "see more info" section of the page.  We don't actually
    // do any action based on this, it's just so that RecordUserReactionTime can
    // track it.
    return;
  }

  NOTREACHED() << "Unexpected command: " << command;
}

void SafeBrowsingBlockingPage::OverrideRendererPrefs(
      content::RendererPreferences* prefs) {
  Profile* profile = Profile::FromBrowserContext(
      web_contents_->GetBrowserContext());
  renderer_preferences_util::UpdateFromSystemSettings(prefs, profile);
 }

void SafeBrowsingBlockingPage::SetReportingPreference(bool report) {
  Profile* profile = Profile::FromBrowserContext(
      web_contents_->GetBrowserContext());
  PrefService* pref = profile->GetPrefs();
  pref->SetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled, report);
  UMA_HISTOGRAM_BOOLEAN("SB2.SetExtendedReportingEnabled", report);
  reporting_checkbox_checked_ = report;
  pref->ClearPref(prefs::kSafeBrowsingReportingEnabled);
  pref->ClearPref(prefs::kSafeBrowsingDownloadFeedbackEnabled);
}

// If the reporting checkbox was left checked on close, the new pref
// kSafeBrowsingExtendedReportingEnabled should be updated.
// TODO(felt): Remove this in M-39. crbug.com/384668
void SafeBrowsingBlockingPage::UpdateReportingPref() {
  if (!reporting_checkbox_checked_)
    return;
  if (IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled))
    return;
  Profile* profile = Profile::FromBrowserContext(
      web_contents_->GetBrowserContext());
  if (profile->GetPrefs()->HasPrefPath(
      prefs::kSafeBrowsingExtendedReportingEnabled))
    return;
  SetReportingPreference(true);
}

void SafeBrowsingBlockingPage::OnProceed() {
  proceeded_ = true;
  RecordUserAction(PROCEED);
  UpdateReportingPref();
  // Send the malware details, if we opted to.
  FinishMalwareDetails(malware_details_proceed_delay_ms_);

  NotifySafeBrowsingUIManager(ui_manager_, unsafe_resources_, true);

  // Check to see if some new notifications of unsafe resources have been
  // received while we were showing the interstitial.
  UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap();
  UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents_);
  SafeBrowsingBlockingPage* blocking_page = NULL;
  if (iter != unsafe_resource_map->end() && !iter->second.empty()) {
    // Build an interstitial for all the unsafe resources notifications.
    // Don't show it now as showing an interstitial while an interstitial is
    // already showing would cause DontProceed() to be invoked.
    blocking_page = factory_->CreateSafeBrowsingPage(ui_manager_, web_contents_,
                                                     iter->second);
    unsafe_resource_map->erase(iter);
  }

  // Now that this interstitial is gone, we can show the new one.
  if (blocking_page)
    blocking_page->interstitial_page_->Show();
}

void SafeBrowsingBlockingPage::OnDontProceed() {
  // Calling this method twice will not double-count.
  RecordUserReactionTime(kNavigatedAwayMetaCommand);
  // We could have already called Proceed(), in which case we must not notify
  // the SafeBrowsingUIManager again, as the client has been deleted.
  if (proceeded_)
    return;

  RecordUserAction(DONT_PROCEED);
  UpdateReportingPref();
  // Send the malware details, if we opted to.
  FinishMalwareDetails(0);  // No delay

  NotifySafeBrowsingUIManager(ui_manager_, unsafe_resources_, false);

  // The user does not want to proceed, clear the queued unsafe resources
  // notifications we received while the interstitial was showing.
  UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap();
  UnsafeResourceMap::iterator iter = unsafe_resource_map->find(web_contents_);
  if (iter != unsafe_resource_map->end() && !iter->second.empty()) {
    NotifySafeBrowsingUIManager(ui_manager_, iter->second, false);
    unsafe_resource_map->erase(iter);
  }

  // We don't remove the navigation entry if the tab is being destroyed as this
  // would trigger a navigation that would cause trouble as the render view host
  // for the tab has by then already been destroyed.  We also don't delete the
  // current entry if it has been committed again, which is possible on a page
  // that had a subresource warning.
  int last_committed_index =
      web_contents_->GetController().GetLastCommittedEntryIndex();
  if (navigation_entry_index_to_remove_ != -1 &&
      navigation_entry_index_to_remove_ != last_committed_index &&
      !web_contents_->IsBeingDestroyed()) {
    CHECK(web_contents_->GetController().RemoveEntryAtIndex(
        navigation_entry_index_to_remove_));
    navigation_entry_index_to_remove_ = -1;
  }
}

void SafeBrowsingBlockingPage::OnGotHistoryCount(bool success,
                                                 int num_visits,
                                                 base::Time first_visit) {
  if (success)
    num_visits_ = num_visits;
}

void SafeBrowsingBlockingPage::RecordUserAction(BlockingPageEvent event) {
  // This enum is used for a histogram.  Don't reorder, delete, or insert
  // elements.  New elements should be added before MAX_ACTION only.
  enum {
    MALWARE_SHOW = 0,
    MALWARE_DONT_PROCEED,
    MALWARE_FORCED_DONT_PROCEED,
    MALWARE_PROCEED,
    MULTIPLE_SHOW,
    MULTIPLE_DONT_PROCEED,
    MULTIPLE_FORCED_DONT_PROCEED,
    MULTIPLE_PROCEED,
    PHISHING_SHOW,
    PHISHING_DONT_PROCEED,
    PHISHING_FORCED_DONT_PROCEED,
    PHISHING_PROCEED,
    MALWARE_SHOW_ADVANCED,
    MULTIPLE_SHOW_ADVANCED,
    PHISHING_SHOW_ADVANCED,
    MAX_ACTION
  } histogram_action = MAX_ACTION;

  switch (event) {
    case SHOW:
      switch (interstitial_type_) {
        case TYPE_MALWARE_AND_PHISHING:
          histogram_action = MULTIPLE_SHOW;
          break;
        case TYPE_MALWARE:
          histogram_action = MALWARE_SHOW;
          break;
        case TYPE_PHISHING:
          histogram_action = PHISHING_SHOW;
          break;
      }
      break;
    case PROCEED:
      switch (interstitial_type_) {
        case TYPE_MALWARE_AND_PHISHING:
          histogram_action = MULTIPLE_PROCEED;
          break;
        case TYPE_MALWARE:
          histogram_action = MALWARE_PROCEED;
          break;
        case TYPE_PHISHING:
          histogram_action = PHISHING_PROCEED;
          break;
      }
      break;
    case DONT_PROCEED:
      if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled)) {
        switch (interstitial_type_) {
          case TYPE_MALWARE_AND_PHISHING:
            histogram_action = MULTIPLE_FORCED_DONT_PROCEED;
            break;
          case TYPE_MALWARE:
            histogram_action = MALWARE_FORCED_DONT_PROCEED;
            break;
          case TYPE_PHISHING:
            histogram_action = PHISHING_FORCED_DONT_PROCEED;
            break;
        }
      } else {
        switch (interstitial_type_) {
          case TYPE_MALWARE_AND_PHISHING:
            histogram_action = MULTIPLE_DONT_PROCEED;
            break;
          case TYPE_MALWARE:
            histogram_action = MALWARE_DONT_PROCEED;
            break;
          case TYPE_PHISHING:
            histogram_action = PHISHING_DONT_PROCEED;
            break;
        }
      }
      break;
    case SHOW_ADVANCED:
      switch (interstitial_type_) {
        case TYPE_MALWARE_AND_PHISHING:
          histogram_action = MULTIPLE_SHOW_ADVANCED;
          break;
        case TYPE_MALWARE:
          histogram_action = MALWARE_SHOW_ADVANCED;
          break;
        case TYPE_PHISHING:
          histogram_action = PHISHING_SHOW_ADVANCED;
          break;
      }
      break;
    default:
      NOTREACHED() << "Unexpected event: " << event;
  }
  if (histogram_action == MAX_ACTION) {
    NOTREACHED();
  } else {
    UMA_HISTOGRAM_ENUMERATION("SB2.InterstitialAction", histogram_action,
                              MAX_ACTION);
  }

  if (event == PROCEED || event == DONT_PROCEED) {
    if (num_visits_ == 0 && interstitial_type_ != TYPE_MALWARE_AND_PHISHING) {
      RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
                               MALWARE_SHOW_NEW_SITE : PHISHING_SHOW_NEW_SITE);
      if (event == PROCEED) {
        RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
            MALWARE_PROCEED_NEW_SITE : PHISHING_PROCEED_NEW_SITE);
      }
    }
    if (unsafe_resources_[0].is_subresource &&
        interstitial_type_ != TYPE_MALWARE_AND_PHISHING) {
      RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
          MALWARE_SHOW_CROSS_SITE : PHISHING_SHOW_CROSS_SITE);
      if (event == PROCEED) {
        RecordDetailedUserAction((interstitial_type_ == TYPE_MALWARE) ?
            MALWARE_PROCEED_CROSS_SITE : PHISHING_PROCEED_CROSS_SITE);
      }
    }
  }

  // TODO(felt): Get rid of the old interstitial histogram.
  std::string action = "SBInterstitial";
  switch (interstitial_type_) {
    case TYPE_MALWARE_AND_PHISHING:
      action.append("Multiple");
      break;
    case TYPE_MALWARE:
      action.append("Malware");
      break;
    case TYPE_PHISHING:
      action.append("Phishing");
      break;
  }

  switch (event) {
    case SHOW:
      action.append("Show");
      break;
    case PROCEED:
      action.append("Proceed");
      break;
    case DONT_PROCEED:
      if (IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled))
        action.append("ForcedDontProceed");
      else
        action.append("DontProceed");
      break;
    case SHOW_ADVANCED:
      break;
    default:
      NOTREACHED() << "Unexpected event: " << event;
  }

  content::RecordComputedAction(action);
}

void SafeBrowsingBlockingPage::RecordUserReactionTime(
    const std::string& command) {
  if (interstitial_show_time_.is_null())
    return;  // We already reported the user reaction time.
  base::TimeDelta dt = base::TimeTicks::Now() - interstitial_show_time_;
  DVLOG(1) << "User reaction time for command:" << command
           << " on interstitial_type_:" << interstitial_type_
           << " warning took " << dt.InMilliseconds() << "ms";
  bool recorded = true;
  if (interstitial_type_ == TYPE_MALWARE ||
      interstitial_type_ == TYPE_MALWARE_AND_PHISHING) {
    // There are six ways in which the malware interstitial can go
    // away.  We handle all of them here but we group two together: closing the
    // tag / browser window and clicking on the back button in the browser (not
    // the big green button) are considered the same action.
    if (command == kProceedCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeProceed", dt);
    } else if (command == kTakeMeBackCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeTakeMeBack", dt);
    } else if (command == kShowDiagnosticCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeDiagnostic", dt);
    } else if (command == kShowPrivacyCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimePrivacyPolicy",
                                 dt);
    } else if (command == kLearnMoreCommand || command == kLearnMoreCommandV2) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialLearnMore",
                                 dt);
    } else if (command == kNavigatedAwayMetaCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeClosed", dt);
    } else if (command == kExpandedSeeMoreCommand) {
      // Only record the expanded histogram once per display of the
      // interstitial.
      if (has_expanded_see_more_section_)
        return;
      RecordUserAction(SHOW_ADVANCED);
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.MalwareInterstitialTimeExpandedSeeMore",
                                 dt);
      has_expanded_see_more_section_ = true;
      // Expanding the "See More" section doesn't finish the interstitial, so
      // don't mark the reaction time as recorded.
      recorded = false;
    } else {
      recorded = false;
    }
  } else {
    // Same as above but for phishing warnings.
    if (command == kProceedCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeProceed", dt);
    } else if (command == kTakeMeBackCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeTakeMeBack", dt);
    } else if (command == kShowDiagnosticCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeReportError", dt);
    } else if (command == kLearnMoreCommand || command == kLearnMoreCommandV2) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeLearnMore", dt);
    } else if (command == kNavigatedAwayMetaCommand) {
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeClosed", dt);
    } else if (command == kExpandedSeeMoreCommand) {
      // Only record the expanded histogram once per display of the
      // interstitial.
      if (has_expanded_see_more_section_)
        return;
      RecordUserAction(SHOW_ADVANCED);
      UMA_HISTOGRAM_MEDIUM_TIMES("SB2.PhishingInterstitialTimeExpandedSeeMore",
                                 dt);
      has_expanded_see_more_section_ = true;
      // Expanding the "See More" section doesn't finish the interstitial, so
      // don't mark the reaction time as recorded.
      recorded = false;
    } else {
      recorded = false;
    }
  }
  if (recorded)  // Making sure we don't double-count reaction times.
    interstitial_show_time_ = base::TimeTicks();  //  Resets the show time.
}

void SafeBrowsingBlockingPage::FinishMalwareDetails(int64 delay_ms) {
  if (malware_details_.get() == NULL)
    return;  // Not all interstitials have malware details (eg phishing).

  const bool enabled =
      IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled);
  UMA_HISTOGRAM_BOOLEAN("SB2.ExtendedReportingIsEnabled", enabled);
  if (enabled) {
    // Finish the malware details collection, send it over.
    BrowserThread::PostDelayedTask(
        BrowserThread::IO, FROM_HERE,
        base::Bind(&MalwareDetails::FinishCollection, malware_details_.get()),
        base::TimeDelta::FromMilliseconds(delay_ms));
  }
}

bool SafeBrowsingBlockingPage::IsPrefEnabled(const char* pref) {
  Profile* profile =
      Profile::FromBrowserContext(web_contents_->GetBrowserContext());
  return profile->GetPrefs()->GetBoolean(pref);
}

// static
void SafeBrowsingBlockingPage::NotifySafeBrowsingUIManager(
    SafeBrowsingUIManager* ui_manager,
    const UnsafeResourceList& unsafe_resources,
    bool proceed) {
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&SafeBrowsingUIManager::OnBlockingPageDone,
                 ui_manager, unsafe_resources, proceed));
}

// static
SafeBrowsingBlockingPage::UnsafeResourceMap*
    SafeBrowsingBlockingPage::GetUnsafeResourcesMap() {
  return g_unsafe_resource_map.Pointer();
}

// static
void SafeBrowsingBlockingPage::ShowBlockingPage(
    SafeBrowsingUIManager* ui_manager,
    const UnsafeResource& unsafe_resource) {
  DVLOG(1) << __FUNCTION__ << " " << unsafe_resource.url.spec();
  WebContents* web_contents = tab_util::GetWebContentsByID(
      unsafe_resource.render_process_host_id, unsafe_resource.render_view_id);

  InterstitialPage* interstitial =
      InterstitialPage::GetInterstitialPage(web_contents);
  if (interstitial && !unsafe_resource.is_subresource) {
    // There is already an interstitial showing and we are about to display a
    // new one for the main frame. Just hide the current one, it is now
    // irrelevent
    interstitial->DontProceed();
    interstitial = NULL;
  }

  if (!interstitial) {
    // There are no interstitial currently showing in that tab, go ahead and
    // show this interstitial.
    std::vector<UnsafeResource> resources;
    resources.push_back(unsafe_resource);
    // Set up the factory if this has not been done already (tests do that
    // before this method is called).
    if (!factory_)
      factory_ = g_safe_browsing_blocking_page_factory_impl.Pointer();
    SafeBrowsingBlockingPage* blocking_page =
        factory_->CreateSafeBrowsingPage(ui_manager, web_contents, resources);
    blocking_page->interstitial_page_->Show();
    return;
  }

  // This is an interstitial for a page's resource, let's queue it.
  UnsafeResourceMap* unsafe_resource_map = GetUnsafeResourcesMap();
  (*unsafe_resource_map)[web_contents].push_back(unsafe_resource);
}

// static
bool SafeBrowsingBlockingPage::IsMainPageLoadBlocked(
    const UnsafeResourceList& unsafe_resources) {
  // Client-side phishing detection interstitials never block the main frame
  // load, since they happen after the page is finished loading.
  if (unsafe_resources[0].threat_type ==
      SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL) {
    return false;
  }

  // Otherwise, check the threat type.
  return unsafe_resources.size() == 1 && !unsafe_resources[0].is_subresource;
}

SafeBrowsingBlockingPageV1::SafeBrowsingBlockingPageV1(
    SafeBrowsingUIManager* ui_manager,
    WebContents* web_contents,
    const UnsafeResourceList& unsafe_resources)
  : SafeBrowsingBlockingPage(ui_manager, web_contents, unsafe_resources) {
}

std::string SafeBrowsingBlockingPageV1::GetHTMLContents() {
  // Load the HTML page and create the template components.
  base::DictionaryValue strings;
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  std::string html;

  if (unsafe_resources_.empty()) {
    NOTREACHED();
    return std::string();
  }

  DCHECK_GT(unsafe_resources_.size(), 1U);
  PopulateMultipleThreatStringDictionary(&strings);
  html = rb.GetRawDataResource(
      IDR_SAFE_BROWSING_MULTIPLE_THREAT_BLOCK).as_string();
  interstitial_show_time_ = base::TimeTicks::Now();
  return webui::GetTemplatesHtml(html, &strings, "template_root");
}

void SafeBrowsingBlockingPageV1::PopulateStringDictionary(
    base::DictionaryValue* strings,
    const base::string16& title,
    const base::string16& headline,
    const base::string16& description1,
    const base::string16& description2,
    const base::string16& description3) {
  strings->SetString("title", title);
  strings->SetString("headLine", headline);
  strings->SetString("description1", description1);
  strings->SetString("description2", description2);
  strings->SetString("description3", description3);
  strings->SetBoolean("proceedDisabled",
                      IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled));
}

void SafeBrowsingBlockingPageV1::PopulateMultipleThreatStringDictionary(
    base::DictionaryValue* strings) {

  base::string16 malware_label =
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_LABEL);
  base::string16 malware_link =
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_DIAGNOSTIC_PAGE);
  base::string16 phishing_label =
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_LABEL);
  base::string16 phishing_link =
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_REPORT_ERROR);

  base::ListValue* error_strings = new base::ListValue;
  for (UnsafeResourceList::const_iterator iter = unsafe_resources_.begin();
       iter != unsafe_resources_.end(); ++iter) {
    const UnsafeResource& resource = *iter;
    SBThreatType threat_type = resource.threat_type;
    base::DictionaryValue* current_error_strings = new base::DictionaryValue;
    if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
        threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
      current_error_strings->SetString("type", "malware");
      current_error_strings->SetString("typeLabel", malware_label);
      current_error_strings->SetString("errorLink", malware_link);
    } else {
      DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
             threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
      current_error_strings->SetString("type", "phishing");
      current_error_strings->SetString("typeLabel", phishing_label);
      current_error_strings->SetString("errorLink", phishing_link);
    }
    current_error_strings->SetString("url", resource.url.spec());
    error_strings->Append(current_error_strings);
  }
  strings->Set("errors", error_strings);

  switch (interstitial_type_) {
    case TYPE_MALWARE_AND_PHISHING:
      PopulateStringDictionary(
          strings,
          // Use the malware headline, it is the scariest one.
          l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MULTI_THREAT_TITLE),
          l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_HEADLINE),
          l10n_util::GetStringFUTF16(
              IDS_SAFE_BROWSING_MULTI_THREAT_DESCRIPTION1,
              base::UTF8ToUTF16(web_contents_->GetURL().host())),
          l10n_util::GetStringUTF16(
              IDS_SAFE_BROWSING_MULTI_THREAT_DESCRIPTION2),
          base::string16());
      break;
    case TYPE_MALWARE:
      PopulateStringDictionary(
          strings,
          l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_TITLE),
          l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_HEADLINE),
          l10n_util::GetStringFUTF16(
              IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION1,
              base::UTF8ToUTF16(web_contents_->GetURL().host())),
          l10n_util::GetStringUTF16(
              IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION2),
          l10n_util::GetStringUTF16(
              IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION3));
      break;
    case TYPE_PHISHING:
      PopulateStringDictionary(
          strings,
          l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_TITLE),
          l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_HEADLINE),
          l10n_util::GetStringFUTF16(
              IDS_SAFE_BROWSING_MULTI_PHISHING_DESCRIPTION1,
              base::UTF8ToUTF16(web_contents_->GetURL().host())),
          base::string16(),
          base::string16());
      break;
  }

  strings->SetString("confirm_text",
                     l10n_util::GetStringUTF16(
                         IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION_AGREE));
  strings->SetString("continue_button",
                     l10n_util::GetStringUTF16(
                         IDS_SAFE_BROWSING_MULTI_MALWARE_PROCEED_BUTTON));
  strings->SetString("back_button",
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_BACK_BUTTON));
  strings->SetString("textdirection", base::i18n::IsRTL() ? "rtl" : "ltr");
}

void SafeBrowsingBlockingPageV1::PopulateMalwareStringDictionary(
    base::DictionaryValue* strings) {
  NOTREACHED();
}

void SafeBrowsingBlockingPageV1::PopulatePhishingStringDictionary(
    base::DictionaryValue* strings) {
  NOTREACHED();
}

SafeBrowsingBlockingPageV2::SafeBrowsingBlockingPageV2(
    SafeBrowsingUIManager* ui_manager,
    WebContents* web_contents,
    const UnsafeResourceList& unsafe_resources)
  : SafeBrowsingBlockingPage(ui_manager, web_contents, unsafe_resources) {
}

std::string SafeBrowsingBlockingPageV2::GetHTMLContents() {
  // Load the HTML page and create the template components.
  base::DictionaryValue strings;
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  std::string html;

  if (unsafe_resources_.empty()) {
    NOTREACHED();
    return std::string();
  }

  if (unsafe_resources_.size() > 1) {
    // TODO(felt): Implement new multi-threat interstitial and remove
    // SafeBrowsingBlockingPageV1 entirely.  (http://crbug.com/160336)
    NOTREACHED();
  } else {
    SBThreatType threat_type = unsafe_resources_[0].threat_type;
    if (threat_type == SB_THREAT_TYPE_URL_MALWARE ||
        threat_type == SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL) {
      PopulateMalwareStringDictionary(&strings);
    } else {  // Phishing.
      DCHECK(threat_type == SB_THREAT_TYPE_URL_PHISHING ||
             threat_type == SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL);
      PopulatePhishingStringDictionary(&strings);
    }
    html = rb.GetRawDataResource(IDR_SAFE_BROWSING_MALWARE_BLOCK_V2).
        as_string();
  }
  interstitial_show_time_ = base::TimeTicks::Now();
  return webui::GetTemplatesHtml(html, &strings, "template-root");
}

void SafeBrowsingBlockingPageV2::PopulateStringDictionary(
    base::DictionaryValue* strings,
    const base::string16& title,
    const base::string16& headline,
    const base::string16& description1,
    const base::string16& description2,
    const base::string16& description3) {
  strings->SetString("title", title);
  strings->SetString("headLine", headline);
  strings->SetString("description1", description1);
  strings->SetString("description2", description2);
  strings->SetString("description3", description3);
  strings->SetBoolean("proceedDisabled",
                      IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled));
  strings->SetBoolean("isMainFrame", is_main_frame_load_blocked_);
  strings->SetBoolean("isPhishing", interstitial_type_ == TYPE_PHISHING);

  strings->SetString("back_button",
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_BACK_BUTTON));
  strings->SetString("seeMore", l10n_util::GetStringUTF16(
      IDS_SAFE_BROWSING_MALWARE_V2_SEE_MORE));
  strings->SetString("proceed",
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_PROCEED_LINK));
  webui::SetFontAndTextDirection(strings);
}

void SafeBrowsingBlockingPageV2::PopulateMultipleThreatStringDictionary(
    base::DictionaryValue* strings) {
  NOTREACHED();
}

void SafeBrowsingBlockingPageV2::PopulateMalwareStringDictionary(
    base::DictionaryValue* strings) {
  // Check to see if we're blocking the main page, or a sub-resource on the
  // main page.
  base::string16 headline, description1, description2, description3;


  description3 = l10n_util::GetStringUTF16(
      IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION3);
  if (is_main_frame_load_blocked_) {
    headline = l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_HEADLINE);
    description1 = l10n_util::GetStringFUTF16(
        IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION1,
        l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
        base::UTF8ToUTF16(url_.host()));
    description2 = l10n_util::GetStringUTF16(
        IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION2);
    strings->SetString("details", l10n_util::GetStringUTF16(
          IDS_SAFE_BROWSING_MALWARE_V2_DETAILS));
  } else {
    headline = l10n_util::GetStringUTF16(
        IDS_SAFE_BROWSING_MALWARE_V2_HEADLINE_SUBRESOURCE);
    description1 = l10n_util::GetStringFUTF16(
        IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION1_SUBRESOURCE,
        l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
        base::UTF8ToUTF16(web_contents_->GetURL().host()));
    description2 = l10n_util::GetStringFUTF16(
        IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION2_SUBRESOURCE,
        base::UTF8ToUTF16(url_.host()));
    strings->SetString("details", l10n_util::GetStringFUTF16(
          IDS_SAFE_BROWSING_MALWARE_V2_DETAILS_SUBRESOURCE,
          base::UTF8ToUTF16(url_.host())));
  }

  PopulateStringDictionary(
      strings,
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_TITLE),
      headline,
      description1,
      description2,
      description3);

  if (!CanShowMalwareDetailsOption()) {
    strings->SetBoolean(kDisplayCheckBox, false);
    strings->SetString("confirm_text", std::string());
    strings->SetString(kBoxChecked, std::string());
  } else {
    // Show the checkbox for sending malware details.
    strings->SetBoolean(kDisplayCheckBox, true);

    std::string privacy_link = base::StringPrintf(
        kPrivacyLinkHtml,
        l10n_util::GetStringUTF8(
            IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE_V2).c_str());

    strings->SetString("confirm_text",
                       l10n_util::GetStringFUTF16(
                           IDS_SAFE_BROWSING_MALWARE_V2_REPORTING_AGREE,
                           base::UTF8ToUTF16(privacy_link)));
    Profile* profile = Profile::FromBrowserContext(
       web_contents_->GetBrowserContext());
    if (profile->GetPrefs()->HasPrefPath(
            prefs::kSafeBrowsingExtendedReportingEnabled)) {
      reporting_checkbox_checked_ =
          IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled);
    } else if (IsPrefEnabled(prefs::kSafeBrowsingReportingEnabled) ||
         IsPrefEnabled(prefs::kSafeBrowsingDownloadFeedbackEnabled)) {
      reporting_checkbox_checked_ = true;
    }
    strings->SetString(kBoxChecked,
                       reporting_checkbox_checked_ ? "yes" : std::string());
  }

  strings->SetString("report_error", base::string16());
  strings->SetString("learnMore",
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_LEARN_MORE));
}

void SafeBrowsingBlockingPageV2::PopulatePhishingStringDictionary(
    base::DictionaryValue* strings) {
  PopulateStringDictionary(
      strings,
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_TITLE),
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_HEADLINE),
      l10n_util::GetStringFUTF16(IDS_SAFE_BROWSING_PHISHING_V2_DESCRIPTION1,
                                 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME),
                                 base::UTF8ToUTF16(url_.host())),
      base::string16(),
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_DESCRIPTION2));

  strings->SetString("details", std::string());
  strings->SetString("confirm_text", std::string());
  strings->SetString(kBoxChecked, std::string());
  strings->SetString(
      "report_error",
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_PHISHING_V2_REPORT_ERROR));
  strings->SetBoolean(kDisplayCheckBox, false);
  strings->SetString("learnMore",
      l10n_util::GetStringUTF16(IDS_SAFE_BROWSING_MALWARE_V2_LEARN_MORE));
}

SafeBrowsingBlockingPageV3::SafeBrowsingBlockingPageV3(
    SafeBrowsingUIManager* ui_manager,
    WebContents* web_contents,
    const UnsafeResourceList& unsafe_resources)
    : SafeBrowsingBlockingPage(ui_manager, web_contents, unsafe_resources),
      trial_condition_(GetTrialCondition()) {
}

std::string SafeBrowsingBlockingPageV3::GetHTMLContents() {
  if (unsafe_resources_.empty() || unsafe_resources_.size() > 1) {
    // TODO(felt): Implement new multi-threat interstitial. crbug.com/160336
    NOTIMPLEMENTED();
    return std::string();
  }

  // Fill in the shared values.
  base::DictionaryValue load_time_data;
  webui::SetFontAndTextDirection(&load_time_data);
  load_time_data.SetBoolean("ssl", false);
  load_time_data.SetString(
      "tabTitle", l10n_util::GetStringUTF16(IDS_SAFEBROWSING_V3_TITLE));
  load_time_data.SetString(
      "openDetails",
      l10n_util::GetStringUTF16(IDS_SAFEBROWSING_V3_OPEN_DETAILS_BUTTON));
  load_time_data.SetString(
      "closeDetails",
      l10n_util::GetStringUTF16(IDS_SAFEBROWSING_V3_CLOSE_DETAILS_BUTTON));
  load_time_data.SetString(
      "primaryButtonText",
      l10n_util::GetStringUTF16(IDS_SAFEBROWSING_OVERRIDABLE_SAFETY_BUTTON));
  load_time_data.SetBoolean(
      "overridable",
      !IsPrefEnabled(prefs::kSafeBrowsingProceedAnywayDisabled));

  // Fill in the values that are specific to malware or phishing.
  SBThreatType threat_type = unsafe_resources_[0].threat_type;
  switch (threat_type) {
    case SB_THREAT_TYPE_URL_MALWARE:
    case SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL:
      PopulateMalwareLoadTimeData(&load_time_data);
      break;
    case SB_THREAT_TYPE_URL_PHISHING:
    case SB_THREAT_TYPE_CLIENT_SIDE_PHISHING_URL:
      PopulatePhishingLoadTimeData(&load_time_data);
      break;
    case SB_THREAT_TYPE_SAFE:
    case SB_THREAT_TYPE_BINARY_MALWARE_URL:
    case SB_THREAT_TYPE_EXTENSION:
      NOTREACHED();
  }

  interstitial_show_time_ = base::TimeTicks::Now();

  base::StringPiece html(
      ResourceBundle::GetSharedInstance().GetRawDataResource(
          IRD_SSL_INTERSTITIAL_V2_HTML));
  webui::UseVersion2 version;
  return webui::GetI18nTemplateHtml(html, &load_time_data);
}

void SafeBrowsingBlockingPageV3::PopulateMalwareLoadTimeData(
    base::DictionaryValue* load_time_data) {
  load_time_data->SetString("trialCondition", trial_condition_);
  load_time_data->SetBoolean("phishing", false);
  load_time_data->SetString(
      "heading", l10n_util::GetStringUTF16(IDS_MALWARE_V3_HEADING));
  load_time_data->SetString(
      "primaryParagraph",
      l10n_util::GetStringFUTF16(
          IDS_MALWARE_V3_PRIMARY_PARAGRAPH,
          base::UTF8ToUTF16(url_.host())));
  if (trial_condition_ == kCondV3History) {
    load_time_data->SetString(
        "explanationParagraph",
        is_main_frame_load_blocked_ ?
            l10n_util::GetStringFUTF16(
                IDS_MALWARE_V3_EXPLANATION_PARAGRAPH_HISTORY,
                base::UTF8ToUTF16(url_.host())) :
            l10n_util::GetStringFUTF16(
                IDS_MALWARE_V3_EXPLANATION_PARAGRAPH_SUBRESOURCE_HISTORY,
                base::UTF8ToUTF16(web_contents_->GetURL().host()),
                base::UTF8ToUTF16(url_.host())));
  } else if (trial_condition_ == kCondV3Advice) {
    load_time_data->SetString(
        "explanationParagraph",
        is_main_frame_load_blocked_ ?
            l10n_util::GetStringFUTF16(
                IDS_MALWARE_V3_EXPLANATION_PARAGRAPH_ADVICE,
                base::UTF8ToUTF16(url_.host())) :
            l10n_util::GetStringFUTF16(
                IDS_MALWARE_V3_EXPLANATION_PARAGRAPH_SUBRESOURCE_ADVICE,
                base::UTF8ToUTF16(web_contents_->GetURL().host()),
                base::UTF8ToUTF16(url_.host())));
    load_time_data->SetString(
        "adviceHeading",
        l10n_util::GetStringUTF16(IDS_MALWARE_V3_ADVICE_HEADING));
  } else {
    load_time_data->SetString(
        "explanationParagraph",
        is_main_frame_load_blocked_ ?
            l10n_util::GetStringFUTF16(
                IDS_MALWARE_V3_EXPLANATION_PARAGRAPH,
                base::UTF8ToUTF16(url_.host())) :
            l10n_util::GetStringFUTF16(
                IDS_MALWARE_V3_EXPLANATION_PARAGRAPH_SUBRESOURCE,
                base::UTF8ToUTF16(web_contents_->GetURL().host()),
                base::UTF8ToUTF16(url_.host())));
  }
  if (trial_condition_ == kCondV3Social) {
    load_time_data->SetString(
        "finalParagraph",
        l10n_util::GetStringUTF16(IDS_MALWARE_V3_PROCEED_PARAGRAPH_SOCIAL));
  } else if (trial_condition_ == kCondV3NotRecommend) {
    load_time_data->SetString(
        "finalParagraph",
        l10n_util::GetStringUTF16(
            IDS_MALWARE_V3_PROCEED_PARAGRAPH_NOT_RECOMMEND));
  } else {
    load_time_data->SetString(
        "finalParagraph",
        l10n_util::GetStringUTF16(IDS_MALWARE_V3_PROCEED_PARAGRAPH));
  }

  load_time_data->SetBoolean(kDisplayCheckBox, CanShowMalwareDetailsOption());
  if (CanShowMalwareDetailsOption()) {
    std::string privacy_link = base::StringPrintf(
        kPrivacyLinkHtml,
        l10n_util::GetStringUTF8(
            IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE_V2).c_str());
    load_time_data->SetString(
        "optInLink",
        l10n_util::GetStringFUTF16(IDS_SAFE_BROWSING_MALWARE_V2_REPORTING_AGREE,
                                   base::UTF8ToUTF16(privacy_link)));
    Profile* profile = Profile::FromBrowserContext(
       web_contents_->GetBrowserContext());
    if (profile->GetPrefs()->HasPrefPath(
            prefs::kSafeBrowsingExtendedReportingEnabled)) {
      reporting_checkbox_checked_ =
          IsPrefEnabled(prefs::kSafeBrowsingExtendedReportingEnabled);
    } else if (IsPrefEnabled(prefs::kSafeBrowsingReportingEnabled) ||
         IsPrefEnabled(prefs::kSafeBrowsingDownloadFeedbackEnabled)) {
      reporting_checkbox_checked_ = true;
    }
    load_time_data->SetBoolean(
        kBoxChecked, reporting_checkbox_checked_);
  }
}

void SafeBrowsingBlockingPageV3::PopulatePhishingLoadTimeData(
    base::DictionaryValue* load_time_data) {
  load_time_data->SetString("trialCondition", std::string());
  load_time_data->SetBoolean("phishing", true);
  load_time_data->SetString(
      "heading",
      l10n_util::GetStringUTF16(IDS_PHISHING_V3_HEADING));
  load_time_data->SetString(
      "primaryParagraph",
      l10n_util::GetStringFUTF16(
          IDS_PHISHING_V3_PRIMARY_PARAGRAPH,
          base::UTF8ToUTF16(url_.host())));
  load_time_data->SetString(
      "explanationParagraph",
      l10n_util::GetStringFUTF16(IDS_PHISHING_V3_EXPLANATION_PARAGRAPH,
                                 base::UTF8ToUTF16(url_.host())));
  load_time_data->SetString(
      "finalParagraph",
      l10n_util::GetStringUTF16(IDS_PHISHING_V3_PROCEED_PARAGRAPH));
}
