Commit 74893ffe authored by cthomp@chromium.org's avatar cthomp@chromium.org

Experience sampling instrumentation for SSL and Safe Browsing interstitials

This CL instruments the interstitial pages to generate the experience sampling API onDecision event.

BUG=384635

Review URL: https://codereview.chromium.org/399773002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@288177 0039d316-1c4b-4281-b951-d872f2087c98
parent 546e2e69
......@@ -61,7 +61,7 @@ void ExperienceSamplingEvent::CreateUserDecisionEvent(
const std::string& decision_name) {
// Check if this is from an incognito context. If it is, don't create and send
// any events.
if (browser_context_->IsOffTheRecord())
if (browser_context_ && browser_context_->IsOffTheRecord())
return;
api::experience_sampling_private::UserDecision decision;
decision.name = decision_name;
......@@ -74,19 +74,23 @@ void ExperienceSamplingEvent::CreateUserDecisionEvent(
args->Append(decision.ToValue().release());
scoped_ptr<Event> event(new Event(
api::experience_sampling_private::OnDecision::kEventName, args.Pass()));
EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass());
EventRouter* router = EventRouter::Get(browser_context_);
if (router)
router->BroadcastEvent(event.Pass());
}
void ExperienceSamplingEvent::CreateOnDisplayedEvent() {
// Check if this is from an incognito context. If it is, don't create and send
// any events.
if (browser_context_->IsOffTheRecord())
if (browser_context_ && browser_context_->IsOffTheRecord())
return;
scoped_ptr<base::ListValue> args(new base::ListValue());
args->Append(ui_element_.ToValue().release());
scoped_ptr<Event> event(new Event(
api::experience_sampling_private::OnDisplayed::kEventName, args.Pass()));
EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass());
EventRouter* router = EventRouter::Get(browser_context_);
if (router)
router->BroadcastEvent(event.Pass());
}
} // namespace extensions
......@@ -47,6 +47,10 @@
#include "ui/base/webui/jstemplate_builder.h"
#include "ui/base/webui/web_ui_util.h"
#if defined(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/api/experience_sampling_private/experience_sampling.h"
#endif
using base::UserMetricsAction;
using content::BrowserThread;
using content::InterstitialPage;
......@@ -54,6 +58,10 @@ using content::OpenURLParams;
using content::Referrer;
using content::WebContents;
#if defined(ENABLE_EXTENSIONS)
using extensions::ExperienceSamplingEvent;
#endif
namespace {
// For malware interstitial pages, we link the problematic URL to Google's
......@@ -104,6 +112,15 @@ const char kNavigatedAwayMetaCommand[] = "closed";
const char kBoxChecked[] = "boxchecked";
const char kDisplayCheckBox[] = "displaycheckbox";
// Constants for the Experience Sampling instrumentation.
#if defined(ENABLE_EXTENSIONS)
const char kEventNameMalware[] = "safebrowsing_interstitial_";
const char kEventNamePhishing[] = "phishing_interstitial_";
const char kEventNameMalwareAndPhishing[] =
"malware_and_phishing_interstitial_";
const char kEventNameOther[] = "safebrowsing_other_interstitial_";
#endif
base::LazyInstance<SafeBrowsingBlockingPage::UnsafeResourceMap>
g_unsafe_resource_map = LAZY_INSTANCE_INITIALIZER;
......@@ -295,6 +312,32 @@ SafeBrowsingBlockingPage::SafeBrowsingBlockingPage(
malware_details_ = MalwareDetails::NewMalwareDetails(
ui_manager_, web_contents, unsafe_resources[0]);
}
#if defined(ENABLE_EXTENSIONS)
// ExperienceSampling: Set up new sampling event for this interstitial.
// This needs to handle all types of warnings this interstitial can show.
std::string event_name;
switch (interstitial_type_) {
case TYPE_MALWARE_AND_PHISHING:
event_name = kEventNameMalwareAndPhishing;
break;
case TYPE_MALWARE:
event_name = kEventNameMalware;
break;
case TYPE_PHISHING:
event_name = kEventNamePhishing;
break;
default:
event_name = kEventNameOther;
break;
}
sampling_event_.reset(new ExperienceSamplingEvent(
event_name,
url_,
web_contents_->GetLastCommittedURL(),
web_contents_->GetBrowserContext()));
#endif
// Creating interstitial_page_ without showing it leaks memory, so don't
// create it here.
}
......@@ -328,6 +371,10 @@ void SafeBrowsingBlockingPage::CommandReceived(const std::string& cmd) {
// User pressed "Learn more".
GURL url(interstitial_type_ == TYPE_PHISHING ?
kLearnMorePhishingUrlV2 : kLearnMoreMalwareUrlV2);
#if defined(ENABLE_EXTENSIONS)
if (sampling_event_.get())
sampling_event_->set_has_viewed_learn_more(true);
#endif
OpenURLParams params(
url, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_LINK, false);
web_contents_->OpenURL(params);
......@@ -441,6 +488,12 @@ void SafeBrowsingBlockingPage::CommandReceived(const std::string& cmd) {
// 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.
#if defined(ENABLE_EXTENSIONS)
// ExperienceSampling: We track that the user expanded the details.
if (sampling_event_.get())
sampling_event_->set_has_viewed_details(true);
#endif
return;
}
......@@ -504,6 +557,12 @@ void SafeBrowsingBlockingPage::OnProceed() {
unsafe_resource_map->erase(iter);
}
#if defined(ENABLE_EXTENSIONS)
// ExperienceSampling: Notify that user decided to proceed.
if (sampling_event_.get())
sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kProceed);
#endif
// Now that this interstitial is gone, we can show the new one.
if (blocking_page)
blocking_page->Show();
......@@ -560,6 +619,13 @@ void SafeBrowsingBlockingPage::OnDontProceed() {
navigation_entry_index_to_remove_));
navigation_entry_index_to_remove_ = -1;
}
#if defined(ENABLE_EXTENSIONS)
// ExperienceSampling: Notify that user decided to go back.
// This also occurs if the user navigates away or closes the tab.
if (sampling_event_.get())
sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kDeny);
#endif
}
void SafeBrowsingBlockingPage::OnGotHistoryCount(bool success,
......
......@@ -53,6 +53,12 @@ class InterstitialPage;
class WebContents;
}
#if defined(ENABLE_EXTENSIONS)
namespace extensions {
class ExperienceSamplingEvent;
}
#endif
class SafeBrowsingBlockingPage : public content::InterstitialPageDelegate {
public:
typedef SafeBrowsingUIManager::UnsafeResource UnsafeResource;
......@@ -233,6 +239,11 @@ class SafeBrowsingBlockingPage : public content::InterstitialPageDelegate {
int num_visits_;
base::CancelableTaskTracker request_tracker_;
private:
#if defined(ENABLE_EXTENSIONS)
scoped_ptr<extensions::ExperienceSamplingEvent> sampling_event_;
#endif
DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPage);
};
......
......@@ -51,6 +51,10 @@
#include "chrome/browser/captive_portal/captive_portal_service_factory.h"
#endif
#if defined(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/api/experience_sampling_private/experience_sampling.h"
#endif
#if defined(OS_WIN)
#include "base/base_paths_win.h"
#include "base/path_service.h"
......@@ -70,8 +74,19 @@ using content::InterstitialPage;
using content::NavigationController;
using content::NavigationEntry;
#if defined(ENABLE_EXTENSIONS)
using extensions::ExperienceSamplingEvent;
#endif
namespace {
// Constants for the Experience Sampling instrumentation.
#if defined(ENABLE_EXTENSIONS)
const char kEventNameBase[] = "ssl_interstitial_";
const char kEventNotOverridable[] = "notoverridable_";
const char kEventOverridable[] = "overridable_";
#endif
// Events for UMA. Do not reorder or change!
enum SSLBlockingPageEvent {
SHOW_ALL,
......@@ -329,6 +344,21 @@ SSLBlockingPage::SSLBlockingPage(
content::Source<Profile>(profile));
#endif
#if defined(ENABLE_EXTENSIONS)
// ExperienceSampling: Set up new sampling event for this interstitial.
std::string event_name(kEventNameBase);
if (overridable_ && !strict_enforcement_)
event_name.append(kEventOverridable);
else
event_name.append(kEventNotOverridable);
event_name.append(net::ErrorToString(cert_error_));
sampling_event_.reset(new ExperienceSamplingEvent(
event_name,
request_url_,
web_contents_->GetLastCommittedURL(),
web_contents_->GetBrowserContext()));
#endif
// Creating an interstitial without showing (e.g. from chrome://interstitials)
// it leaks memory, so don't create it here.
}
......@@ -486,6 +516,10 @@ void SSLBlockingPage::CommandReceived(const std::string& command) {
}
case CMD_MORE: {
RecordSSLBlockingPageEventStats(MORE);
#if defined(ENABLE_EXTENSIONS)
if (sampling_event_.get())
sampling_event_->set_has_viewed_details(true);
#endif
break;
}
case CMD_RELOAD: {
......@@ -496,6 +530,10 @@ void SSLBlockingPage::CommandReceived(const std::string& command) {
case CMD_HELP: {
content::NavigationController::LoadURLParams help_page_params(GURL(
"https://support.google.com/chrome/answer/4454607"));
#if defined(ENABLE_EXTENSIONS)
if (sampling_event_.get())
sampling_event_->set_has_viewed_learn_more(true);
#endif
web_contents_->GetController().LoadURLWithParams(help_page_params);
break;
}
......@@ -526,6 +564,11 @@ void SSLBlockingPage::OnProceed() {
captive_portal_probe_completed_,
captive_portal_no_response_,
captive_portal_detected_);
#if defined(ENABLE_EXTENSIONS)
// ExperienceSampling: Notify that user decided to proceed.
if (sampling_event_.get())
sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kProceed);
#endif
// Accepting the certificate resumes the loading of the page.
NotifyAllowCertificate();
}
......@@ -540,6 +583,12 @@ void SSLBlockingPage::OnDontProceed() {
captive_portal_probe_completed_,
captive_portal_no_response_,
captive_portal_detected_);
#if defined(ENABLE_EXTENSIONS)
// ExperienceSampling: Notify that user decided to not proceed.
// This also occurs if the user navigates away or closes the tab.
if (sampling_event_.get())
sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kDeny);
#endif
NotifyDenyCertificate();
}
......
......@@ -26,6 +26,12 @@ class InterstitialPage;
class WebContents;
}
#if defined(ENABLE_EXTENSIONS)
namespace extensions {
class ExperienceSamplingEvent;
}
#endif
// This class is responsible for showing/hiding the interstitial page that is
// shown when a certificate error happens.
// It deletes itself when the interstitial page is closed.
......@@ -121,6 +127,14 @@ class SSLBlockingPage : public content::InterstitialPageDelegate,
// Was a captive portal detected?
bool captive_portal_detected_;
// For the FieldTrial: this contains the name of the condition.
std::string trial_condition_;
#if defined(ENABLE_EXTENSIONS)
// For Chrome Experience Sampling Platform: this maintains event state.
scoped_ptr<extensions::ExperienceSamplingEvent> sampling_event_;
#endif
content::NotificationRegistrar registrar_;
DISALLOW_COPY_AND_ASSIGN(SSLBlockingPage);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment