1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_ACTIONS_H_ 6 #define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_ACTIONS_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/memory/ref_counted_memory.h" 12 #include "base/time/time.h" 13 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/common/extensions/api/activity_log_private.h" 15 #include "sql/connection.h" 16 #include "sql/statement.h" 17 #include "sql/transaction.h" 18 #include "url/gurl.h" 19 20 namespace base { 21 class ListValue; 22 class DictionaryValue; 23 } 24 25 namespace rappor { 26 class RapporService; 27 } 28 29 namespace extensions { 30 31 // This is the interface for extension actions that are to be recorded in 32 // the activity log. 33 class Action : public base::RefCountedThreadSafe<Action> { 34 public: 35 // Types of log entries that can be stored. The numeric values are stored in 36 // the database, so keep them stable. Append values only. 37 enum ActionType { 38 ACTION_API_CALL = 0, 39 ACTION_API_EVENT = 1, 40 UNUSED_ACTION_API_BLOCKED = 2, // Not in use, but reserved for future. 41 ACTION_CONTENT_SCRIPT = 3, 42 ACTION_DOM_ACCESS = 4, 43 ACTION_DOM_EVENT = 5, 44 ACTION_WEB_REQUEST = 6, 45 ACTION_ANY = 1001, // Used for lookups of unspecified type. 46 }; 47 48 // The type of ad injection an action performed. Do not delete or reorder 49 // these metrics, as they are used in histogramming. 50 enum InjectionType { 51 // No ad injection occurred. 52 NO_AD_INJECTION = 0, 53 // A new ad was injected. 54 INJECTION_NEW_AD, 55 // An ad was removed. 56 INJECTION_REMOVED_AD, 57 // An ad was replaced. 58 INJECTION_REPLACED_AD, 59 // Something occurred which heuristically looks like an ad injection, but we 60 // didn't categorize it as such (likely because we didn't recognize it as 61 // an ad network). If our list is effective, this should be significantly 62 // lower than the non-LIKELY counterparts. 63 INJECTION_LIKELY_NEW_AD, 64 INJECTION_LIKELY_REPLACED_AD, 65 66 // Place any new injection types above this entry. 67 NUM_INJECTION_TYPES 68 }; 69 70 // The type of ad which was injected. 71 enum AdType { 72 AD_TYPE_NONE, 73 AD_TYPE_IFRAME, 74 AD_TYPE_EMBED, 75 AD_TYPE_ANCHOR, 76 77 // Place any new injection types above this entry. 78 NUM_AD_TYPES 79 }; 80 81 // A useful shorthand for methods that take or return collections of Action 82 // objects. 83 typedef std::vector<scoped_refptr<Action> > ActionVector; 84 85 // Creates a new activity log Action object. The extension_id and type 86 // fields are immutable. All other fields can be filled in with the 87 // accessors/mutators below. 88 Action(const std::string& extension_id, 89 const base::Time& time, 90 const ActionType action_type, 91 const std::string& api_name, 92 int64 action_id = -1); 93 94 // Creates and returns a mutable copy of an Action. 95 scoped_refptr<Action> Clone() const; 96 97 // Return the type of ad-injection performed in the |action|, or 98 // NO_AD_INJECTION if none was present. 99 // TODO(rdevlin.cronin): This isn't done. 100 // See crbug.com/357204. 101 InjectionType DidInjectAd(rappor::RapporService* rappor_service) const; 102 103 // The extension which caused this record to be generated. extension_id()104 const std::string& extension_id() const { return extension_id_; } 105 106 // The time the record was generated (or some approximation). time()107 const base::Time& time() const { return time_; } set_time(const base::Time & time)108 void set_time(const base::Time& time) { time_ = time; } 109 110 // The ActionType distinguishes different classes of actions that can be 111 // logged, and determines which other fields are expected to be filled in. action_type()112 ActionType action_type() const { return action_type_; } 113 114 // The specific API call used or accessed, for example "chrome.tabs.get". api_name()115 const std::string& api_name() const { return api_name_; } set_api_name(const std::string api_name)116 void set_api_name(const std::string api_name) { api_name_ = api_name; } 117 118 // Any applicable arguments. This might be null to indicate no data 119 // available (a distinct condition from an empty argument list). 120 // mutable_args() returns a pointer to the list stored in the Action which 121 // can be modified in place; if the list was null an empty list is created 122 // first. args()123 const base::ListValue* args() const { return args_.get(); } 124 void set_args(scoped_ptr<base::ListValue> args); 125 base::ListValue* mutable_args(); 126 127 // The URL of the page which was modified or accessed. page_url()128 const GURL& page_url() const { return page_url_; } 129 void set_page_url(const GURL& page_url); 130 131 // The title of the above page if available. page_title()132 const std::string& page_title() const { return page_title_; } set_page_title(const std::string & title)133 void set_page_title(const std::string& title) { page_title_ = title; } 134 135 // A URL which appears in the arguments of the API call, if present. arg_url()136 const GURL& arg_url() const { return arg_url_; } 137 void set_arg_url(const GURL& arg_url); 138 139 // Get or set a flag indicating whether the page or argument values above 140 // refer to incognito pages. page_incognito()141 bool page_incognito() const { return page_incognito_; } set_page_incognito(bool incognito)142 void set_page_incognito(bool incognito) { page_incognito_ = incognito; } arg_incognito()143 bool arg_incognito() const { return arg_incognito_; } set_arg_incognito(bool incognito)144 void set_arg_incognito(bool incognito) { arg_incognito_ = incognito; } 145 146 // A dictionary where any additional data can be stored. other()147 const base::DictionaryValue* other() const { return other_.get(); } 148 void set_other(scoped_ptr<base::DictionaryValue> other); 149 base::DictionaryValue* mutable_other(); 150 151 // An ID that identifies an action stored in the Activity Log database. If the 152 // action is not retrieved from the database, e.g., live stream, then the ID 153 // is set to -1. action_id()154 int64 action_id() const { return action_id_; } 155 156 // Helper methods for serializing and deserializing URLs into strings. If 157 // the URL is marked as incognito, then the string is prefixed with 158 // kIncognitoUrl ("<incognito>"). 159 std::string SerializePageUrl() const; 160 void ParsePageUrl(const std::string& url); 161 std::string SerializeArgUrl() const; 162 void ParseArgUrl(const std::string& url); 163 164 // Number of merged records for this action. count()165 int count() const { return count_; } set_count(int count)166 void set_count(int count) { count_ = count; } 167 168 // Flatten the activity's type-specific fields into an ExtensionActivity. 169 scoped_ptr<api::activity_log_private::ExtensionActivity> 170 ConvertToExtensionActivity(); 171 172 // Print an action as a regular string for debugging purposes. 173 virtual std::string PrintForDebug() const; 174 175 protected: 176 virtual ~Action(); 177 178 private: 179 friend class base::RefCountedThreadSafe<Action>; 180 181 // Returns true if a given |url| could be an ad. 182 bool UrlCouldBeAd(const GURL& url) const; 183 184 // Uploads the URL to RAPPOR (preserving privacy) if this might have been an 185 // ad injection. 186 void MaybeUploadUrl(rappor::RapporService* rappor_service) const; 187 188 // Checks an action that modified the src of an element for ad injection. 189 InjectionType CheckSrcModification() const; 190 // Checks an action with the appendChild API for ad injection. 191 // |ad_type_out| is populated with the type of ad which was injected, if there 192 // was an injection. 193 InjectionType CheckAppendChild(AdType* ad_type_out) const; 194 // Checks a DOM object (e.g. an appended child) for ad injection. 195 // |ad_type_out| is populated with the type of ad which was injected, if there 196 // was an injection. 197 InjectionType CheckDomObject(const base::DictionaryValue* object, 198 AdType* ad_type_out) const; 199 200 std::string extension_id_; 201 base::Time time_; 202 ActionType action_type_; 203 std::string api_name_; 204 scoped_ptr<base::ListValue> args_; 205 GURL page_url_; 206 std::string page_title_; 207 bool page_incognito_; 208 GURL arg_url_; 209 bool arg_incognito_; 210 scoped_ptr<base::DictionaryValue> other_; 211 int count_; 212 int64 action_id_; 213 214 DISALLOW_COPY_AND_ASSIGN(Action); 215 }; 216 217 // A comparator for Action class objects; this performs a lexicographic 218 // comparison of the fields of the Action object (in an unspecfied order). 219 // This can be used to use Action objects as keys in STL containers. 220 struct ActionComparator { 221 // Evaluates the comparison lhs < rhs. 222 bool operator()(const scoped_refptr<Action>& lhs, 223 const scoped_refptr<Action>& rhs) const; 224 }; 225 226 // Like ActionComparator, but ignores the time field and the action ID field in 227 // comparisons. 228 struct ActionComparatorExcludingTimeAndActionId { 229 // Evaluates the comparison lhs < rhs. 230 bool operator()(const scoped_refptr<Action>& lhs, 231 const scoped_refptr<Action>& rhs) const; 232 }; 233 234 } // namespace extensions 235 236 #endif // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_ACTIONS_H_ 237