12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/extensions/activity_log/activity_actions.h"
6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include <algorithm>  // for std::find.
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
10558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/command_line.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/format_macros.h"
12ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/json/json_string_value_serializer.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/macros.h"
15558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/memory/singleton.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/metrics/histogram.h"
17558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/strings/string_number_conversions.h"
18ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/strings/string_util.h"
195e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/values.h"
21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/extensions/activity_log/activity_action_constants.h"
220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/extensions/activity_log/ad_network_database.h"
23558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
24558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/browser/ui/browser.h"
25558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/common/chrome_switches.h"
260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/rappor/rappor_service.h"
27558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/public/browser/web_contents.h"
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/common/constants.h"
295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "extensions/common/dom_action_types.h"
30558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "sql/statement.h"
310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "url/gurl.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace constants = activity_log_constants;
34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace extensions {
360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
37ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace {
38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// The "Extensions.PossibleAdInjection2" metric uses different Rappor
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// parameters than the original metric.
410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst char* kExtensionAdInjectionRapporMetricName =
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    "Extensions.PossibleAdInjection2";
430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kBlinkSetAttributeEvent[] = "blinkSetAttribute";
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kBlinkAddElementEvent[] = "blinkAddElement";
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kIframe[] = "iframe";
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kAnchor[] = "a";
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kScript[] = "script";
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kSrc[] = "src";
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kHref[] = "href";
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
54ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochstd::string Serialize(const base::Value* value) {
55ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  std::string value_as_text;
56ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (!value) {
57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    value_as_text = "null";
58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  } else {
59ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    JSONStringValueSerializer serializer(&value_as_text);
60ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    serializer.SerializeAndOmitBinaryValues(*value);
61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return value_as_text;
63ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
64ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}  // namespace
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using api::activity_log_private::ExtensionActivity;
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Action::Action(const std::string& extension_id,
70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)               const base::Time& time,
71558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch               const ActionType action_type,
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               const std::string& api_name,
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               int64 action_id)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : extension_id_(extension_id),
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      time_(time),
76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      action_type_(action_type),
77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      api_name_(api_name),
78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      page_incognito_(false),
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      arg_incognito_(false),
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      count_(0),
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      action_id_(action_id) {}
82558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
83558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochAction::~Action() {}
84558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// TODO(mvrable): As an optimization, we might return this directly if the
86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// refcount is one.  However, there are likely to be other stray references in
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// many cases that will prevent this optimization.
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_refptr<Action> Action::Clone() const {
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_refptr<Action> clone(
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new Action(
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          extension_id(), time(), action_type(), api_name(), action_id()));
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (args())
93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    clone->set_args(make_scoped_ptr(args()->DeepCopy()));
94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  clone->set_page_url(page_url());
95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  clone->set_page_title(page_title());
96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  clone->set_page_incognito(page_incognito());
97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  clone->set_arg_url(arg_url());
98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  clone->set_arg_incognito(arg_incognito());
99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (other())
100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    clone->set_other(make_scoped_ptr(other()->DeepCopy()));
101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return clone;
102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1040529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochAction::InjectionType Action::DidInjectAd(
1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    rappor::RapporService* rappor_service) const {
1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MaybeUploadUrl(rappor_service);
1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // We should always have an AdNetworkDatabase, but, on the offchance we don't,
109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // don't crash in a release build.
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!AdNetworkDatabase::Get()) {
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    NOTREACHED();
1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return NO_AD_INJECTION;
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  AdType ad_type = AD_TYPE_NONE;
116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InjectionType injection_type = NO_AD_INJECTION;
1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (api_name_ == kBlinkSetAttributeEvent) {
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string element_name;
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string attr_name;
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (args_.get()) {
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      args_->GetString(0u, &element_name);
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      args_->GetString(1u, &attr_name);
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (attr_name == kSrc) {
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      if (element_name == kIframe)
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        ad_type = AD_TYPE_IFRAME;
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      else if (element_name == kScript)
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        ad_type = AD_TYPE_SCRIPT;
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    } else if (element_name == kAnchor && attr_name == kHref) {
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ad_type = AD_TYPE_ANCHOR;
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (ad_type != AD_TYPE_NONE)
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      injection_type = CheckAttrModification();
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else if (api_name_ == kBlinkAddElementEvent) {
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string element_name;
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (args_.get())
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      args_->GetString(0u, &element_name);
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (element_name == kIframe)
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ad_type = AD_TYPE_IFRAME;
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    else if (element_name == kAnchor)
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ad_type = AD_TYPE_ANCHOR;
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else if (element_name == kScript)
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ad_type = AD_TYPE_SCRIPT;
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (ad_type != AD_TYPE_NONE)
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      injection_type = CheckElementAddition();
1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (injection_type != NO_AD_INJECTION) {
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION(
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "Extensions.AdInjection.AdType", ad_type, Action::NUM_AD_TYPES);
154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return injection_type;
1570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void Action::set_args(scoped_ptr<base::ListValue> args) {
160558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  args_.reset(args.release());
161558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
162558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::ListValue* Action::mutable_args() {
164558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!args_.get()) {
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    args_.reset(new base::ListValue());
166558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
167558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return args_.get();
168558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
169558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
170558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid Action::set_page_url(const GURL& page_url) {
171558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  page_url_ = page_url;
172558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
173558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
174558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid Action::set_arg_url(const GURL& arg_url) {
175558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  arg_url_ = arg_url;
176558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
177558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void Action::set_other(scoped_ptr<base::DictionaryValue> other) {
179558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  other_.reset(other.release());
180558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
181558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::DictionaryValue* Action::mutable_other() {
183558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!other_.get()) {
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    other_.reset(new base::DictionaryValue());
185558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
186558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return other_.get();
187558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
188558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
189ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstd::string Action::SerializePageUrl() const {
190ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return (page_incognito() ? constants::kIncognitoUrl : "") + page_url().spec();
191ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
192ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
193ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid Action::ParsePageUrl(const std::string& url) {
194ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  set_page_incognito(StartsWithASCII(url, constants::kIncognitoUrl, true));
195ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (page_incognito())
196ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    set_page_url(GURL(url.substr(strlen(constants::kIncognitoUrl))));
197ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  else
198ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    set_page_url(GURL(url));
199ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
200ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
201ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstd::string Action::SerializeArgUrl() const {
202ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  return (arg_incognito() ? constants::kIncognitoUrl : "") + arg_url().spec();
203ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
204ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
205ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid Action::ParseArgUrl(const std::string& url) {
206ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  set_arg_incognito(StartsWithASCII(url, constants::kIncognitoUrl, true));
207ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (arg_incognito())
208ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    set_arg_url(GURL(url.substr(strlen(constants::kIncognitoUrl))));
209ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  else
210ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    set_arg_url(GURL(url));
211ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
212ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
213558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_ptr<ExtensionActivity> Action::ConvertToExtensionActivity() {
214558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  scoped_ptr<ExtensionActivity> result(new ExtensionActivity);
215558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // We do this translation instead of using the same enum because the database
2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // values need to be stable; this allows us to change the extension API
2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // without affecting the database.
219558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  switch (action_type()) {
220558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    case ACTION_API_CALL:
2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      result->activity_type = ExtensionActivity::ACTIVITY_TYPE_API_CALL;
222558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      break;
2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case ACTION_API_EVENT:
2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      result->activity_type = ExtensionActivity::ACTIVITY_TYPE_API_EVENT;
225558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      break;
226558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    case ACTION_CONTENT_SCRIPT:
2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      result->activity_type = ExtensionActivity::ACTIVITY_TYPE_CONTENT_SCRIPT;
2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case ACTION_DOM_ACCESS:
2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      result->activity_type = ExtensionActivity::ACTIVITY_TYPE_DOM_ACCESS;
2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case ACTION_DOM_EVENT:
2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      result->activity_type = ExtensionActivity::ACTIVITY_TYPE_DOM_EVENT;
2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case ACTION_WEB_REQUEST:
2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      result->activity_type = ExtensionActivity::ACTIVITY_TYPE_WEB_REQUEST;
2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case UNUSED_ACTION_API_BLOCKED:
239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    case ACTION_ANY:
240424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    default:
241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      // This shouldn't be reached, but some people might have old or otherwise
242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      // weird db entries. Treat it like an API call if that happens.
2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      result->activity_type = ExtensionActivity::ACTIVITY_TYPE_API_CALL;
244558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      break;
2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
246558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  result->extension_id.reset(new std::string(extension_id()));
2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  result->time.reset(new double(time().ToJsTime()));
2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  result->count.reset(new double(count()));
2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  result->api_call.reset(new std::string(api_name()));
2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  result->args.reset(new std::string(Serialize(args())));
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (action_id() != -1)
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result->activity_id.reset(
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new std::string(base::StringPrintf("%" PRId64, action_id())));
2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (page_url().is_valid()) {
2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (!page_title().empty())
2573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      result->page_title.reset(new std::string(page_title()));
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    result->page_url.reset(new std::string(SerializePageUrl()));
259558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (arg_url().is_valid())
26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    result->arg_url.reset(new std::string(SerializeArgUrl()));
262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (other()) {
264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scoped_ptr<ExtensionActivity::Other> other_field(
265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        new ExtensionActivity::Other);
266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    bool prerender;
267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (other()->GetBooleanWithoutPathExpansion(constants::kActionPrerender,
268d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                                &prerender)) {
269d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      other_field->prerender.reset(new bool(prerender));
270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::DictionaryValue* web_request;
272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (other()->GetDictionaryWithoutPathExpansion(constants::kActionWebRequest,
273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                                   &web_request)) {
274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      other_field->web_request.reset(new std::string(
275d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          ActivityLogPolicy::Util::Serialize(web_request)));
276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    std::string extra;
278d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (other()->GetStringWithoutPathExpansion(constants::kActionExtra, &extra))
279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      other_field->extra.reset(new std::string(extra));
280d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    int dom_verb;
281d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (other()->GetIntegerWithoutPathExpansion(constants::kActionDomVerb,
282d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                                                &dom_verb)) {
283d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      switch (static_cast<DomActionType::Type>(dom_verb)) {
284d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        case DomActionType::GETTER:
285d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_GETTER;
286d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          break;
287d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        case DomActionType::SETTER:
288d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_SETTER;
289d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          break;
290d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        case DomActionType::METHOD:
291d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_METHOD;
292d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          break;
293d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        case DomActionType::INSERTED:
294d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_INSERTED;
295d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          break;
296d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        case DomActionType::XHR:
297d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_XHR;
298d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          break;
299d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        case DomActionType::WEBREQUEST:
300d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_WEBREQUEST;
301d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          break;
302d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        case DomActionType::MODIFIED:
303d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_MODIFIED;
304d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          break;
305d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        default:
306d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_NONE;
307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      }
308d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    } else {
309d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      other_field->dom_verb = ExtensionActivity::Other::DOM_VERB_NONE;
310d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    }
311d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    result->other.reset(other_field.release());
312d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
313558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
314ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return result.Pass();
315ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
316ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
317ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochstd::string Action::PrintForDebug() const {
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string result = base::StringPrintf("ACTION ID=%" PRId64, action_id());
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  result += " EXTENSION ID=" + extension_id() + " CATEGORY=";
320ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  switch (action_type_) {
321ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case ACTION_API_CALL:
322ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      result += "api_call";
323ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      break;
324ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case ACTION_API_EVENT:
325ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      result += "api_event_callback";
326ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      break;
327ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case ACTION_WEB_REQUEST:
328ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      result += "webrequest";
329ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      break;
330ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case ACTION_CONTENT_SCRIPT:
331ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      result += "content_script";
332ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      break;
3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case UNUSED_ACTION_API_BLOCKED:
3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      // This is deprecated.
335ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      result += "api_blocked";
336ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      break;
337ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case ACTION_DOM_EVENT:
338ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      result += "dom_event";
339ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      break;
340ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    case ACTION_DOM_ACCESS:
341ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      result += "dom_access";
342ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      break;
343ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    default:
344ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      result += base::StringPrintf("type%d", static_cast<int>(action_type_));
345ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
347ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  result += " API=" + api_name_;
348ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (args_.get()) {
349ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    result += " ARGS=" + Serialize(args_.get());
350ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
351ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (page_url_.is_valid()) {
352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (page_incognito_)
353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      result += " PAGE_URL=(incognito)" + page_url_.spec();
354a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    else
355a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      result += " PAGE_URL=" + page_url_.spec();
356ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
357558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!page_title_.empty()) {
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::StringValue title(page_title_);
359558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    result += " PAGE_TITLE=" + Serialize(&title);
360558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
361ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (arg_url_.is_valid()) {
362a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (arg_incognito_)
363a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      result += " ARG_URL=(incognito)" + arg_url_.spec();
364a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    else
365a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      result += " ARG_URL=" + arg_url_.spec();
366ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
367ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (other_.get()) {
368ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    result += " OTHER=" + Serialize(other_.get());
369ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
370ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  result += base::StringPrintf(" COUNT=%d", count_);
372ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return result;
373ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
374ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool Action::UrlCouldBeAd(const GURL& url) const {
376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Ads can only be valid urls that don't match the page's host (linking to the
377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // current page should be considered valid use), and aren't local to the
378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // extension.
379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return url.is_valid() &&
380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         !url.is_empty() &&
381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         url.host() != page_url_.host() &&
382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         !url.SchemeIs(kExtensionScheme);
383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
3840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void Action::MaybeUploadUrl(rappor::RapporService* rappor_service) const {
386cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Don't bother recording if the url is innocuous (or no |rappor_service|).
387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!rappor_service)
3880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
3890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GURL url;
391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (api_name_ == kBlinkSetAttributeEvent) {
393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string element_name;
394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string attr_name;
395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string url_string;
396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (args_.get()) {
397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      args_->GetString(0u, &element_name);
398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      args_->GetString(1u, &attr_name);
399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (element_name == kIframe && attr_name == kSrc) {
401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      args_->GetString(3u, &url_string);
402116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      url = GURL(url_string);
403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    } else if (element_name == kAnchor && attr_name == kHref) {
404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      args_->GetString(3u, &url_string);
405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      url = GURL(url_string);
406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else if (api_name_ == kBlinkAddElementEvent) {
408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string element_name;
409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string url_string;
410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (args_.get())
411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      args_->GetString(0u, &element_name);
412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (element_name == kIframe) {
413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      args_->GetString(1u, &url_string);
414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      url = GURL(url_string);
415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    } else if (element_name == kAnchor) {
416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      args_->GetString(1u, &url_string);
417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      url = GURL(url_string);
4180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
4190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!UrlCouldBeAd(url))
4220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
4230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Record the URL - an ad *may* have been injected.
4250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rappor_service->RecordSample(kExtensionAdInjectionRapporMetricName,
4260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               rappor::ETLD_PLUS_ONE_RAPPOR_TYPE,
427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               url.host());
4280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
4290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
430116680a4aac90f2aa7413d9095a592090648e557Ben MurdochAction::InjectionType Action::CheckAttrModification() const {
431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (api_name_ != kBlinkSetAttributeEvent)
432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return NO_AD_INJECTION;
433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const AdNetworkDatabase* database = AdNetworkDatabase::Get();
435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  GURL prev_url;
437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string prev_url_string;
438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (args_.get() && args_->GetString(2u, &prev_url_string))
439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    prev_url = GURL(prev_url_string);
440cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GURL new_url;
442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string new_url_string;
443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (args_.get() && args_->GetString(3u, &new_url_string))
444116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    new_url = GURL(new_url_string);
445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool new_url_could_be_ad = UrlCouldBeAd(new_url);
447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool prev_url_valid = prev_url.is_valid() && !prev_url.is_empty();
448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool injected_ad = new_url_could_be_ad && database->IsAdNetwork(new_url);
450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool replaced_ad = prev_url_valid && database->IsAdNetwork(prev_url);
451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (injected_ad && replaced_ad)
453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return INJECTION_REPLACED_AD;
454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (injected_ad)
455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return INJECTION_NEW_AD;
456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (replaced_ad)
457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return INJECTION_REMOVED_AD;
458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If the extension modified the URL with an external, valid URL then there's
460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // a good chance it's ad injection. Log it as a likely one, which also helps
461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // us determine the effectiveness of our IsAdNetwork() recognition.
462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (new_url_could_be_ad) {
463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (prev_url_valid)
464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return INJECTION_LIKELY_REPLACED_AD;
465cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return INJECTION_LIKELY_NEW_AD;
466cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
467cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return NO_AD_INJECTION;
4690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
4700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
471116680a4aac90f2aa7413d9095a592090648e557Ben MurdochAction::InjectionType Action::CheckElementAddition() const {
4725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK_EQ(kBlinkAddElementEvent, api_name_);
4730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GURL url;
475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string url_string;
476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (args_.get() && args_->GetString(1u, &url_string))
477116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    url = GURL(url_string);
478116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
479116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (UrlCouldBeAd(url)) {
480116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (AdNetworkDatabase::Get()->IsAdNetwork(url))
481116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return INJECTION_NEW_AD;
482116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // If the extension injected an URL which is not local to itself or the
483116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // page, there is a good chance it could be a new ad, and our database
484116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // missed it.
485116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return INJECTION_LIKELY_NEW_AD;
486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
487cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return NO_AD_INJECTION;
4880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
4890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool ActionComparator::operator()(
4913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const scoped_refptr<Action>& lhs,
4923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const scoped_refptr<Action>& rhs) const {
4933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (lhs->time() != rhs->time())
4943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return lhs->time() < rhs->time();
4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else if (lhs->action_id() != rhs->action_id())
4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return lhs->action_id() < rhs->action_id();
4973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  else
4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return ActionComparatorExcludingTimeAndActionId()(lhs, rhs);
4993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ActionComparatorExcludingTimeAndActionId::operator()(
5023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const scoped_refptr<Action>& lhs,
5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const scoped_refptr<Action>& rhs) const {
5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (lhs->extension_id() != rhs->extension_id())
5053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return lhs->extension_id() < rhs->extension_id();
5063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (lhs->action_type() != rhs->action_type())
5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return lhs->action_type() < rhs->action_type();
5083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (lhs->api_name() != rhs->api_name())
5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return lhs->api_name() < rhs->api_name();
5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // args might be null; treat a null value as less than all non-null values,
5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // including the empty string.
5133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!lhs->args() && rhs->args())
5143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return true;
5153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (lhs->args() && !rhs->args())
5163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (lhs->args() && rhs->args()) {
5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::string lhs_args = ActivityLogPolicy::Util::Serialize(lhs->args());
5193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::string rhs_args = ActivityLogPolicy::Util::Serialize(rhs->args());
5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (lhs_args != rhs_args)
5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return lhs_args < rhs_args;
5223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
5233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Compare URLs as strings, and treat the incognito flag as a separate field.
5253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (lhs->page_url().spec() != rhs->page_url().spec())
5263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return lhs->page_url().spec() < rhs->page_url().spec();
5273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (lhs->page_incognito() != rhs->page_incognito())
5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return lhs->page_incognito() < rhs->page_incognito();
5293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (lhs->page_title() != rhs->page_title())
5313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return lhs->page_title() < rhs->page_title();
5323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (lhs->arg_url().spec() != rhs->arg_url().spec())
5343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return lhs->arg_url().spec() < rhs->arg_url().spec();
5353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (lhs->arg_incognito() != rhs->arg_incognito())
5363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return lhs->arg_incognito() < rhs->arg_incognito();
5373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // other is treated much like the args field.
5393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!lhs->other() && rhs->other())
5403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return true;
5413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (lhs->other() && !rhs->other())
5423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
5433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (lhs->other() && rhs->other()) {
5443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::string lhs_other = ActivityLogPolicy::Util::Serialize(lhs->other());
5453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    std::string rhs_other = ActivityLogPolicy::Util::Serialize(rhs->other());
5463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (lhs_other != rhs_other)
5473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return lhs_other < rhs_other;
5483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
5493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // All fields compare as equal if this point is reached.
5513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return false;
5523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
554ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}  // namespace extensions
555