Home | History | Annotate | Download | only in activity_log
      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.
    104   const std::string& extension_id() const { return extension_id_; }
    105 
    106   // The time the record was generated (or some approximation).
    107   const base::Time& time() const { return 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.
    112   ActionType action_type() const { return action_type_; }
    113 
    114   // The specific API call used or accessed, for example "chrome.tabs.get".
    115   const std::string& api_name() const { return 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.
    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.
    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.
    132   const std::string& page_title() const { return page_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.
    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.
    141   bool page_incognito() const { return page_incognito_; }
    142   void set_page_incognito(bool incognito) { page_incognito_ = incognito; }
    143   bool arg_incognito() const { return arg_incognito_; }
    144   void set_arg_incognito(bool incognito) { arg_incognito_ = incognito; }
    145 
    146   // A dictionary where any additional data can be stored.
    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.
    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.
    165   int count() const { return 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