blob: e90065418c9efce7b53e5f95ccb811e8bd175a5a [file] [log] [blame]
// Copyright (c) 2013 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.
#ifndef CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_ACTIONS_H_
#define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_ACTIONS_H_
#include <string>
#include <vector>
#include "base/memory/ref_counted_memory.h"
#include "base/time/time.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/activity_log_private.h"
#include "sql/connection.h"
#include "sql/statement.h"
#include "sql/transaction.h"
#include "url/gurl.h"
namespace base {
class ListValue;
class DictionaryValue;
}
namespace rappor {
class RapporService;
}
namespace extensions {
// This is the interface for extension actions that are to be recorded in
// the activity log.
class Action : public base::RefCountedThreadSafe<Action> {
public:
// Types of log entries that can be stored. The numeric values are stored in
// the database, so keep them stable. Append values only.
enum ActionType {
ACTION_API_CALL = 0,
ACTION_API_EVENT = 1,
UNUSED_ACTION_API_BLOCKED = 2, // Not in use, but reserved for future.
ACTION_CONTENT_SCRIPT = 3,
ACTION_DOM_ACCESS = 4,
ACTION_DOM_EVENT = 5,
ACTION_WEB_REQUEST = 6,
ACTION_ANY = 1001, // Used for lookups of unspecified type.
};
// The type of ad injection an action performed. Do not delete or reorder
// these metrics, as they are used in histogramming.
enum InjectionType {
// No ad injection occurred.
NO_AD_INJECTION = 0,
// A new ad was injected.
INJECTION_NEW_AD,
// An ad was removed.
INJECTION_REMOVED_AD,
// An ad was replaced.
INJECTION_REPLACED_AD,
// Something occurred which heuristically looks like an ad injection, but we
// didn't categorize it as such (likely because we didn't recognize it as
// an ad network). If our list is effective, this should be significantly
// lower than the non-LIKELY counterparts.
INJECTION_LIKELY_NEW_AD,
INJECTION_LIKELY_REPLACED_AD,
// Place any new injection types above this entry.
NUM_INJECTION_TYPES
};
// The type of ad which was injected.
enum AdType {
AD_TYPE_NONE,
AD_TYPE_IFRAME,
AD_TYPE_EMBED,
AD_TYPE_ANCHOR,
// Place any new injection types above this entry.
NUM_AD_TYPES
};
// A useful shorthand for methods that take or return collections of Action
// objects.
typedef std::vector<scoped_refptr<Action> > ActionVector;
// Creates a new activity log Action object. The extension_id and type
// fields are immutable. All other fields can be filled in with the
// accessors/mutators below.
Action(const std::string& extension_id,
const base::Time& time,
const ActionType action_type,
const std::string& api_name,
int64 action_id = -1);
// Creates and returns a mutable copy of an Action.
scoped_refptr<Action> Clone() const;
// Return the type of ad-injection performed in the |action|, or
// NO_AD_INJECTION if none was present.
// TODO(rdevlin.cronin): This isn't done.
// See crbug.com/357204.
InjectionType DidInjectAd(rappor::RapporService* rappor_service) const;
// The extension which caused this record to be generated.
const std::string& extension_id() const { return extension_id_; }
// The time the record was generated (or some approximation).
const base::Time& time() const { return time_; }
void set_time(const base::Time& time) { time_ = time; }
// The ActionType distinguishes different classes of actions that can be
// logged, and determines which other fields are expected to be filled in.
ActionType action_type() const { return action_type_; }
// The specific API call used or accessed, for example "chrome.tabs.get".
const std::string& api_name() const { return api_name_; }
void set_api_name(const std::string api_name) { api_name_ = api_name; }
// Any applicable arguments. This might be null to indicate no data
// available (a distinct condition from an empty argument list).
// mutable_args() returns a pointer to the list stored in the Action which
// can be modified in place; if the list was null an empty list is created
// first.
const base::ListValue* args() const { return args_.get(); }
void set_args(scoped_ptr<base::ListValue> args);
base::ListValue* mutable_args();
// The URL of the page which was modified or accessed.
const GURL& page_url() const { return page_url_; }
void set_page_url(const GURL& page_url);
// The title of the above page if available.
const std::string& page_title() const { return page_title_; }
void set_page_title(const std::string& title) { page_title_ = title; }
// A URL which appears in the arguments of the API call, if present.
const GURL& arg_url() const { return arg_url_; }
void set_arg_url(const GURL& arg_url);
// Get or set a flag indicating whether the page or argument values above
// refer to incognito pages.
bool page_incognito() const { return page_incognito_; }
void set_page_incognito(bool incognito) { page_incognito_ = incognito; }
bool arg_incognito() const { return arg_incognito_; }
void set_arg_incognito(bool incognito) { arg_incognito_ = incognito; }
// A dictionary where any additional data can be stored.
const base::DictionaryValue* other() const { return other_.get(); }
void set_other(scoped_ptr<base::DictionaryValue> other);
base::DictionaryValue* mutable_other();
// An ID that identifies an action stored in the Activity Log database. If the
// action is not retrieved from the database, e.g., live stream, then the ID
// is set to -1.
int64 action_id() const { return action_id_; }
// Helper methods for serializing and deserializing URLs into strings. If
// the URL is marked as incognito, then the string is prefixed with
// kIncognitoUrl ("<incognito>").
std::string SerializePageUrl() const;
void ParsePageUrl(const std::string& url);
std::string SerializeArgUrl() const;
void ParseArgUrl(const std::string& url);
// Number of merged records for this action.
int count() const { return count_; }
void set_count(int count) { count_ = count; }
// Flatten the activity's type-specific fields into an ExtensionActivity.
scoped_ptr<api::activity_log_private::ExtensionActivity>
ConvertToExtensionActivity();
// Print an action as a regular string for debugging purposes.
virtual std::string PrintForDebug() const;
protected:
virtual ~Action();
private:
friend class base::RefCountedThreadSafe<Action>;
// Returns true if a given |url| could be an ad.
bool UrlCouldBeAd(const GURL& url) const;
// Uploads the URL to RAPPOR (preserving privacy) if this might have been an
// ad injection.
void MaybeUploadUrl(rappor::RapporService* rappor_service) const;
// Checks an action that modified the src or href of an element for ad
// injection.
InjectionType CheckAttrModification() const;
// Checks an action that adds an element for ad injection.
InjectionType CheckElementAddition() const;
std::string extension_id_;
base::Time time_;
ActionType action_type_;
std::string api_name_;
scoped_ptr<base::ListValue> args_;
GURL page_url_;
std::string page_title_;
bool page_incognito_;
GURL arg_url_;
bool arg_incognito_;
scoped_ptr<base::DictionaryValue> other_;
int count_;
int64 action_id_;
DISALLOW_COPY_AND_ASSIGN(Action);
};
// A comparator for Action class objects; this performs a lexicographic
// comparison of the fields of the Action object (in an unspecfied order).
// This can be used to use Action objects as keys in STL containers.
struct ActionComparator {
// Evaluates the comparison lhs < rhs.
bool operator()(const scoped_refptr<Action>& lhs,
const scoped_refptr<Action>& rhs) const;
};
// Like ActionComparator, but ignores the time field and the action ID field in
// comparisons.
struct ActionComparatorExcludingTimeAndActionId {
// Evaluates the comparison lhs < rhs.
bool operator()(const scoped_refptr<Action>& lhs,
const scoped_refptr<Action>& rhs) const;
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_ACTIONS_H_