summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormvrable@chromium.org <mvrable@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-26 22:53:39 +0000
committermvrable@chromium.org <mvrable@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-26 22:53:39 +0000
commit6d792d52403a3770e9f0caccec9d09879a9e144e (patch)
treed93c3a8e376f5404ffcd6446461167ed9dec07b1
parent0e33a9e516ac2e7a815091d6eddabc877271e3e6 (diff)
downloadchromium_src-6d792d52403a3770e9f0caccec9d09879a9e144e.zip
chromium_src-6d792d52403a3770e9f0caccec9d09879a9e144e.tar.gz
chromium_src-6d792d52403a3770e9f0caccec9d09879a9e144e.tar.bz2
Extension activity log database refactoring (step 3)
This is a continuation of work in https://codereview.chromium.org/18660004/ and https://codereview.chromium.org/19234003/. Flatten the Extension::Action hierarchy, getting rid of all subclasses and keeping just the top class. The new Action class has a number of data fields (some optional), so any of the old extension actions can be encoded into it. It maps in a straightforward fashion onto the current database schema. Change all the old sites that used specific Action subclasses to use the new version, and fix up unit tests. The extension activity log private API will be updated soon (by felt) to more closely match the new Action class. There is some basic compatibility in place so that the end-to-end tests still pass, but the private API unit tests have been disabled pending the rewrite. BUG=255730 TBR=jhawkins@chromium.org Review URL: https://chromiumcodereview.appspot.com/19690003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213995 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/activity_log/activity_action_constants.cc17
-rw-r--r--chrome/browser/extensions/activity_log/activity_action_constants.h20
-rw-r--r--chrome/browser/extensions/activity_log/activity_actions.cc338
-rw-r--r--chrome/browser/extensions/activity_log/activity_actions.h139
-rw-r--r--chrome/browser/extensions/activity_log/activity_database.cc73
-rw-r--r--chrome/browser/extensions/activity_log/activity_database.h4
-rw-r--r--chrome/browser/extensions/activity_log/activity_database_unittest.cc293
-rw-r--r--chrome/browser/extensions/activity_log/activity_log.cc182
-rw-r--r--chrome/browser/extensions/activity_log/activity_log.h16
-rw-r--r--chrome/browser/extensions/activity_log/activity_log_browsertest.cc6
-rw-r--r--chrome/browser/extensions/activity_log/activity_log_policy.h8
-rw-r--r--chrome/browser/extensions/activity_log/activity_log_unittest.cc17
-rw-r--r--chrome/browser/extensions/activity_log/api_actions.cc257
-rw-r--r--chrome/browser/extensions/activity_log/api_actions.h78
-rw-r--r--chrome/browser/extensions/activity_log/blocked_actions.cc98
-rw-r--r--chrome/browser/extensions/activity_log/blocked_actions.h64
-rw-r--r--chrome/browser/extensions/activity_log/dom_actions.cc151
-rw-r--r--chrome/browser/extensions/activity_log/dom_actions.h67
-rw-r--r--chrome/browser/extensions/activity_log/fullstream_ui_policy.cc122
-rw-r--r--chrome/browser/extensions/activity_log/fullstream_ui_policy.h11
-rw-r--r--chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc41
-rw-r--r--chrome/browser/extensions/activity_log/stream_noargs_ui_policy.cc17
-rw-r--r--chrome/browser/extensions/activity_log/stream_noargs_ui_policy.h7
-rw-r--r--chrome/browser/extensions/activity_log/stream_noargs_ui_policy_unittest.cc41
-rw-r--r--chrome/browser/extensions/api/activity_log_private/activity_log_private_api_unittest.cc8
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc1
-rw-r--r--chrome/browser/renderer_host/chrome_render_message_filter.cc2
-rw-r--r--chrome/chrome_browser_extensions.gypi10
28 files changed, 753 insertions, 1335 deletions
diff --git a/chrome/browser/extensions/activity_log/activity_action_constants.cc b/chrome/browser/extensions/activity_log/activity_action_constants.cc
new file mode 100644
index 0000000..eb04230
--- /dev/null
+++ b/chrome/browser/extensions/activity_log/activity_action_constants.cc
@@ -0,0 +1,17 @@
+// Copyright 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.
+
+// String constants used when logging data in the extension activity log.
+
+#include "chrome/browser/extensions/activity_log/activity_action_constants.h"
+
+namespace activity_log_constants {
+
+// Keys that may be used in the "other" attribute of an Action.
+const char kActionBlockedReason[] = "blocked_reason";
+const char kActionDomVerb[] = "dom_verb";
+const char kActionExtra[] = "extra";
+const char kActionWebRequest[] = "web_request";
+
+} // namespace activity_log_constants
diff --git a/chrome/browser/extensions/activity_log/activity_action_constants.h b/chrome/browser/extensions/activity_log/activity_action_constants.h
new file mode 100644
index 0000000..9c8d7c6
--- /dev/null
+++ b/chrome/browser/extensions/activity_log/activity_action_constants.h
@@ -0,0 +1,20 @@
+// Copyright 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.
+
+// String constants used when logging data in the extension activity log.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_ACTION_CONSTANTS_H_
+#define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_ACTION_CONSTANTS_H_
+
+namespace activity_log_constants {
+
+// Keys that may be used in the "other" attribute of an Action.
+extern const char kActionBlockedReason[];
+extern const char kActionDomVerb[];
+extern const char kActionExtra[];
+extern const char kActionWebRequest[];
+
+} // namespace activity_log_constants
+
+#endif // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_ACTION_CONSTANTS_H_
diff --git a/chrome/browser/extensions/activity_log/activity_actions.cc b/chrome/browser/extensions/activity_log/activity_actions.cc
index 93e9b68..d4603de 100644
--- a/chrome/browser/extensions/activity_log/activity_actions.cc
+++ b/chrome/browser/extensions/activity_log/activity_actions.cc
@@ -3,10 +3,21 @@
// found in the LICENSE file.
#include <string>
+#include "base/command_line.h"
#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
+#include "base/memory/singleton.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/extensions/activity_log/activity_actions.h"
+#include "chrome/browser/extensions/activity_log/api_name_constants.h"
+#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
+#include "chrome/browser/extensions/extension_tab_util.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/common/chrome_switches.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_contents.h"
+#include "sql/statement.h"
namespace {
@@ -21,51 +32,318 @@ std::string Serialize(const base::Value* value) {
return value_as_text;
}
+// Gets the URL for a given tab ID. Helper method for APIAction::LookupTabId.
+std::string GetUrlForTabId(int tab_id, Profile* profile) {
+ content::WebContents* contents = NULL;
+ Browser* browser = NULL;
+ bool found = ExtensionTabUtil::GetTabById(tab_id,
+ profile,
+ true, // search incognito tabs too
+ &browser,
+ NULL,
+ &contents,
+ NULL);
+ if (found) {
+ // Check whether the profile the tab was found in is a normal or incognito
+ // profile.
+ if (!browser->profile()->IsOffTheRecord()) {
+ GURL url = contents->GetURL();
+ return std::string(url.spec());
+ } else {
+ return std::string(extensions::APIAction::kIncognitoUrl);
+ }
+ } else {
+ return std::string();
+ }
+}
+
+// Sets up the hashmap for mapping extension strings to "ints". The hashmap is
+// only set up once because it's quite long; the value is then cached.
+class APINameMap {
+ public:
+ APINameMap() {
+ SetupMap();
+ }
+
+ // activity_log_api_name_constants.h lists all known API calls as of 5/17.
+ // This code maps each of those API calls (and events) to short strings
+ // (integers converted to strings). They're all strings because (1) sqlite
+ // databases are all strings underneath anyway and (2) the Lookup function
+ // will simply return the original api_call string if we don't have it in our
+ // lookup table.
+ void SetupMap() {
+ for (size_t i = 0;
+ i < arraysize(activity_log_api_name_constants::kNames);
+ ++i) {
+ std::string name =
+ std::string(activity_log_api_name_constants::kNames[i]);
+ std::string num = base::IntToString(i);
+ names_to_nums_[name] = num;
+ nums_to_names_[num] = name;
+ }
+ }
+
+ static APINameMap* GetInstance() {
+ return Singleton<APINameMap>::get();
+ }
+
+ // This matches an api call to a number, if it's in the lookup table. If not,
+ // it returns the original api call.
+ const std::string& ApiToShortname(const std::string& api_call) {
+ std::map<std::string, std::string>::iterator it =
+ names_to_nums_.find(api_call);
+ if (it == names_to_nums_.end())
+ return api_call;
+ else
+ return it->second;
+ }
+
+ // This matches a number to an API call -- it's the opposite of
+ // ApiToShortname.
+ const std::string& ShortnameToApi(const std::string& shortname) {
+ std::map<std::string, std::string>::iterator it =
+ nums_to_names_.find(shortname);
+ if (it == nums_to_names_.end())
+ return shortname;
+ else
+ return it->second;
+ }
+
+ private:
+ std::map<std::string, std::string> names_to_nums_; // <name, number label>
+ std::map<std::string, std::string> nums_to_names_; // <number label, name>
+};
+
} // namespace
namespace extensions {
+using api::activity_log_private::BlockedChromeActivityDetail;
+using api::activity_log_private::ChromeActivityDetail;
+using api::activity_log_private::DomActivityDetail;
using api::activity_log_private::ExtensionActivity;
+// We should log the arguments to these API calls, even if argument logging is
+// disabled by default.
+const char* APIAction::kAlwaysLog[] =
+ {"extension.connect", "extension.sendMessage",
+ "tabs.executeScript", "tabs.insertCSS" };
+const int APIAction::kSizeAlwaysLog = arraysize(kAlwaysLog);
+
+// A string used in place of the real URL when the URL is hidden because it is
+// in an incognito window. Extension activity logs mentioning kIncognitoUrl
+// let the user know that an extension is manipulating incognito tabs without
+// recording specific data about the pages.
+const char* APIAction::kIncognitoUrl = "http://incognito/";
+
+// static
+void APIAction::LookupTabId(const std::string& api_call,
+ base::ListValue* args,
+ Profile* profile) {
+ if (api_call == "tabs.get" || // api calls, ID as int
+ api_call == "tabs.connect" ||
+ api_call == "tabs.sendMessage" ||
+ api_call == "tabs.duplicate" ||
+ api_call == "tabs.update" ||
+ api_call == "tabs.reload" ||
+ api_call == "tabs.detectLanguage" ||
+ api_call == "tabs.executeScript" ||
+ api_call == "tabs.insertCSS" ||
+ api_call == "tabs.move" || // api calls, IDs in array
+ api_call == "tabs.remove" ||
+ api_call == "tabs.onUpdated" || // events, ID as int
+ api_call == "tabs.onMoved" ||
+ api_call == "tabs.onDetached" ||
+ api_call == "tabs.onAttached" ||
+ api_call == "tabs.onRemoved" ||
+ api_call == "tabs.onReplaced") {
+ int tab_id;
+ base::ListValue* id_list;
+ if (args->GetInteger(0, &tab_id)) {
+ std::string url = GetUrlForTabId(tab_id, profile);
+ if (url != std::string())
+ args->Set(0, new base::StringValue(url));
+ } else if ((api_call == "tabs.move" || api_call == "tabs.remove") &&
+ args->GetList(0, &id_list)) {
+ for (int i = 0; i < static_cast<int>(id_list->GetSize()); ++i) {
+ if (id_list->GetInteger(i, &tab_id)) {
+ std::string url = GetUrlForTabId(tab_id, profile);
+ if (url != std::string())
+ id_list->Set(i, new base::StringValue(url));
+ } else {
+ LOG(ERROR) << "The tab ID array is malformed at index " << i;
+ }
+ }
+ }
+ }
+}
+
Action::Action(const std::string& extension_id,
const base::Time& time,
- ExtensionActivity::ActivityType activity_type)
+ const ActionType action_type,
+ const std::string& api_name)
: extension_id_(extension_id),
time_(time),
- activity_type_(activity_type) {}
-
-WatchdogAction::WatchdogAction(const std::string& extension_id,
- const base::Time& time,
- const ActionType action_type,
- const std::string& api_name,
- scoped_ptr<ListValue> args,
- const GURL& page_url,
- const GURL& arg_url,
- scoped_ptr<DictionaryValue> other)
- : Action(extension_id, time, ExtensionActivity::ACTIVITY_TYPE_CHROME),
action_type_(action_type),
- api_name_(api_name),
- args_(args.Pass()),
- page_url_(page_url),
- arg_url_(arg_url),
- other_(other.Pass()) {}
-
-WatchdogAction::~WatchdogAction() {}
-
-bool WatchdogAction::Record(sql::Connection* db) {
- // This methods isn't used and will go away entirely soon once database
- // writing moves to the policy objects.
- NOTREACHED();
+ api_name_(api_name) {}
+
+Action::~Action() {}
+
+void Action::set_args(scoped_ptr<ListValue> args) {
+ args_.reset(args.release());
+}
+
+ListValue* Action::mutable_args() {
+ if (!args_.get()) {
+ args_.reset(new ListValue());
+ }
+ return args_.get();
+}
+
+void Action::set_page_url(const GURL& page_url) {
+ page_url_ = page_url;
+}
+
+void Action::set_arg_url(const GURL& arg_url) {
+ arg_url_ = arg_url;
+}
+
+void Action::set_other(scoped_ptr<DictionaryValue> other) {
+ other_.reset(other.release());
+}
+
+DictionaryValue* Action::mutable_other() {
+ if (!other_.get()) {
+ other_.reset(new DictionaryValue());
+ }
+ return other_.get();
+}
+
+bool Action::Record(sql::Connection* db) {
+ std::string sql_str =
+ "INSERT INTO " + std::string(FullStreamUIPolicy::kTableName) +
+ " (extension_id, time, action_type, api_name, args, "
+ "page_url, page_title, arg_url, other) VALUES (?,?,?,?,?,?,?,?,?)";
+ sql::Statement statement(db->GetCachedStatement(
+ sql::StatementID(SQL_FROM_HERE), sql_str.c_str()));
+ statement.BindString(0, extension_id());
+ statement.BindInt64(1, time().ToInternalValue());
+ statement.BindInt(2, static_cast<int>(action_type()));
+ statement.BindString(3, api_name());
+ if (args()) {
+ statement.BindString(4, Serialize(args()));
+ } else {
+ statement.BindNull(4);
+ }
+ if (other()) {
+ statement.BindString(8, Serialize(other()));
+ } else {
+ statement.BindNull(8);
+ }
+
+ url_canon::Replacements<char> url_sanitizer;
+ if (!CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableExtensionActivityLogTesting)) {
+ url_sanitizer.ClearQuery();
+ url_sanitizer.ClearRef();
+ }
+ if (page_url().is_valid()) {
+ statement.BindString(5, page_url().ReplaceComponents(url_sanitizer).spec());
+ }
+ statement.BindString(6, page_title());
+ if (arg_url().is_valid()) {
+ statement.BindString(7, arg_url().ReplaceComponents(url_sanitizer).spec());
+ }
+
+ if (!statement.Run()) {
+ LOG(ERROR) << "Activity log database I/O failed: " << sql_str;
+ statement.Clear();
+ return false;
+ }
return true;
}
-scoped_ptr<api::activity_log_private::ExtensionActivity>
-WatchdogAction::ConvertToExtensionActivity() {
- scoped_ptr<api::activity_log_private::ExtensionActivity> result;
+scoped_ptr<ExtensionActivity> Action::ConvertToExtensionActivity() {
+ scoped_ptr<ExtensionActivity> result(new ExtensionActivity);
+
+ result->extension_id.reset(new std::string(extension_id()));
+ result->time.reset(new double(time().ToJsTime()));
+
+ switch (action_type()) {
+ case ACTION_API_CALL:
+ case ACTION_API_EVENT: {
+ ChromeActivityDetail* details = new ChromeActivityDetail;
+ if (action_type() == ACTION_API_CALL) {
+ details->api_activity_type =
+ ChromeActivityDetail::API_ACTIVITY_TYPE_CALL;
+ } else {
+ details->api_activity_type =
+ ChromeActivityDetail::API_ACTIVITY_TYPE_EVENT_CALLBACK;
+ }
+ details->api_call.reset(new std::string(api_name()));
+ details->args.reset(new std::string(Serialize(args())));
+ details->extra.reset(new std::string(Serialize(other())));
+
+ result->activity_type = ExtensionActivity::ACTIVITY_TYPE_CHROME;
+ result->chrome_activity_detail.reset(details);
+ break;
+ }
+
+ case ACTION_API_BLOCKED: {
+ BlockedChromeActivityDetail* details = new BlockedChromeActivityDetail;
+ details->api_call.reset(new std::string(api_name()));
+ details->args.reset(new std::string(Serialize(args())));
+ details->extra.reset(new std::string(Serialize(other())));
+ // TODO(mvrable): details->reason isn't filled in; fix this after
+ // converting logging to using the types from
+ // BlockedChromeActivityDetail::Reason.
+ details->reason = BlockedChromeActivityDetail::REASON_NONE;
+
+ result->activity_type = ExtensionActivity::ACTIVITY_TYPE_BLOCKED_CHROME;
+ result->blocked_chrome_activity_detail.reset(details);
+ break;
+ }
+
+ case ACTION_DOM_EVENT:
+ case ACTION_DOM_XHR:
+ case ACTION_DOM_ACCESS:
+ case ACTION_CONTENT_SCRIPT:
+ case ACTION_WEB_REQUEST: {
+ DomActivityDetail* details = new DomActivityDetail;
+
+ if (action_type() == ACTION_WEB_REQUEST) {
+ details->dom_activity_type =
+ DomActivityDetail::DOM_ACTIVITY_TYPE_WEBREQUEST;
+ } else if (action_type() == ACTION_CONTENT_SCRIPT) {
+ details->dom_activity_type =
+ DomActivityDetail::DOM_ACTIVITY_TYPE_INSERTED;
+ } else {
+ // TODO(mvrable): This ought to be filled in properly, but since the
+ // API will change soon don't worry about it now.
+ details->dom_activity_type =
+ DomActivityDetail::DOM_ACTIVITY_TYPE_NONE;
+ }
+ details->api_call.reset(new std::string(api_name()));
+ details->args.reset(new std::string(Serialize(args())));
+ details->extra.reset(new std::string(Serialize(other())));
+ details->url.reset(new std::string(page_url().spec()));
+ if (!page_title().empty())
+ details->url_title.reset(new std::string(page_title()));
+
+ result->activity_type = ExtensionActivity::ACTIVITY_TYPE_DOM;
+ result->dom_activity_detail.reset(details);
+ break;
+ }
+
+ default:
+ LOG(WARNING) << "Bad activity log entry read from database (type="
+ << action_type_ << ")!";
+ }
+
return result.Pass();
}
-std::string WatchdogAction::PrintForDebug() {
+std::string Action::PrintForDebug() {
std::string result = "ID=" + extension_id() + " CATEGORY=";
switch (action_type_) {
case ACTION_API_CALL:
@@ -103,6 +381,10 @@ std::string WatchdogAction::PrintForDebug() {
if (page_url_.is_valid()) {
result += " PAGE_URL=" + page_url_.spec();
}
+ if (!page_title_.empty()) {
+ StringValue title(page_title_);
+ result += " PAGE_TITLE=" + Serialize(&title);
+ }
if (arg_url_.is_valid()) {
result += " ARG_URL=" + arg_url_.spec();
}
diff --git a/chrome/browser/extensions/activity_log/activity_actions.h b/chrome/browser/extensions/activity_log/activity_actions.h
index 22a242b..ba621af 100644
--- a/chrome/browser/extensions/activity_log/activity_actions.h
+++ b/chrome/browser/extensions/activity_log/activity_actions.h
@@ -9,6 +9,7 @@
#include "base/memory/ref_counted_memory.h"
#include "base/time/time.h"
#include "base/values.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/activity_log_private.h"
#include "sql/connection.h"
#include "sql/statement.h"
@@ -34,26 +35,66 @@ class Action : public base::RefCountedThreadSafe<Action> {
ACTION_WEB_REQUEST = 7,
};
+ // Creates a new activity log Action object. The extension_id, time, and
+ // type 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);
+
+ // 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_; }
+
+ // 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 ListValue* args() const { return args_.get(); }
+ void set_args(scoped_ptr<ListValue> args);
+ 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);
+
+ // A dictionary where any additional data can be stored.
+ const DictionaryValue* other() const { return other_.get(); }
+ void set_other(scoped_ptr<DictionaryValue> other);
+ DictionaryValue* mutable_other();
+
// Record the action in the database.
- virtual bool Record(sql::Connection* db) = 0;
+ bool Record(sql::Connection* db);
// Flatten the activity's type-specific fields into an ExtensionActivity.
- virtual scoped_ptr<api::activity_log_private::ExtensionActivity>
- ConvertToExtensionActivity() = 0;
+ scoped_ptr<api::activity_log_private::ExtensionActivity>
+ ConvertToExtensionActivity();
// Print an action as a regular string for debugging purposes.
- virtual std::string PrintForDebug() = 0;
-
- const std::string& extension_id() const { return extension_id_; }
- const base::Time& time() const { return time_; }
- api::activity_log_private::ExtensionActivity::ActivityType activity_type()
- const { return activity_type_; }
+ std::string PrintForDebug();
protected:
- Action(const std::string& extension_id,
- const base::Time& time,
- api::activity_log_private::ExtensionActivity::ActivityType type);
- virtual ~Action() {}
+ virtual ~Action();
private:
friend class base::RefCountedThreadSafe<Action>;
@@ -61,43 +102,61 @@ class Action : public base::RefCountedThreadSafe<Action> {
std::string extension_id_;
base::Time time_;
api::activity_log_private::ExtensionActivity::ActivityType activity_type_;
+ ActionType action_type_;
+ std::string api_name_;
+ scoped_ptr<ListValue> args_;
+ GURL page_url_;
+ std::string page_title_;
+ GURL arg_url_;
+ scoped_ptr<DictionaryValue> other_;
DISALLOW_COPY_AND_ASSIGN(Action);
};
-// TODO(mvrable): This is a temporary class used to represent Actions which
-// have been loaded from the SQLite database. Soon the entire Action hierarchy
-// will be flattened out as the type-specific classes are eliminated, at which
-// time some of the logic here will be moved.
-class WatchdogAction : public Action {
+// Constants defined for various action types.
+// TODO(mvrable): These are here for compatibility but should be moved
+// elsewhere as cleanup progresses.
+class APIAction {
public:
- WatchdogAction(const std::string& extension_id,
- const base::Time& time,
- const ActionType action_type,
- const std::string& api_name, // full method name
- scoped_ptr<ListValue> args, // the argument list
- const GURL& page_url, // page the action occurred on
- const GURL& arg_url, // URL extracted from the argument list
- scoped_ptr<DictionaryValue> other); // any extra logging info
-
- virtual bool Record(sql::Connection* db) OVERRIDE;
- virtual scoped_ptr<api::activity_log_private::ExtensionActivity>
- ConvertToExtensionActivity() OVERRIDE;
- virtual std::string PrintForDebug() OVERRIDE;
+ // These values should not be changed. Append any additional values to the
+ // end with sequential numbers.
+ enum Type {
+ CALL = 0,
+ EVENT_CALLBACK = 1,
+ UNKNOWN_TYPE = 2,
+ };
- protected:
- virtual ~WatchdogAction();
+ static const char* kAlwaysLog[];
+ static const int kSizeAlwaysLog;
+
+ static const char* kIncognitoUrl;
+
+ // Used to associate tab IDs with URLs. It will swap out the int in args with
+ // a URL as a string. If the tab is in incognito mode, we leave it alone as
+ // the original int. There is a small chance that the URL translation could
+ // be wrong, if the tab has already been navigated by the time of invocation.
+ static void LookupTabId(const std::string& api_call,
+ base::ListValue* args,
+ Profile* profile);
private:
- ActionType action_type_;
- std::string api_name_;
- scoped_ptr<ListValue> args_;
- GURL page_url_;
- GURL arg_url_;
- scoped_ptr<DictionaryValue> other_;
+ DISALLOW_IMPLICIT_CONSTRUCTORS(APIAction);
+};
+
+class BlockedAction {
+ public:
+ // These values should not be changed. Append any additional values to the
+ // end with sequential numbers.
+ enum Reason {
+ UNKNOWN = 0,
+ ACCESS_DENIED = 1,
+ QUOTA_EXCEEDED = 2,
+ };
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(BlockedAction);
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_ACTIONS_H_
-
diff --git a/chrome/browser/extensions/activity_log/activity_database.cc b/chrome/browser/extensions/activity_log/activity_database.cc
index 1a644b8..3f02b9c 100644
--- a/chrome/browser/extensions/activity_log/activity_database.cc
+++ b/chrome/browser/extensions/activity_log/activity_database.cc
@@ -25,15 +25,6 @@
using content::BrowserThread;
-namespace {
-
-bool SortActionsByTime(const scoped_refptr<extensions::Action> a,
- const scoped_refptr<extensions::Action> b) {
- return a->time() > b->time();
-}
-
-} // namespace
-
namespace extensions {
ActivityDatabase::ActivityDatabase(ActivityDatabase::Delegate* delegate)
@@ -163,8 +154,10 @@ scoped_ptr<ActivityDatabase::ActionVector> ActivityDatabase::GetActions(
late_bound = late_time.ToInternalValue();
}
std::string query_str = base::StringPrintf(
- "SELECT time, action_type, api_name, args, page_url, arg_url, other "
- "FROM %s WHERE extension_id=? AND time>? AND time<=?",
+ "SELECT time, action_type, api_name, args, page_url, page_title, "
+ "arg_url, other "
+ "FROM %s WHERE extension_id=? AND time>? AND time<=? "
+ "ORDER BY time DESC",
FullStreamUIPolicy::kTableName);
sql::Statement query(db_.GetCachedStatement(SQL_FROM_HERE,
query_str.c_str()));
@@ -172,38 +165,46 @@ scoped_ptr<ActivityDatabase::ActionVector> ActivityDatabase::GetActions(
query.BindInt64(1, early_bound);
query.BindInt64(2, late_bound);
while (query.is_valid() && query.Step()) {
- scoped_ptr<Value> raw_value(base::JSONReader::Read(query.ColumnString(3)));
- scoped_ptr<ListValue> args;
- if (raw_value && raw_value->IsType(Value::TYPE_LIST)) {
- args.reset(static_cast<ListValue*>(raw_value.release()));
- } else {
- args.reset(new ListValue());
+ scoped_refptr<Action> action =
+ new Action(extension_id,
+ base::Time::FromInternalValue(query.ColumnInt64(0)),
+ static_cast<Action::ActionType>(query.ColumnInt(1)),
+ query.ColumnString(2));
+
+ if (query.ColumnType(3) != sql::COLUMN_TYPE_NULL) {
+ scoped_ptr<Value> parsed_value(
+ base::JSONReader::Read(query.ColumnString(3)));
+ if (parsed_value && parsed_value->IsType(Value::TYPE_LIST)) {
+ action->set_args(
+ make_scoped_ptr(static_cast<ListValue*>(parsed_value.release())));
+ } else {
+ LOG(WARNING) << "Unable to parse args: '" << query.ColumnString(3)
+ << "'";
+ }
}
GURL page_url(query.ColumnString(4));
- GURL arg_url(query.ColumnString(5));
-
- raw_value.reset(base::JSONReader::Read(query.ColumnString(6)));
- scoped_ptr<DictionaryValue> other;
- if (raw_value && raw_value->IsType(Value::TYPE_DICTIONARY)) {
- other.reset(static_cast<DictionaryValue*>(raw_value.release()));
- } else {
- other.reset(new DictionaryValue());
+ action->set_page_url(page_url);
+
+ action->set_page_title(query.ColumnString(5));
+
+ GURL arg_url(query.ColumnString(6));
+ action->set_arg_url(arg_url);
+
+ if (query.ColumnType(7) != sql::COLUMN_TYPE_NULL) {
+ scoped_ptr<Value> parsed_value(
+ base::JSONReader::Read(query.ColumnString(7)));
+ if (parsed_value && parsed_value->IsType(Value::TYPE_DICTIONARY)) {
+ action->set_other(make_scoped_ptr(
+ static_cast<DictionaryValue*>(parsed_value.release())));
+ } else {
+ LOG(WARNING) << "Unable to parse other: '" << query.ColumnString(7)
+ << "'";
+ }
}
- scoped_refptr<WatchdogAction> action =
- new WatchdogAction(extension_id,
- base::Time::FromInternalValue(query.ColumnInt64(0)),
- static_cast<Action::ActionType>(query.ColumnInt(1)),
- query.ColumnString(2),
- args.Pass(),
- page_url,
- arg_url,
- other.Pass());
actions->push_back(action);
}
- // Sort by time (from newest to oldest).
- std::sort(actions->begin(), actions->end(), SortActionsByTime);
return actions.Pass();
}
diff --git a/chrome/browser/extensions/activity_log/activity_database.h b/chrome/browser/extensions/activity_log/activity_database.h
index 6c3c554..188c5fb 100644
--- a/chrome/browser/extensions/activity_log/activity_database.h
+++ b/chrome/browser/extensions/activity_log/activity_database.h
@@ -13,9 +13,7 @@
#include "base/memory/ref_counted_memory.h"
#include "base/synchronization/lock.h"
#include "base/timer/timer.h"
-#include "chrome/browser/extensions/activity_log/api_actions.h"
-#include "chrome/browser/extensions/activity_log/blocked_actions.h"
-#include "chrome/browser/extensions/activity_log/dom_actions.h"
+#include "chrome/browser/extensions/activity_log/activity_actions.h"
#include "chrome/common/extensions/extension.h"
#include "content/public/browser/browser_thread.h"
#include "sql/connection.h"
diff --git a/chrome/browser/extensions/activity_log/activity_database_unittest.cc b/chrome/browser/extensions/activity_log/activity_database_unittest.cc
index 1add2ff..ab9d869 100644
--- a/chrome/browser/extensions/activity_log/activity_database_unittest.cc
+++ b/chrome/browser/extensions/activity_log/activity_database_unittest.cc
@@ -10,10 +10,8 @@
#include "base/run_loop.h"
#include "base/test/simple_test_clock.h"
#include "base/time/time.h"
+#include "chrome/browser/extensions/activity_log/activity_action_constants.h"
#include "chrome/browser/extensions/activity_log/activity_database.h"
-#include "chrome/browser/extensions/activity_log/api_actions.h"
-#include "chrome/browser/extensions/activity_log/blocked_actions.h"
-#include "chrome/browser/extensions/activity_log/dom_actions.h"
#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/test_extension_system.h"
@@ -38,6 +36,8 @@
using content::BrowserThread;
+namespace constants = activity_log_constants;
+
namespace extensions {
// A dummy implementation of ActivityDatabase::Delegate, sufficient for
@@ -119,8 +119,8 @@ TEST_F(ActivityDatabaseTest, Init) {
db.Close();
}
-// Check that API actions are recorded in the db.
-TEST_F(ActivityDatabaseTest, RecordAPIAction) {
+// Check that actions are recorded in the db.
+TEST_F(ActivityDatabaseTest, RecordAction) {
base::ScopedTempDir temp_dir;
base::FilePath db_file;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
@@ -129,16 +129,11 @@ TEST_F(ActivityDatabaseTest, RecordAPIAction) {
ActivityDatabase* activity_db = OpenDatabase(db_file);
activity_db->SetBatchModeForTesting(false);
- base::ListValue args_list;
- args_list.AppendString("woof");
- scoped_refptr<APIAction> action = new APIAction(
- "punky",
- base::Time::Now(),
- APIAction::CALL,
- "brewster",
- "woof",
- args_list,
- "extra");
+ scoped_refptr<Action> action(new Action(
+ "punky", base::Time::Now(), Action::ACTION_API_CALL, "brewster"));
+ action->mutable_args()->AppendString("woof");
+ action->set_page_url(GURL("http://www.google.com/"));
+ action->mutable_other()->SetString(constants::kActionExtra, "extra");
activity_db->RecordAction(action);
activity_db->Close();
@@ -154,88 +149,8 @@ TEST_F(ActivityDatabaseTest, RecordAPIAction) {
ASSERT_EQ(static_cast<int>(Action::ACTION_API_CALL), statement.ColumnInt(2));
ASSERT_EQ("brewster", statement.ColumnString(3));
ASSERT_EQ("[\"woof\"]", statement.ColumnString(4));
-}
-
-// Check that DOM actions are recorded in the db.
-TEST_F(ActivityDatabaseTest, RecordDOMAction) {
- base::ScopedTempDir temp_dir;
- base::FilePath db_file;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- db_file = temp_dir.path().AppendASCII("ActivityRecord.db");
- base::DeleteFile(db_file, false);
-
- ActivityDatabase* activity_db = OpenDatabase(db_file);
- activity_db->SetBatchModeForTesting(false);
- scoped_refptr<DOMAction> action = new DOMAction(
- "punky",
- base::Time::Now(),
- DomActionType::MODIFIED,
- GURL("http://www.google.com/foo?bar"),
- string16(),
- "lets",
- "vamoose",
- "extra");
- activity_db->RecordAction(action);
- activity_db->Close();
-
- sql::Connection db;
- ASSERT_TRUE(db.Open(db_file));
-
- ASSERT_TRUE(db.DoesTableExist(FullStreamUIPolicy::kTableName));
- std::string sql_str = "SELECT * FROM " +
- std::string(FullStreamUIPolicy::kTableName);
- sql::Statement statement(db.GetUniqueStatement(sql_str.c_str()));
- ASSERT_TRUE(statement.Step());
- ASSERT_EQ("punky", statement.ColumnString(0));
- ASSERT_EQ(static_cast<int>(Action::ACTION_DOM_ACCESS),
- statement.ColumnInt(2));
- // TODO(mvrable): This test doesn't work properly, due to crbug.com/260784
- // This will be fixed when URL sanitization is moved into the activity log
- // policies in some upcoming code refactoring.
- if (CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableExtensionActivityLogTesting))
- ASSERT_EQ("http://www.google.com/foo?bar", statement.ColumnString(5));
- else
- ASSERT_EQ("http://www.google.com/foo", statement.ColumnString(5));
- ASSERT_EQ("lets", statement.ColumnString(3));
- ASSERT_EQ("[\"vamoose\"]", statement.ColumnString(4));
- ASSERT_EQ("{\"dom_verb\":6,\"extra\":\"extra\",\"page_title\":\"\"}",
- statement.ColumnString(7));
-}
-
-// Check that blocked actions are recorded in the db.
-TEST_F(ActivityDatabaseTest, RecordBlockedAction) {
- base::ScopedTempDir temp_dir;
- base::FilePath db_file;
- ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- db_file = temp_dir.path().AppendASCII("ActivityRecord.db");
- base::DeleteFile(db_file, false);
-
- ActivityDatabase* activity_db = OpenDatabase(db_file);
- scoped_refptr<BlockedAction> action = new BlockedAction(
- "punky",
- base::Time::Now(),
- "do.evilThings",
- "1, 2",
- BlockedAction::ACCESS_DENIED,
- "extra");
- activity_db->RecordAction(action);
- activity_db->Close();
-
- sql::Connection db;
- ASSERT_TRUE(db.Open(db_file));
-
- ASSERT_TRUE(db.DoesTableExist(FullStreamUIPolicy::kTableName));
- std::string sql_str = "SELECT * FROM " +
- std::string(FullStreamUIPolicy::kTableName);
- sql::Statement statement(db.GetUniqueStatement(sql_str.c_str()));
- ASSERT_TRUE(statement.Step());
- ASSERT_EQ("punky", statement.ColumnString(0));
- ASSERT_EQ(static_cast<int>(Action::ACTION_API_BLOCKED),
- statement.ColumnInt(2));
- ASSERT_EQ("do.evilThings", statement.ColumnString(3));
- ASSERT_EQ("1, 2", statement.ColumnString(4));
- ASSERT_EQ("{\"reason\":1}", statement.ColumnString(7));
+ ASSERT_EQ("http://www.google.com/", statement.ColumnString(5));
+ ASSERT_EQ("{\"extra\":\"extra\"}", statement.ColumnString(8));
}
// Check that we can read back recent actions in the db.
@@ -254,45 +169,33 @@ TEST_F(ActivityDatabaseTest, GetTodaysActions) {
// Record some actions
ActivityDatabase* activity_db = OpenDatabase(db_file);
- base::ListValue args_list;
- args_list.AppendString("woof");
- scoped_refptr<APIAction> api_action = new APIAction(
- "punky",
- mock_clock.Now() - base::TimeDelta::FromMinutes(40),
- APIAction::CALL,
- "brewster",
- "woof",
- args_list,
- "extra");
- scoped_refptr<DOMAction> dom_action = new DOMAction(
- "punky",
- mock_clock.Now(),
- DomActionType::MODIFIED,
- GURL("http://www.google.com"),
- string16(),
- "lets",
- "vamoose",
- "extra");
- scoped_refptr<DOMAction> extra_dom_action = new DOMAction(
- "scoobydoo",
- mock_clock.Now(),
- DomActionType::MODIFIED,
- GURL("http://www.google.com"),
- string16(),
- "lets",
- "vamoose",
- "extra");
- activity_db->RecordAction(api_action);
- activity_db->RecordAction(dom_action);
- activity_db->RecordAction(extra_dom_action);
+
+ scoped_refptr<Action> action;
+ action = new Action("punky",
+ mock_clock.Now() - base::TimeDelta::FromMinutes(40),
+ Action::ACTION_API_CALL,
+ "brewster");
+ action->mutable_args()->AppendString("woof");
+ activity_db->RecordAction(action);
+
+ action =
+ new Action("punky", mock_clock.Now(), Action::ACTION_DOM_ACCESS, "lets");
+ action->mutable_args()->AppendString("vamoose");
+ action->set_page_url(GURL("http://www.google.com"));
+ activity_db->RecordAction(action);
+
+ action = new Action(
+ "scoobydoo", mock_clock.Now(), Action::ACTION_DOM_ACCESS, "lets");
+ action->mutable_args()->AppendString("vamoose");
+ action->set_page_url(GURL("http://www.google.com"));
+ activity_db->RecordAction(action);
// Read them back
std::string api_print =
- "ID=punky CATEGORY=api_call API=brewster ARGS=[\"woof\"] OTHER={}";
+ "ID=punky CATEGORY=api_call API=brewster ARGS=[\"woof\"]";
std::string dom_print =
"ID=punky CATEGORY=dom_access API=lets ARGS=[\"vamoose\"] "
- "PAGE_URL=http://www.google.com/ "
- "OTHER={\"dom_verb\":6,\"extra\":\"extra\",\"page_title\":\"\"}";
+ "PAGE_URL=http://www.google.com/";
scoped_ptr<std::vector<scoped_refptr<Action> > > actions =
activity_db->GetActions("punky", 0);
ASSERT_EQ(2, static_cast<int>(actions->size()));
@@ -302,7 +205,7 @@ TEST_F(ActivityDatabaseTest, GetTodaysActions) {
activity_db->Close();
}
-// Check that we can read back recent actions in the db.
+// Check that we can read back less recent actions in the db.
TEST_F(ActivityDatabaseTest, GetOlderActions) {
base::ScopedTempDir temp_dir;
base::FilePath db_file;
@@ -318,56 +221,43 @@ TEST_F(ActivityDatabaseTest, GetOlderActions) {
// Record some actions
ActivityDatabase* activity_db = OpenDatabase(db_file);
- base::ListValue args_list;
- args_list.AppendString("woof");
- scoped_refptr<APIAction> api_action = new APIAction(
- "punky",
- mock_clock.Now() - base::TimeDelta::FromDays(3)
- - base::TimeDelta::FromMinutes(40),
- APIAction::CALL,
- "brewster",
- "woof",
- args_list,
- "extra");
- scoped_refptr<DOMAction> dom_action = new DOMAction(
- "punky",
- mock_clock.Now() - base::TimeDelta::FromDays(3),
- DomActionType::MODIFIED,
- GURL("http://www.google.com"),
- string16(),
- "lets",
- "vamoose",
- "extra");
- scoped_refptr<DOMAction> toonew_dom_action = new DOMAction(
- "punky",
- mock_clock.Now(),
- DomActionType::MODIFIED,
- GURL("http://www.google.com"),
- string16(),
- "too new",
- "vamoose",
- "extra");
- scoped_refptr<DOMAction> tooold_dom_action = new DOMAction(
- "punky",
- mock_clock.Now() - base::TimeDelta::FromDays(7),
- DomActionType::MODIFIED,
- GURL("http://www.google.com"),
- string16(),
- "too old",
- "vamoose",
- "extra");
- activity_db->RecordAction(api_action);
- activity_db->RecordAction(dom_action);
- activity_db->RecordAction(toonew_dom_action);
- activity_db->RecordAction(tooold_dom_action);
+ scoped_refptr<Action> action =
+ new Action("punky",
+ mock_clock.Now() - base::TimeDelta::FromDays(3) -
+ base::TimeDelta::FromMinutes(40),
+ Action::ACTION_API_CALL,
+ "brewster");
+ action->mutable_args()->AppendString("woof");
+ activity_db->RecordAction(action);
+
+ action = new Action("punky",
+ mock_clock.Now() - base::TimeDelta::FromDays(3),
+ Action::ACTION_DOM_ACCESS,
+ "lets");
+ action->mutable_args()->AppendString("vamoose");
+ action->set_page_url(GURL("http://www.google.com"));
+ activity_db->RecordAction(action);
+
+ action =
+ new Action("punky", mock_clock.Now(), Action::ACTION_DOM_ACCESS, "lets");
+ action->mutable_args()->AppendString("too new");
+ action->set_page_url(GURL("http://www.google.com"));
+ activity_db->RecordAction(action);
+
+ action = new Action("punky",
+ mock_clock.Now() - base::TimeDelta::FromDays(7),
+ Action::ACTION_DOM_ACCESS,
+ "lets");
+ action->mutable_args()->AppendString("too old");
+ action->set_page_url(GURL("http://www.google.com"));
+ activity_db->RecordAction(action);
// Read them back
std::string api_print =
- "ID=punky CATEGORY=api_call API=brewster ARGS=[\"woof\"] OTHER={}";
+ "ID=punky CATEGORY=api_call API=brewster ARGS=[\"woof\"]";
std::string dom_print =
"ID=punky CATEGORY=dom_access API=lets ARGS=[\"vamoose\"] "
- "PAGE_URL=http://www.google.com/ "
- "OTHER={\"dom_verb\":6,\"extra\":\"extra\",\"page_title\":\"\"}";
+ "PAGE_URL=http://www.google.com/";
scoped_ptr<std::vector<scoped_refptr<Action> > > actions =
activity_db->GetActions("punky", 3);
ASSERT_EQ(2, static_cast<int>(actions->size()));
@@ -394,17 +284,13 @@ TEST_F(ActivityDatabaseTest, BatchModeOff) {
ActivityDatabase* activity_db = OpenDatabase(db_file);
activity_db->SetBatchModeForTesting(false);
activity_db->SetClockForTesting(&mock_clock);
- base::ListValue args_list;
- args_list.AppendString("woof");
- scoped_refptr<APIAction> api_action = new APIAction(
- "punky",
- mock_clock.Now() - base::TimeDelta::FromMinutes(40),
- APIAction::CALL,
- "brewster",
- "woof",
- args_list,
- "extra");
- activity_db->RecordAction(api_action);
+ scoped_refptr<Action> action =
+ new Action("punky",
+ mock_clock.Now() - base::TimeDelta::FromMinutes(40),
+ Action::ACTION_API_CALL,
+ "brewster");
+ action->mutable_args()->AppendString("woof");
+ activity_db->RecordAction(action);
scoped_ptr<std::vector<scoped_refptr<Action> > > actions =
activity_db->GetActions("punky", 0);
@@ -429,17 +315,13 @@ TEST_F(ActivityDatabaseTest, BatchModeOn) {
ActivityDatabase* activity_db = OpenDatabase(db_file);
activity_db->SetBatchModeForTesting(true);
activity_db->SetClockForTesting(&mock_clock);
- base::ListValue args_list;
- args_list.AppendString("woof");
- scoped_refptr<APIAction> api_action = new APIAction(
- "punky",
- mock_clock.Now() - base::TimeDelta::FromMinutes(40),
- APIAction::CALL,
- "brewster",
- "woof",
- args_list,
- "extra");
- activity_db->RecordAction(api_action);
+ scoped_refptr<Action> action =
+ new Action("punky",
+ mock_clock.Now() - base::TimeDelta::FromMinutes(40),
+ Action::ACTION_API_CALL,
+ "brewster");
+ action->mutable_args()->AppendString("woof");
+ activity_db->RecordAction(action);
scoped_ptr<std::vector<scoped_refptr<Action> > > actions_before =
activity_db->GetActions("punky", 0);
@@ -466,16 +348,9 @@ TEST_F(ActivityDatabaseTest, InitFailure) {
ActivityDatabase* activity_db =
new ActivityDatabase(new ActivityDatabaseTestPolicy());
- base::ListValue args_list;
- args_list.AppendString("woof");
- scoped_refptr<APIAction> action = new APIAction(
- "punky",
- base::Time::Now(),
- APIAction::CALL,
- "brewster",
- "woooof",
- args_list,
- "extra");
+ scoped_refptr<Action> action = new Action(
+ "punky", base::Time::Now(), Action::ACTION_API_CALL, "brewster");
+ action->mutable_args()->AppendString("woof");
activity_db->RecordAction(action);
activity_db->Close();
}
diff --git a/chrome/browser/extensions/activity_log/activity_log.cc b/chrome/browser/extensions/activity_log/activity_log.cc
index 4233e12..b96886b 100644
--- a/chrome/browser/extensions/activity_log/activity_log.cc
+++ b/chrome/browser/extensions/activity_log/activity_log.cc
@@ -8,10 +8,10 @@
#include "base/json/json_string_value_serializer.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_checker.h"
+#include "chrome/browser/extensions/activity_log/activity_action_constants.h"
#include "chrome/browser/extensions/activity_log/activity_log.h"
-#include "chrome/browser/extensions/activity_log/api_actions.h"
-#include "chrome/browser/extensions/activity_log/blocked_actions.h"
#include "chrome/browser/extensions/activity_log/stream_noargs_ui_policy.h"
#include "chrome/browser/extensions/api/activity_log_private/activity_log_private_api.h"
#include "chrome/browser/extensions/extension_service.h"
@@ -29,6 +29,8 @@
#include "third_party/re2/re2/re2.h"
#include "url/gurl.h"
+namespace constants = activity_log_constants;
+
namespace {
// Concatenate arguments.
@@ -253,6 +255,17 @@ void ActivityLog::RemoveObserver(ActivityLog::Observer* observer) {
observers_->RemoveObserver(observer);
}
+void ActivityLog::LogAction(scoped_refptr<Action> action) {
+ if (IsLogEnabled() &&
+ !ActivityLogAPI::IsExtensionWhitelisted(action->extension_id())) {
+ if (policy_)
+ policy_->ProcessAction(action);
+ observers_->Notify(&Observer::OnExtensionActivity, action);
+ if (testing_mode_)
+ LOG(INFO) << action->PrintForDebug();
+ }
+}
+
void ActivityLog::LogAPIActionInternal(const std::string& extension_id,
const std::string& api_call,
base::ListValue* args,
@@ -265,35 +278,20 @@ void ActivityLog::LogAPIActionInternal(const std::string& extension_id,
APIAction::LookupTabId(api_call, args, profile_);
}
- if (policy_) {
- scoped_ptr<base::DictionaryValue> details(new DictionaryValue());
- std::string key = policy_->GetKey(ActivityLogPolicy::PARAM_KEY_EXTRA);
- details->SetString(key, extra);
- DCHECK((type == APIAction::CALL || type == APIAction::EVENT_CALLBACK) &&
- "Unexpected APIAction call type.");
- policy_->ProcessAction(
- type == APIAction::CALL ? ActivityLogPolicy::ACTION_API :
- ActivityLogPolicy::ACTION_EVENT,
- extension_id,
- api_call,
- GURL(),
- args,
- details.get());
- }
+ DCHECK((type == APIAction::CALL || type == APIAction::EVENT_CALLBACK) &&
+ "Unexpected APIAction call type.");
- // TODO(felt) Logging should be done more efficiently, so that it
- // doesn't require construction of the action object.
- scoped_refptr<APIAction> action = new APIAction(
- extension_id,
- base::Time::Now(),
- type,
- api_call,
- MakeArgList(args),
- *args,
- extra);
+ scoped_refptr<Action> action;
+ action = new Action(extension_id,
+ base::Time::Now(),
+ type == APIAction::CALL ? Action::ACTION_API_CALL
+ : Action::ACTION_API_EVENT,
+ api_call);
+ action->set_args(make_scoped_ptr(args->DeepCopy()));
+ if (!extra.empty())
+ action->mutable_other()->SetString(constants::kActionExtra, extra);
- observers_->Notify(&Observer::OnExtensionActivity, action);
- if (testing_mode_) LOG(INFO) << action->PrintForDebug();
+ LogAction(action);
} else {
LOG(ERROR) << "Unknown API call! " << api_call;
}
@@ -338,29 +336,18 @@ void ActivityLog::LogBlockedAction(const std::string& extension_id,
if (!IsLogEnabled() ||
ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return;
- if (policy_) {
- scoped_ptr<base::DictionaryValue> details(new DictionaryValue());
- std::string key = policy_->GetKey(ActivityLogPolicy::PARAM_KEY_REASON);
- details->SetInteger(key, static_cast<int>(reason));
- key = policy_->GetKey(ActivityLogPolicy::PARAM_KEY_EXTRA);
- details->SetString(key, extra);
- policy_->ProcessAction(
- ActivityLogPolicy::ACTION_BLOCKED,
- extension_id,
- blocked_call,
- GURL(),
- args,
- details.get());
- }
-
- scoped_refptr<BlockedAction> action = new BlockedAction(extension_id,
- base::Time::Now(),
- blocked_call,
- MakeArgList(args),
- reason,
- extra);
- observers_->Notify(&Observer::OnExtensionActivity, action);
- if (testing_mode_) LOG(INFO) << action->PrintForDebug();
+ scoped_refptr<Action> action;
+ action = new Action(extension_id,
+ base::Time::Now(),
+ Action::ACTION_API_BLOCKED,
+ blocked_call);
+ action->set_args(make_scoped_ptr(args->DeepCopy()));
+ action->mutable_other()
+ ->SetInteger(constants::kActionBlockedReason, static_cast<int>(reason));
+ if (!extra.empty())
+ action->mutable_other()->SetString(constants::kActionExtra, extra);
+
+ LogAction(action);
}
void ActivityLog::LogDOMAction(const std::string& extension_id,
@@ -372,40 +359,28 @@ void ActivityLog::LogDOMAction(const std::string& extension_id,
const std::string& extra) {
if (!IsLogEnabled() ||
ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return;
- if (call_type == DomActionType::METHOD && api_call == "XMLHttpRequest.open")
- call_type = DomActionType::XHR;
- if (policy_) {
- scoped_ptr<base::DictionaryValue> details(new DictionaryValue());
- std::string key = policy_->GetKey(ActivityLogPolicy::PARAM_KEY_DOM_ACTION);
- details->SetInteger(key, static_cast<int>(call_type));
- key = policy_->GetKey(ActivityLogPolicy::PARAM_KEY_URL_TITLE);
- details->SetString(key, url_title);
- key = policy_->GetKey(ActivityLogPolicy::PARAM_KEY_EXTRA);
- details->SetString(key, extra);
- policy_->ProcessAction(
- ActivityLogPolicy::ACTION_DOM,
- extension_id,
- api_call,
- url,
- args,
- details.get());
+ Action::ActionType action_type = Action::ACTION_DOM_ACCESS;
+ if (call_type == DomActionType::INSERTED) {
+ action_type = Action::ACTION_CONTENT_SCRIPT;
+ } else if (call_type == DomActionType::METHOD &&
+ api_call == "XMLHttpRequest.open") {
+ call_type = DomActionType::XHR;
+ action_type = Action::ACTION_DOM_XHR;
}
-
- // TODO(felt) Logging should be done more efficiently, so that it
- // doesn't require construction of the action object.
- scoped_refptr<DOMAction> action = new DOMAction(
- extension_id,
- base::Time::Now(),
- call_type,
- url,
- url_title,
- api_call,
- MakeArgList(args),
- extra);
- observers_->Notify(&Observer::OnExtensionActivity, action);
- if (testing_mode_) LOG(INFO) << action->PrintForDebug();
+ scoped_refptr<Action> action;
+ action = new Action(extension_id, base::Time::Now(), action_type, api_call);
+ if (args)
+ action->set_args(make_scoped_ptr(args->DeepCopy()));
+ action->set_page_url(url);
+ action->set_page_title(base::UTF16ToUTF8(url_title));
+ action->mutable_other()
+ ->SetInteger(constants::kActionDomVerb, static_cast<int>(call_type));
+ if (!extra.empty())
+ action->mutable_other()->SetString(constants::kActionExtra, extra);
+
+ LogAction(action);
}
void ActivityLog::LogWebRequestAction(const std::string& extension_id,
@@ -413,43 +388,18 @@ void ActivityLog::LogWebRequestAction(const std::string& extension_id,
const std::string& api_call,
scoped_ptr<DictionaryValue> details,
const std::string& extra) {
- string16 null_title;
if (!IsLogEnabled() ||
ActivityLogAPI::IsExtensionWhitelisted(extension_id)) return;
- std::string details_string;
- if (policy_) {
- scoped_ptr<base::DictionaryValue> details(new DictionaryValue());
- std::string key = policy_->GetKey(
- ActivityLogPolicy::PARAM_KEY_DETAILS_STRING);
- details->SetString(key, details_string);
- key = policy_->GetKey(ActivityLogPolicy::PARAM_KEY_EXTRA);
- details->SetString(key, extra);
- policy_->ProcessAction(
- ActivityLogPolicy::ACTION_WEB_REQUEST,
- extension_id,
- api_call,
- url,
- NULL,
- details.get());
- }
+ scoped_refptr<Action> action;
+ action = new Action(
+ extension_id, base::Time::Now(), Action::ACTION_WEB_REQUEST, api_call);
+ action->set_page_url(url);
+ action->mutable_other()->Set(constants::kActionWebRequest, details.release());
+ if (!extra.empty())
+ action->mutable_other()->SetString(constants::kActionExtra, extra);
- JSONStringValueSerializer serializer(&details_string);
- serializer.SerializeAndOmitBinaryValues(*details);
-
- // TODO(felt) Logging should be done more efficiently, so that it
- // doesn't require construction of the action object.
- scoped_refptr<DOMAction> action = new DOMAction(
- extension_id,
- base::Time::Now(),
- DomActionType::WEBREQUEST,
- url,
- null_title,
- api_call,
- details_string,
- extra);
- observers_->Notify(&Observer::OnExtensionActivity, action);
- if (testing_mode_) LOG(INFO) << action->PrintForDebug();
+ LogAction(action);
}
void ActivityLog::GetActions(
diff --git a/chrome/browser/extensions/activity_log/activity_log.h b/chrome/browser/extensions/activity_log/activity_log.h
index 19813c2..446d9af 100644
--- a/chrome/browser/extensions/activity_log/activity_log.h
+++ b/chrome/browser/extensions/activity_log/activity_log.h
@@ -17,7 +17,6 @@
#include "chrome/browser/extensions/activity_log/activity_actions.h"
#include "chrome/browser/extensions/activity_log/activity_database.h"
#include "chrome/browser/extensions/activity_log/activity_log_policy.h"
-#include "chrome/browser/extensions/activity_log/api_actions.h"
#include "chrome/browser/extensions/install_observer.h"
#include "chrome/browser/extensions/install_tracker.h"
#include "chrome/browser/extensions/tab_helper.h"
@@ -66,6 +65,21 @@ class ActivityLog : public BrowserContextKeyedService,
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
+ // Logs an extension action: passes it to any installed policy to be logged
+ // to the database, to any observers, and logs to the console if in testing
+ // mode.
+ //
+ // The convenience Log*Action methods below can be used as well if the caller
+ // does not wish to construct the Action object itself, however those methods
+ // are somewhat deprecated.
+ void LogAction(scoped_refptr<Action> action);
+
+ // TODO(mvrable): The calls below take args as a raw pointer, but the callee
+ // does not own the object so these should more properly be a const pointer.
+ // The callee is forced to make a copy of the object which in some cases is
+ // wasteful, and it could be better to take a scoped_ptr as input. Switching
+ // to using LogAction is another way to clean this up.
+
// Log a successful API call made by an extension.
// This will create an APIAction for storage in the database.
// (Note: implemented as a wrapper for LogAPIActionInternal.)
diff --git a/chrome/browser/extensions/activity_log/activity_log_browsertest.cc b/chrome/browser/extensions/activity_log/activity_log_browsertest.cc
index db573c1..ef877b3 100644
--- a/chrome/browser/extensions/activity_log/activity_log_browsertest.cc
+++ b/chrome/browser/extensions/activity_log/activity_log_browsertest.cc
@@ -46,10 +46,10 @@ class ActivityLogPrerenderTest : public ExtensionApiTest {
scoped_refptr<Action> last = i->front();
std::string args = base::StringPrintf(
- "ID=%s CATEGORY=content_script API= ARGS=[\"\\\"/google_cs.js \\\"\"] "
+ "ID=%s CATEGORY=content_script API= ARGS=[\"/google_cs.js \"] "
"PAGE_URL=http://www.google.com.bo:%d/test.html "
- "OTHER={\"dom_verb\":3,\"extra\":\"(prerender)\",\"page_title\":\"www."
- "google.com.bo:%d/test.html\"}",
+ "PAGE_TITLE=\"www.google.com.bo:%d/test.html\" "
+ "OTHER={\"dom_verb\":3,\"extra\":\"(prerender)\"}",
extension_id.c_str(), port, port);
// TODO: Replace PrintForDebug with field testing
// when this feature will be available
diff --git a/chrome/browser/extensions/activity_log/activity_log_policy.h b/chrome/browser/extensions/activity_log/activity_log_policy.h
index 98bc4ba..41dfa0a 100644
--- a/chrome/browser/extensions/activity_log/activity_log_policy.h
+++ b/chrome/browser/extensions/activity_log/activity_log_policy.h
@@ -80,13 +80,7 @@ class ActivityLogPolicy {
// Updates the internal state of the model summarizing actions and possibly
// writes to the database. Implements the default policy storing internal
// state to memory every 5 min.
- virtual void ProcessAction(
- ActionType action_type,
- const std::string& extension_id,
- const std::string& name, // action name
- const GURL& gurl, // target URL
- const base::ListValue* args, // arguments
- const base::DictionaryValue* details) = 0; // details
+ virtual void ProcessAction(scoped_refptr<Action> action) = 0;
// Pass the parameters as a set of key-value pairs and return data back via
// a callback passing results as a set of key-value pairs. The keys are
diff --git a/chrome/browser/extensions/activity_log/activity_log_unittest.cc b/chrome/browser/extensions/activity_log/activity_log_unittest.cc
index 4a7958e..10dbd19 100644
--- a/chrome/browser/extensions/activity_log/activity_log_unittest.cc
+++ b/chrome/browser/extensions/activity_log/activity_log_unittest.cc
@@ -8,7 +8,6 @@
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/extensions/activity_log/activity_log.h"
-#include "chrome/browser/extensions/activity_log/dom_actions.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/test_extension_system.h"
#include "chrome/browser/prerender/prerender_handle.h"
@@ -85,14 +84,14 @@ class ActivityLogTest : public ChromeRenderViewHostTestHarness {
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableExtensionActivityLogTesting))
args =
- "ID=abc CATEGORY=content_script API=document.write ARGS=[\"\"] "
+ "ID=abc CATEGORY=content_script API=document.write ARGS=[] "
"PAGE_URL=http://www.google.com/foo?bar "
- "OTHER={\"dom_verb\":3,\"extra\":\"extra\",\"page_title\":\"\"}";
+ "OTHER={\"dom_verb\":3,\"extra\":\"extra\"}";
else
args =
- "ID=abc CATEGORY=content_script API=document.write ARGS=[\"\"] "
+ "ID=abc CATEGORY=content_script API=document.write ARGS=[] "
"PAGE_URL=http://www.google.com/foo "
- "OTHER={\"dom_verb\":3,\"extra\":\"extra\",\"page_title\":\"\"}";
+ "OTHER={\"dom_verb\":3,\"extra\":\"extra\"}";
ASSERT_EQ(args, last->PrintForDebug());
}
@@ -101,7 +100,7 @@ class ActivityLogTest : public ChromeRenderViewHostTestHarness {
scoped_refptr<Action> last = i->front();
std::string id(kExtensionId);
std::string noargs =
- "ID=" + id + " CATEGORY=api_call API=tabs.testMethod ARGS=[] OTHER={}";
+ "ID=" + id + " CATEGORY=api_call API=tabs.testMethod";
ASSERT_EQ(noargs, last->PrintForDebug());
}
@@ -111,7 +110,7 @@ class ActivityLogTest : public ChromeRenderViewHostTestHarness {
std::string id(kExtensionId);
std::string args = "ID=" + id +
" CATEGORY=api_call API=extension.connect "
- "ARGS=[\"hello\",\"world\"] OTHER={}";
+ "ARGS=[\"hello\",\"world\"]";
ASSERT_EQ(args, last->PrintForDebug());
}
@@ -129,8 +128,8 @@ class ActivityLogTest : public ChromeRenderViewHostTestHarness {
scoped_refptr<Action> last = i->front();
std::string args =
"ID=odlameecjipmbmbejkplpemijjgpljce CATEGORY=content_script API= "
- "ARGS=[\"\\\"script \\\"\"] PAGE_URL=http://www.google.com/ "
- "OTHER={\"dom_verb\":3,\"extra\":\"(prerender)\",\"page_title\":\"\"}";
+ "ARGS=[\"script \"] PAGE_URL=http://www.google.com/ "
+ "OTHER={\"dom_verb\":3,\"extra\":\"(prerender)\"}";
ASSERT_EQ(args, last->PrintForDebug());
}
diff --git a/chrome/browser/extensions/activity_log/api_actions.cc b/chrome/browser/extensions/activity_log/api_actions.cc
deleted file mode 100644
index bb50674..0000000
--- a/chrome/browser/extensions/activity_log/api_actions.cc
+++ /dev/null
@@ -1,257 +0,0 @@
-// 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.
-
-#include "base/json/json_string_value_serializer.h"
-#include "base/logging.h"
-#include "base/memory/singleton.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "chrome/browser/extensions/activity_log/api_actions.h"
-#include "chrome/browser/extensions/activity_log/api_name_constants.h"
-#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
-#include "chrome/browser/extensions/extension_tab_util.h"
-#include "chrome/browser/ui/browser.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/web_contents.h"
-#include "url/gurl.h"
-
-using content::BrowserThread;
-
-namespace {
-
-// Gets the URL for a given tab ID. Helper method for APIAction::LookupTabId.
-std::string GetURLForTabId(const int tab_id, Profile* profile) {
- content::WebContents* contents = NULL;
- Browser* browser = NULL;
- bool found = ExtensionTabUtil::GetTabById(tab_id,
- profile,
- true, // search incognito tabs too
- &browser,
- NULL,
- &contents,
- NULL);
- if (found) {
- // Check whether the profile the tab was found in is a normal or incognito
- // profile.
- if (!browser->profile()->IsOffTheRecord()) {
- GURL url = contents->GetURL();
- return std::string(url.spec());
- } else {
- return std::string(extensions::APIAction::kIncognitoUrl);
- }
- } else {
- return std::string();
- }
-}
-
-// Sets up the hashmap for mapping extension strings to "ints". The hashmap is
-// only set up once because it's quite long; the value is then cached.
-class APINameMap {
- public:
- APINameMap() {
- SetupMap();
- }
-
- // activity_log_api_name_constants.h lists all known API calls as of 5/17.
- // This code maps each of those API calls (and events) to short strings
- // (integers converted to strings). They're all strings because (1) sqlite
- // databases are all strings underneath anyway and (2) the Lookup function
- // will simply return the original api_call string if we don't have it in our
- // lookup table.
- void SetupMap() {
- for (size_t i = 0;
- i < arraysize(activity_log_api_name_constants::kNames);
- ++i) {
- std::string name =
- std::string(activity_log_api_name_constants::kNames[i]);
- std::string num = base::IntToString(i);
- names_to_nums_[name] = num;
- nums_to_names_[num] = name;
- }
- }
-
- static APINameMap* GetInstance() {
- return Singleton<APINameMap>::get();
- }
-
- // This matches an api call to a number, if it's in the lookup table. If not,
- // it returns the original api call.
- const std::string& ApiToShortname(const std::string& api_call) {
- std::map<std::string, std::string>::iterator it =
- names_to_nums_.find(api_call);
- if (it == names_to_nums_.end())
- return api_call;
- else
- return it->second;
- }
-
- // This matches a number to an API call -- it's the opposite of
- // ApiToShortname.
- const std::string& ShortnameToApi(const std::string& shortname) {
- std::map<std::string, std::string>::iterator it =
- nums_to_names_.find(shortname);
- if (it == nums_to_names_.end())
- return shortname;
- else
- return it->second;
- }
-
- private:
- std::map<std::string, std::string> names_to_nums_; // <name, number label>
- std::map<std::string, std::string> nums_to_names_; // <number label, name>
-};
-
-std::string Serialize(const base::Value& value) {
- std::string value_as_text;
- JSONStringValueSerializer serializer(&value_as_text);
- serializer.SerializeAndOmitBinaryValues(value);
- return value_as_text;
-}
-
-} // namespace
-
-namespace extensions {
-
-using api::activity_log_private::ExtensionActivity;
-using api::activity_log_private::DomActivityDetail;
-using api::activity_log_private::ChromeActivityDetail;
-using api::activity_log_private::BlockedChromeActivityDetail;
-
-// We should log the arguments to these API calls, even if argument logging is
-// disabled by default.
-const char* APIAction::kAlwaysLog[] =
- {"extension.connect", "extension.sendMessage",
- "tabs.executeScript", "tabs.insertCSS" };
-const int APIAction::kSizeAlwaysLog = arraysize(kAlwaysLog);
-
-// A string used in place of the real URL when the URL is hidden because it is
-// in an incognito window. Extension activity logs mentioning kIncognitoUrl
-// let the user know that an extension is manipulating incognito tabs without
-// recording specific data about the pages.
-const char* APIAction::kIncognitoUrl = "http://incognito/";
-
-APIAction::APIAction(const std::string& extension_id,
- const base::Time& time,
- const Type type,
- const std::string& api_call,
- const std::string& args,
- const base::ListValue& args_list,
- const std::string& extra)
- : Action(extension_id, time, ExtensionActivity::ACTIVITY_TYPE_CHROME),
- type_(type),
- api_call_(api_call),
- args_(args),
- args_list_(args_list.DeepCopy()),
- extra_(extra) { }
-
-APIAction::~APIAction() {
-}
-
-scoped_ptr<ExtensionActivity> APIAction::ConvertToExtensionActivity() {
- scoped_ptr<ExtensionActivity> formatted_activity;
- formatted_activity.reset(new ExtensionActivity);
- formatted_activity->extension_id.reset(
- new std::string(extension_id()));
- formatted_activity->activity_type = activity_type();
- formatted_activity->time.reset(new double(time().ToJsTime()));
- ChromeActivityDetail* details = new ChromeActivityDetail;
- details->api_activity_type = ChromeActivityDetail::ParseApiActivityType(
- TypeAsString());
- details->api_call.reset(new std::string(api_call_));
- details->args.reset(new std::string(args_));
- details->extra.reset(new std::string(extra_));
- formatted_activity->chrome_activity_detail.reset(details);
- return formatted_activity.Pass();
-}
-
-bool APIAction::Record(sql::Connection* db) {
- std::string sql_str =
- "INSERT INTO " + std::string(FullStreamUIPolicy::kTableName) +
- " (extension_id, time, action_type, api_name, args) VALUES"
- " (?,?,?,?,?)";
- sql::Statement statement(db->GetCachedStatement(
- sql::StatementID(SQL_FROM_HERE), sql_str.c_str()));
- statement.BindString(0, extension_id());
- statement.BindInt64(1, time().ToInternalValue());
- switch (type_) {
- case CALL:
- statement.BindInt(2, static_cast<int>(Action::ACTION_API_CALL));
- break;
- case EVENT_CALLBACK:
- statement.BindInt(2, static_cast<int>(Action::ACTION_API_EVENT));
- break;
- default:
- LOG(ERROR) << "Invalid action type: " << type_;
- return false;
- }
- statement.BindString(3, api_call_);
- statement.BindString(4, Serialize(*args_list_));
- if (!statement.Run()) {
- LOG(ERROR) << "Activity log database I/O failed: " << sql_str;
- statement.Clear();
- return false;
- }
- return true;
-}
-
-// static
-void APIAction::LookupTabId(const std::string& api_call,
- base::ListValue* args,
- Profile* profile) {
- if (api_call == "tabs.get" || // api calls, ID as int
- api_call == "tabs.connect" ||
- api_call == "tabs.sendMessage" ||
- api_call == "tabs.duplicate" ||
- api_call == "tabs.update" ||
- api_call == "tabs.reload" ||
- api_call == "tabs.detectLanguage" ||
- api_call == "tabs.executeScript" ||
- api_call == "tabs.insertCSS" ||
- api_call == "tabs.move" || // api calls, IDs in array
- api_call == "tabs.remove" ||
- api_call == "tabs.onUpdated" || // events, ID as int
- api_call == "tabs.onMoved" ||
- api_call == "tabs.onDetached" ||
- api_call == "tabs.onAttached" ||
- api_call == "tabs.onRemoved" ||
- api_call == "tabs.onReplaced") {
- int tab_id;
- base::ListValue* id_list;
- if (args->GetInteger(0, &tab_id)) {
- std::string url = GetURLForTabId(tab_id, profile);
- if (url != std::string())
- args->Set(0, new base::StringValue(url));
- } else if ((api_call == "tabs.move" || api_call == "tabs.remove") &&
- args->GetList(0, &id_list)) {
- for (int i = 0; i < static_cast<int>(id_list->GetSize()); ++i) {
- if (id_list->GetInteger(i, &tab_id)) {
- std::string url = GetURLForTabId(tab_id, profile);
- if (url != std::string())
- id_list->Set(i, new base::StringValue(url));
- } else {
- LOG(ERROR) << "The tab ID array is malformed at index " << i;
- }
- }
- }
- }
-}
-
-std::string APIAction::PrintForDebug() {
- return "ID: " + extension_id() + ", CATEGORY: " + TypeAsString() +
- ", API: " + api_call_ + ", ARGS: " + args_;
-}
-
-std::string APIAction::TypeAsString() const {
- switch (type_) {
- case CALL:
- return "call";
- case EVENT_CALLBACK:
- return "event_callback";
- default:
- return "unknown_type";
- }
-}
-
-} // namespace extensions
-
diff --git a/chrome/browser/extensions/activity_log/api_actions.h b/chrome/browser/extensions/activity_log/api_actions.h
deleted file mode 100644
index 9ea84ba..0000000
--- a/chrome/browser/extensions/activity_log/api_actions.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// 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_API_ACTIONS_H_
-#define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_API_ACTIONS_H_
-
-#include "chrome/browser/extensions/activity_log/activity_actions.h"
-#include "chrome/browser/profiles/profile.h"
-
-namespace extensions {
-
-// This class describes API calls that did not run into permissions or quota
-// problems. See BlockedActions for API calls that did not succeed.
-class APIAction : public Action {
- public:
- // These values should not be changed. Append any additional values to the
- // end with sequential numbers.
- enum Type {
- CALL = 0,
- EVENT_CALLBACK = 1,
- UNKNOWN_TYPE = 2,
- };
-
- static const char* kAlwaysLog[];
- static const int kSizeAlwaysLog;
-
- static const char* kIncognitoUrl;
-
- // Create a new APIAction to describe a successful API call. All
- // parameters are required.
- APIAction(const std::string& extension_id,
- const base::Time& time,
- const Type type, // e.g. "CALL"
- const std::string& api_call, // full method name
- const std::string& args, // the argument list
- const base::ListValue& args_list, // same as above, as a list
- const std::string& extra); // any extra logging info
-
- // Record the action in the database.
- virtual bool Record(sql::Connection* db) OVERRIDE;
-
- virtual scoped_ptr<api::activity_log_private::ExtensionActivity>
- ConvertToExtensionActivity() OVERRIDE;
-
- // Used to associate tab IDs with URLs. It will swap out the int in args with
- // a URL as a string. If the tab is in incognito mode, we leave it alone as
- // the original int. There is a small chance that the URL translation could
- // be wrong, if the tab has already been navigated by the time of invocation.
- static void LookupTabId(const std::string& api_call,
- base::ListValue* args,
- Profile* profile);
-
- // Print a APIAction as a regular string for debugging purposes.
- virtual std::string PrintForDebug() OVERRIDE;
-
- // Helper methods for recording the values into the db.
- const std::string& api_call() const { return api_call_; }
- const std::string& args() const { return args_; }
- std::string TypeAsString() const;
- std::string extra() const { return extra_; }
-
- protected:
- virtual ~APIAction();
-
- private:
- Type type_;
- std::string api_call_;
- std::string args_;
- scoped_ptr<base::ListValue> args_list_;
- std::string extra_;
-
- DISALLOW_COPY_AND_ASSIGN(APIAction);
-};
-
-} // namespace extensions
-
-#endif // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_API_ACTIONS_H_
diff --git a/chrome/browser/extensions/activity_log/blocked_actions.cc b/chrome/browser/extensions/activity_log/blocked_actions.cc
deleted file mode 100644
index 3ac47a1..0000000
--- a/chrome/browser/extensions/activity_log/blocked_actions.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// 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.
-
-#include "base/json/json_string_value_serializer.h"
-#include "base/logging.h"
-#include "base/strings/stringprintf.h"
-#include "chrome/browser/extensions/activity_log/blocked_actions.h"
-#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
-#include "content/public/browser/browser_thread.h"
-
-using content::BrowserThread;
-
-namespace extensions {
-
-using api::activity_log_private::ExtensionActivity;
-using api::activity_log_private::DomActivityDetail;
-using api::activity_log_private::ChromeActivityDetail;
-using api::activity_log_private::BlockedChromeActivityDetail;
-
-BlockedAction::BlockedAction(const std::string& extension_id,
- const base::Time& time,
- const std::string& api_call,
- const std::string& args,
- const BlockedAction::Reason reason,
- const std::string& extra)
- : Action(extension_id,
- time,
- ExtensionActivity::ACTIVITY_TYPE_BLOCKED_CHROME),
- api_call_(api_call),
- args_(args),
- reason_(reason),
- extra_(extra) { }
-
-BlockedAction::~BlockedAction() {
-}
-
-scoped_ptr<ExtensionActivity> BlockedAction::ConvertToExtensionActivity() {
- scoped_ptr<ExtensionActivity> formatted_activity;
- formatted_activity.reset(new ExtensionActivity);
- formatted_activity->extension_id.reset(
- new std::string(extension_id()));
- formatted_activity->activity_type = activity_type();
- formatted_activity->time.reset(new double(time().ToJsTime()));
- BlockedChromeActivityDetail* details = new BlockedChromeActivityDetail;
- details->api_call.reset(new std::string(api_call_));
- details->args.reset(new std::string(args_));
- details->reason = BlockedChromeActivityDetail::ParseReason(
- ReasonAsString());
- details->extra.reset(new std::string(extra_));
- formatted_activity->blocked_chrome_activity_detail.reset(details);
- return formatted_activity.Pass();
-}
-
-bool BlockedAction::Record(sql::Connection* db) {
- std::string sql_str =
- "INSERT INTO " + std::string(FullStreamUIPolicy::kTableName) +
- " (extension_id, time, action_type, api_name, args, other) VALUES"
- " (?,?,?,?,?,?)";
- sql::Statement statement(db->GetCachedStatement(
- sql::StatementID(SQL_FROM_HERE), sql_str.c_str()));
- statement.BindString(0, extension_id());
- statement.BindInt64(1, time().ToInternalValue());
- statement.BindInt(2, static_cast<int>(Action::ACTION_API_BLOCKED));
- statement.BindString(3, api_call_);
- statement.BindString(4, args_);
-
- DictionaryValue other;
- other.SetInteger("reason", static_cast<int>(reason_));
- std::string other_string;
- JSONStringValueSerializer other_serializer(&other_string);
- other_serializer.SerializeAndOmitBinaryValues(other);
- statement.BindString(5, other_string);
-
- if (!statement.Run()) {
- LOG(ERROR) << "Activity log database I/O failed: " << sql_str;
- statement.Clear();
- return false;
- }
- return true;
-}
-
-std::string BlockedAction::PrintForDebug() {
- return "ID: " + extension_id() + ", blocked action " + api_call_ +
- ", reason: " + ReasonAsString();
-}
-
-std::string BlockedAction::ReasonAsString() const {
- if (reason_ == ACCESS_DENIED)
- return std::string("access_denied");
- else if (reason_ == QUOTA_EXCEEDED)
- return std::string("quota_exceeded");
- else
- return std::string("unknown_reason_type"); // To avoid Win header name.
-}
-
-} // namespace extensions
-
diff --git a/chrome/browser/extensions/activity_log/blocked_actions.h b/chrome/browser/extensions/activity_log/blocked_actions.h
deleted file mode 100644
index e6f4beb..0000000
--- a/chrome/browser/extensions/activity_log/blocked_actions.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// 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_BLOCKED_ACTIONS_H_
-#define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_BLOCKED_ACTIONS_H_
-
-#include "chrome/browser/extensions/activity_log/activity_actions.h"
-
-namespace extensions {
-
-// This class describes API calls that ran into permissions or quota problems.
-// See APIActions for API calls that succeeded.
-class BlockedAction : public Action {
- public:
- // These values should not be changed. Append any additional values to the
- // end with sequential numbers.
- enum Reason {
- UNKNOWN = 0,
- ACCESS_DENIED = 1,
- QUOTA_EXCEEDED = 2,
- };
-
- // You must supply the id, time, api_call, and reason.
- BlockedAction(const std::string& extension_id,
- const base::Time& time,
- const std::string& api_call, // the blocked API call
- const std::string& args, // the arguments
- const Reason reason, // the reason it's blocked
- const std::string& extra); // any extra logging info
-
- // Record the action in the database.
- virtual bool Record(sql::Connection* db) OVERRIDE;
-
- virtual scoped_ptr<api::activity_log_private::ExtensionActivity>
- ConvertToExtensionActivity() OVERRIDE;
-
- // Print a BlockedAction as a string for debugging purposes.
- virtual std::string PrintForDebug() OVERRIDE;
-
- // Helper methods for recording the values into the db.
- const std::string& api_call() const { return api_call_; }
- const std::string& args() const { return args_; }
- const std::string& extra() const { return extra_; }
-
- // Helper method for debugging.
- std::string ReasonAsString() const;
-
- protected:
- virtual ~BlockedAction();
-
- private:
- std::string api_call_;
- std::string args_;
- Reason reason_;
- std::string extra_;
-
- DISALLOW_COPY_AND_ASSIGN(BlockedAction);
-};
-
-} // namespace extensions
-
-#endif // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_BLOCKED_ACTIONS_H_
-
diff --git a/chrome/browser/extensions/activity_log/dom_actions.cc b/chrome/browser/extensions/activity_log/dom_actions.cc
deleted file mode 100644
index 9158abb..0000000
--- a/chrome/browser/extensions/activity_log/dom_actions.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-// 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.
-
-#include "base/command_line.h"
-#include "base/json/json_string_value_serializer.h"
-#include "base/logging.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/extensions/activity_log/dom_actions.h"
-#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
-#include "chrome/browser/history/url_database.h"
-#include "chrome/common/chrome_switches.h"
-#include "content/public/browser/browser_thread.h"
-
-using content::BrowserThread;
-
-namespace extensions {
-
-using api::activity_log_private::ExtensionActivity;
-using api::activity_log_private::DomActivityDetail;
-using api::activity_log_private::ChromeActivityDetail;
-using api::activity_log_private::BlockedChromeActivityDetail;
-
-DOMAction::DOMAction(const std::string& extension_id,
- const base::Time& time,
- const DomActionType::Type verb,
- const GURL& url,
- const string16& url_title,
- const std::string& api_call,
- const std::string& args,
- const std::string& extra)
- : Action(extension_id, time, ExtensionActivity::ACTIVITY_TYPE_DOM),
- verb_(verb),
- url_(url),
- url_title_(url_title),
- api_call_(api_call),
- args_(args),
- extra_(extra) { }
-
-DOMAction::~DOMAction() {
-}
-
-scoped_ptr<ExtensionActivity> DOMAction::ConvertToExtensionActivity() {
- scoped_ptr<ExtensionActivity> formatted_activity;
- formatted_activity.reset(new ExtensionActivity);
- formatted_activity->extension_id.reset(
- new std::string(extension_id()));
- formatted_activity->activity_type = activity_type();
- formatted_activity->time.reset(new double(time().ToJsTime()));
- DomActivityDetail* details = new DomActivityDetail;
- details->dom_activity_type = DomActivityDetail::ParseDomActivityType(
- VerbAsString());
- details->url.reset(new std::string(url_.spec()));
- details->url_title.reset(new std::string(base::UTF16ToUTF8(url_title_)));
- details->api_call.reset(new std::string(api_call_));
- details->args.reset(new std::string(args_));
- details->extra.reset(new std::string(extra_));
- formatted_activity->dom_activity_detail.reset(details);
- return formatted_activity.Pass();
-}
-
-bool DOMAction::Record(sql::Connection* db) {
- std::string sql_str = "INSERT INTO " +
- std::string(FullStreamUIPolicy::kTableName) +
- " (extension_id, time, action_type, api_name, args, "
- "page_url, arg_url, other) VALUES (?,?,?,?,?,?,?,?)";
- sql::Statement statement(db->GetCachedStatement(
- sql::StatementID(SQL_FROM_HERE), sql_str.c_str()));
- statement.BindString(0, extension_id());
- statement.BindInt64(1, time().ToInternalValue());
- if (verb_ == DomActionType::INSERTED)
- statement.BindInt(2, static_cast<int>(Action::ACTION_CONTENT_SCRIPT));
- else
- statement.BindInt(2, static_cast<int>(Action::ACTION_DOM_ACCESS));
- statement.BindString(3, api_call_);
-
- ListValue args_list;
- args_list.AppendString(args_);
- std::string args_as_text;
- JSONStringValueSerializer serializer(&args_as_text);
- serializer.SerializeAndOmitBinaryValues(args_list);
- statement.BindString(4, args_as_text);
-
- // If running in activity testing mode, store the URL parameters as well.
- GURL database_url;
- if ((CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableExtensionActivityLogTesting))) {
- database_url = url_;
- } else {
- url_canon::Replacements<char> sanitize;
- sanitize.ClearQuery();
- sanitize.ClearRef();
- database_url = url_.ReplaceComponents(sanitize);
- }
- statement.BindString(5, database_url.spec());
-
- if (verb_ == DomActionType::INSERTED)
- statement.BindString(6, args_);
- else
- statement.BindNull(6);
-
- DictionaryValue other;
- other.SetString("extra", extra_);
- other.SetString("page_title", url_title_);
- other.SetInteger("dom_verb", static_cast<int>(verb_));
- std::string other_string;
- JSONStringValueSerializer other_serializer(&other_string);
- other_serializer.SerializeAndOmitBinaryValues(other);
- statement.BindString(7, other_string);
-
- if (!statement.Run()) {
- LOG(ERROR) << "Activity log database I/O failed: " << sql_str;
- statement.Clear();
- return false;
- }
- return true;
-}
-
-std::string DOMAction::PrintForDebug() {
- if (verb_ == DomActionType::INSERTED)
- return "Injected scripts (" + args_ + ") onto "
- + std::string(url_.spec()) + (extra_.empty() ? extra_ : " " + extra_);
- else
- return "DOM API CALL: " + api_call_ + ", ARGS: " + args_ + ", VERB: "
- + VerbAsString();
-}
-
-std::string DOMAction::VerbAsString() const {
- switch (verb_) {
- case DomActionType::GETTER:
- return "getter";
- case DomActionType::SETTER:
- return "setter";
- case DomActionType::METHOD:
- return "method";
- case DomActionType::INSERTED:
- return "inserted";
- case DomActionType::XHR:
- return "xhr";
- case DomActionType::WEBREQUEST:
- return "webrequest";
- case DomActionType::MODIFIED: // legacy
- return "modified";
- default:
- NOTREACHED();
- return NULL;
- }
-}
-
-} // namespace extensions
diff --git a/chrome/browser/extensions/activity_log/dom_actions.h b/chrome/browser/extensions/activity_log/dom_actions.h
deleted file mode 100644
index 9129a39..0000000
--- a/chrome/browser/extensions/activity_log/dom_actions.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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_DOM_ACTIONS_H_
-#define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_DOM_ACTIONS_H_
-
-#include "base/strings/string16.h"
-#include "chrome/browser/extensions/activity_log/activity_actions.h"
-#include "chrome/common/extensions/dom_action_types.h"
-#include "url/gurl.h"
-
-namespace extensions {
-
-// This class describes extension actions that pertain to DOM API calls and
-// content script insertions.
-class DOMAction : public Action {
- public:
- // Create a new DOMAction to describe a new DOM API call.
- // If the DOMAction is on a background page, the url & url_title may be null.
- // If the DOMAction refers to a content script insertion, api_call may be null
- // but args should be the name of the content script.
- DOMAction(const std::string& extension_id,
- const base::Time& time,
- const DomActionType::Type verb, // what happened
- const GURL& url, // the url of the page the
- // script is running on
- const string16& url_title, // the page title
- const std::string& api_call, // the DOM API call
- const std::string& args, // the args
- const std::string& extra); // any extra logging info
-
- virtual scoped_ptr<api::activity_log_private::ExtensionActivity>
- ConvertToExtensionActivity() OVERRIDE;
-
- // Record the action in the database.
- virtual bool Record(sql::Connection* db) OVERRIDE;
-
- // Print a DOMAction as a regular string for debugging purposes.
- virtual std::string PrintForDebug() OVERRIDE;
-
- // Helper methods for retrieving the values and debugging.
- std::string VerbAsString() const;
- const GURL& url() const { return url_; }
- const string16& url_title() const { return url_title_; }
- const std::string& api_call() const { return api_call_; }
- const std::string& args() const { return args_; }
- const std::string& extra() const { return extra_; }
-
- protected:
- virtual ~DOMAction();
-
- private:
- DomActionType::Type verb_;
- GURL url_;
- string16 url_title_;
- std::string api_call_;
- std::string args_;
- std::string extra_;
-
- DISALLOW_COPY_AND_ASSIGN(DOMAction);
-};
-
-} // namespace extensions
-
-#endif // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_DOM_ACTIONS_H_
-
diff --git a/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc b/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc
index a6f7b22..a8cc82d 100644
--- a/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc
+++ b/chrome/browser/extensions/activity_log/fullstream_ui_policy.cc
@@ -8,9 +8,6 @@
#include "base/strings/string16.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/extensions/activity_log/activity_database.h"
-#include "chrome/browser/extensions/activity_log/api_actions.h"
-#include "chrome/browser/extensions/activity_log/blocked_actions.h"
-#include "chrome/browser/extensions/activity_log/dom_actions.h"
#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_constants.h"
@@ -45,11 +42,11 @@ namespace extensions {
const char* FullStreamUIPolicy::kTableName = "activitylog_full";
const char* FullStreamUIPolicy::kTableContentFields[] = {
"extension_id", "time", "action_type", "api_name", "args", "page_url",
- "arg_url", "other"
+ "page_title", "arg_url", "other"
};
const char* FullStreamUIPolicy::kTableFieldTypes[] = {
"LONGVARCHAR NOT NULL", "INTEGER", "INTEGER", "LONGVARCHAR", "LONGVARCHAR",
- "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR"
+ "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR"
};
const int FullStreamUIPolicy::kTableFieldCount = arraysize(kTableContentFields);
@@ -123,14 +120,8 @@ std::string FullStreamUIPolicy::GetKey(ActivityLogPolicy::KeyType key_ty) const
}
}
-scoped_ptr<base::ListValue> FullStreamUIPolicy::ProcessArguments(
- ActionType action_type,
- const std::string& name,
- const base::ListValue* args) const {
- if (args)
- return make_scoped_ptr(args->DeepCopy());
- else
- return scoped_ptr<base::ListValue>();
+void FullStreamUIPolicy::ProcessArguments(scoped_refptr<Action> action) const {
+ return;
}
std::string FullStreamUIPolicy::JoinArguments(
@@ -163,105 +154,12 @@ void FullStreamUIPolicy::ProcessWebRequestModifications(
serializer.Serialize(details);
}
-void FullStreamUIPolicy::ProcessAction(
- ActionType action_type,
- const std::string& extension_id,
- const std::string& name,
- const GURL& url_param,
- const base::ListValue* args_in,
- const DictionaryValue* details) {
- scoped_ptr<base::ListValue> args =
- ProcessArguments(action_type, name, args_in);
- std::string concatenated_args = JoinArguments(action_type, name, args.get());
- const Time now = Time::Now();
- scoped_refptr<Action> action;
- std::string extra;
- if (details) {
- details->GetString(GetKey(PARAM_KEY_EXTRA), &extra);
- }
-
- switch (action_type) {
- case ACTION_API: {
- action = new APIAction(
- extension_id,
- now,
- APIAction::CALL,
- name,
- concatenated_args,
- *args,
- extra);
- break;
- }
- case ACTION_EVENT: {
- action = new APIAction(
- extension_id,
- now,
- APIAction::EVENT_CALLBACK,
- name,
- concatenated_args,
- *args,
- extra);
- break;
- }
- case ACTION_BLOCKED: {
- int reason = 0;
- if (details) {
- details->GetInteger(GetKey(PARAM_KEY_REASON), &reason);
- }
-
- action = new BlockedAction(
- extension_id,
- now,
- name,
- concatenated_args,
- static_cast<BlockedAction::Reason>(reason),
- extra);
- break;
- }
- case ACTION_DOM: {
- string16 value;
- DomActionType::Type action_type = DomActionType::MODIFIED;
-
- if (details) {
- int action_id = 0;
- details->GetInteger(GetKey(PARAM_KEY_DOM_ACTION), &action_id);
- action_type = static_cast<DomActionType::Type>(action_id);
- details->GetString(GetKey(PARAM_KEY_URL_TITLE), &value);
- }
-
- action = new DOMAction(
- extension_id,
- now,
- action_type,
- url_param,
- value,
- name,
- concatenated_args,
- extra);
- break;
- }
- case ACTION_WEB_REQUEST: {
- std::string details_string;
- if (details) {
- scoped_ptr<DictionaryValue> copy_of_details(details->DeepCopy());
- ProcessWebRequestModifications(*copy_of_details.get(), details_string);
- }
-
- action = new DOMAction(
- extension_id,
- now,
- DomActionType::WEBREQUEST,
- url_param,
- string16(),
- name,
- details_string,
- extra);
- break;
- }
- default:
- NOTREACHED();
- }
-
+void FullStreamUIPolicy::ProcessAction(scoped_refptr<Action> action) {
+ // TODO(mvrable): Right now this argument stripping updates the Action object
+ // in place, which isn't good if there are other users of the object. When
+ // database writing is moved to policy class, the modifications should be
+ // made locally.
+ ProcessArguments(action);
ScheduleAndForget(db_, &ActivityDatabase::RecordAction, action);
}
diff --git a/chrome/browser/extensions/activity_log/fullstream_ui_policy.h b/chrome/browser/extensions/activity_log/fullstream_ui_policy.h
index f915ad5..8ff9c61 100644
--- a/chrome/browser/extensions/activity_log/fullstream_ui_policy.h
+++ b/chrome/browser/extensions/activity_log/fullstream_ui_policy.h
@@ -22,11 +22,7 @@ class FullStreamUIPolicy : public ActivityLogPolicy,
// For more info about these member functions, see the super class.
explicit FullStreamUIPolicy(Profile* profile);
- virtual void ProcessAction(ActionType action_type,
- const std::string& extension_id,
- const std::string& name, const GURL& gurl,
- const base::ListValue* args,
- const base::DictionaryValue* details) OVERRIDE;
+ virtual void ProcessAction(scoped_refptr<Action> action) OVERRIDE;
// TODO(felt,dbabic) This is overly specific to FullStreamUIPolicy.
// It assumes that the callback can return a sorted vector of actions. Some
@@ -62,10 +58,7 @@ class FullStreamUIPolicy : public ActivityLogPolicy,
virtual void OnDatabaseClose() OVERRIDE;
// Strips arguments if needed by policy.
- virtual scoped_ptr<base::ListValue> ProcessArguments(
- ActionType action_type,
- const std::string& name,
- const base::ListValue* args) const;
+ virtual void ProcessArguments(scoped_refptr<Action> action) const;
// Concatenates arguments.
virtual std::string JoinArguments(ActionType action_type,
diff --git a/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc b/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc
index af735b9..860a6b9 100644
--- a/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc
+++ b/chrome/browser/extensions/activity_log/fullstream_ui_policy_unittest.cc
@@ -68,7 +68,7 @@ class FullStreamUIPolicyTest : public testing::Test {
scoped_refptr<Action> last = i->front();
std::string args =
"ID=odlameecjipmbmbejkplpemijjgpljce CATEGORY=api_call "
- "API=extension.connect ARGS=[\"hello\",\"world\"] OTHER={}";
+ "API=extension.connect ARGS=[\"hello\",\"world\"]";
ASSERT_EQ(args, last->PrintForDebug());
}
@@ -100,8 +100,12 @@ TEST_F(FullStreamUIPolicyTest, Construct) {
.Build();
extension_service_->AddExtension(extension.get());
scoped_ptr<base::ListValue> args(new base::ListValue());
- policy->ProcessAction(ActivityLogPolicy::ACTION_API, extension->id(),
- std::string("tabs.testMethod"), GURL(), args.get(), NULL);
+ scoped_refptr<Action> action = new Action(extension->id(),
+ base::Time::Now(),
+ Action::ACTION_API_CALL,
+ "tabs.testMethod");
+ action->set_args(args.Pass());
+ policy->ProcessAction(action);
policy->Close();
}
@@ -115,15 +119,24 @@ TEST_F(FullStreamUIPolicyTest, LogAndFetchActions) {
.Set("manifest_version", 2))
.Build();
extension_service_->AddExtension(extension.get());
- scoped_ptr<base::ListValue> args(new base::ListValue());
GURL gurl("http://www.google.com");
// Write some API calls
- policy->ProcessAction(ActivityLogPolicy::ACTION_API, extension->id(),
- std::string("tabs.testMethod"), GURL(), args.get(), NULL);
- policy->ProcessAction(ActivityLogPolicy::ACTION_DOM,
- extension->id(), std::string("document.write"),
- gurl, args.get(), NULL);
+ scoped_refptr<Action> action_api = new Action(extension->id(),
+ base::Time::Now(),
+ Action::ACTION_API_CALL,
+ "tabs.testMethod");
+ action_api->set_args(make_scoped_ptr(new base::ListValue()));
+ policy->ProcessAction(action_api);
+
+ scoped_refptr<Action> action_dom = new Action(extension->id(),
+ base::Time::Now(),
+ Action::ACTION_DOM_ACCESS,
+ "document.write");
+ action_dom->set_args(make_scoped_ptr(new base::ListValue()));
+ action_dom->set_page_url(gurl);
+ policy->ProcessAction(action_dom);
+
policy->ReadData(extension->id(), 0,
base::Bind(FullStreamUIPolicyTest::RetrieveActions_LogAndFetchActions));
@@ -140,11 +153,17 @@ TEST_F(FullStreamUIPolicyTest, LogWithArguments) {
.Set("manifest_version", 2))
.Build();
extension_service_->AddExtension(extension.get());
+
scoped_ptr<base::ListValue> args(new base::ListValue());
args->Set(0, new base::StringValue("hello"));
args->Set(1, new base::StringValue("world"));
- policy->ProcessAction(ActivityLogPolicy::ACTION_API, extension->id(),
- std::string("extension.connect"), GURL(), args.get(), NULL);
+ scoped_refptr<Action> action = new Action(extension->id(),
+ base::Time::Now(),
+ Action::ACTION_API_CALL,
+ "extension.connect");
+ action->set_args(args.Pass());
+
+ policy->ProcessAction(action);
policy->ReadData(extension->id(), 0,
base::Bind(FullStreamUIPolicyTest::Arguments_Present));
policy->Close();
diff --git a/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.cc b/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.cc
index 180b802..f977cc6 100644
--- a/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.cc
+++ b/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.cc
@@ -16,15 +16,16 @@ StreamWithoutArgsUIPolicy::StreamWithoutArgsUIPolicy(Profile* profile)
StreamWithoutArgsUIPolicy::~StreamWithoutArgsUIPolicy() {}
-scoped_ptr<base::ListValue> StreamWithoutArgsUIPolicy::ProcessArguments(
- ActionType action_type,
- const std::string& name,
- const base::ListValue* args) const {
- if (action_type == ACTION_DOM ||
- arg_whitelist_api_.find(name) != arg_whitelist_api_.end()) {
- return FullStreamUIPolicy::ProcessArguments(action_type, name, args).Pass();
+void StreamWithoutArgsUIPolicy::ProcessArguments(
+ scoped_refptr<Action> action) const {
+ if (action->action_type() == Action::ACTION_DOM_ACCESS ||
+ action->action_type() == Action::ACTION_DOM_EVENT ||
+ action->action_type() == Action::ACTION_DOM_XHR ||
+ action->action_type() == Action::ACTION_WEB_REQUEST ||
+ arg_whitelist_api_.find(action->api_name()) != arg_whitelist_api_.end()) {
+ // No stripping of arguments
} else {
- return make_scoped_ptr(new ListValue());
+ action->set_args(scoped_ptr<ListValue>());
}
}
diff --git a/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.h b/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.h
index 46064b9d..b87c5c7 100644
--- a/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.h
+++ b/chrome/browser/extensions/activity_log/stream_noargs_ui_policy.h
@@ -7,7 +7,6 @@
#include <string>
#include "base/containers/hash_tables.h"
-#include "chrome/browser/extensions/activity_log/api_actions.h"
#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
namespace extensions {
@@ -19,10 +18,8 @@ class StreamWithoutArgsUIPolicy : public FullStreamUIPolicy {
virtual ~StreamWithoutArgsUIPolicy();
protected:
- virtual scoped_ptr<base::ListValue> ProcessArguments(
- ActionType action_type,
- const std::string& name,
- const base::ListValue* args) const OVERRIDE;
+ virtual void ProcessArguments(scoped_refptr<Action> action) const
+ OVERRIDE;
virtual void ProcessWebRequestModifications(
base::DictionaryValue& details,
diff --git a/chrome/browser/extensions/activity_log/stream_noargs_ui_policy_unittest.cc b/chrome/browser/extensions/activity_log/stream_noargs_ui_policy_unittest.cc
index 1a5dd4a..5c5207a 100644
--- a/chrome/browser/extensions/activity_log/stream_noargs_ui_policy_unittest.cc
+++ b/chrome/browser/extensions/activity_log/stream_noargs_ui_policy_unittest.cc
@@ -68,7 +68,7 @@ class StreamWithoutArgsUIPolicyTest : public testing::Test {
scoped_refptr<Action> last = i->front();
std::string noargs =
"ID=odlameecjipmbmbejkplpemijjgpljce CATEGORY=api_call "
- "API=tabs.testMethod ARGS=[] OTHER={}";
+ "API=tabs.testMethod";
ASSERT_EQ(noargs, last->PrintForDebug());
}
@@ -100,8 +100,12 @@ TEST_F(StreamWithoutArgsUIPolicyTest, Construct) {
.Build();
extension_service_->AddExtension(extension.get());
scoped_ptr<base::ListValue> args(new base::ListValue());
- policy->ProcessAction(ActivityLogPolicy::ACTION_API, extension->id(),
- std::string("tabs.testMethod"), GURL(), args.get(), NULL);
+ scoped_refptr<Action> action = new Action(extension->id(),
+ base::Time::Now(),
+ Action::ACTION_API_CALL,
+ "tabs.testMethod");
+ action->set_args(args.Pass());
+ policy->ProcessAction(action);
policy->Close();
}
@@ -115,15 +119,24 @@ TEST_F(StreamWithoutArgsUIPolicyTest, LogAndFetchActions) {
.Set("manifest_version", 2))
.Build();
extension_service_->AddExtension(extension.get());
- scoped_ptr<base::ListValue> args(new base::ListValue());
GURL gurl("http://www.google.com");
// Write some API calls
- policy->ProcessAction(ActivityLogPolicy::ACTION_API, extension->id(),
- std::string("tabs.testMethod"), GURL(), args.get(), NULL);
- policy->ProcessAction(ActivityLogPolicy::ACTION_DOM,
- extension->id(), std::string("document.write"),
- gurl, args.get(), NULL);
+ scoped_refptr<Action> action_api = new Action(extension->id(),
+ base::Time::Now(),
+ Action::ACTION_API_CALL,
+ "tabs.testMethod");
+ action_api->set_args(make_scoped_ptr(new base::ListValue()));
+ policy->ProcessAction(action_api);
+
+ scoped_refptr<Action> action_dom = new Action(extension->id(),
+ base::Time::Now(),
+ Action::ACTION_DOM_ACCESS,
+ "document.write");
+ action_dom->set_args(make_scoped_ptr(new base::ListValue()));
+ action_dom->set_page_url(gurl);
+ policy->ProcessAction(action_dom);
+
policy->ReadData(extension->id(), 0,
base::Bind(
StreamWithoutArgsUIPolicyTest::RetrieveActions_LogAndFetchActions));
@@ -141,11 +154,17 @@ TEST_F(StreamWithoutArgsUIPolicyTest, LogWithoutArguments) {
.Set("manifest_version", 2))
.Build();
extension_service_->AddExtension(extension.get());
+
scoped_ptr<base::ListValue> args(new base::ListValue());
args->Set(0, new base::StringValue("hello"));
args->Set(1, new base::StringValue("world"));
- policy->ProcessAction(ActivityLogPolicy::ACTION_API, extension->id(),
- std::string("tabs.testMethod"), GURL(), args.get(), NULL);
+ scoped_refptr<Action> action = new Action(extension->id(),
+ base::Time::Now(),
+ Action::ACTION_API_CALL,
+ "tabs.testMethod");
+ action->set_args(args.Pass());
+
+ policy->ProcessAction(action);
policy->ReadData(extension->id(), 0,
base::Bind(StreamWithoutArgsUIPolicyTest::Arguments_Missing));
policy->Close();
diff --git a/chrome/browser/extensions/api/activity_log_private/activity_log_private_api_unittest.cc b/chrome/browser/extensions/api/activity_log_private/activity_log_private_api_unittest.cc
index 841f09d..1431259 100644
--- a/chrome/browser/extensions/api/activity_log_private/activity_log_private_api_unittest.cc
+++ b/chrome/browser/extensions/api/activity_log_private/activity_log_private_api_unittest.cc
@@ -28,6 +28,10 @@ using api::activity_log_private::ExtensionActivity;
class ActivityLogApiUnitTest : public testing::Test {
};
+// TODO(felt): These are the old unit tests from before the activity log Action
+// class and database refactoring. These need to be updated, but since the
+// private API will be reworked anyway these are just disabled for now.
+#if 0
TEST_F(ActivityLogApiUnitTest, ConvertBlockedAction) {
scoped_refptr<Action> action(
new BlockedAction(kExtensionId,
@@ -101,6 +105,6 @@ TEST_F(ActivityLogApiUnitTest, ConvertDomAction) {
ASSERT_EQ(kExtra,
*(result->dom_activity_detail->extra.get()));
}
+#endif
-} // extensions
-
+} // namespace extensions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 1109652..ac2acae 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -13,7 +13,6 @@
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/activity_log/activity_log.h"
-#include "chrome/browser/extensions/activity_log/blocked_actions.h"
#include "chrome/browser/extensions/extension_function_registry.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.cc b/chrome/browser/renderer_host/chrome_render_message_filter.cc
index 4829231..7ca57b5 100644
--- a/chrome/browser/renderer_host/chrome_render_message_filter.cc
+++ b/chrome/browser/renderer_host/chrome_render_message_filter.cc
@@ -14,8 +14,6 @@
#include "chrome/browser/content_settings/cookie_settings.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/browser/extensions/activity_log/activity_log.h"
-#include "chrome/browser/extensions/activity_log/blocked_actions.h"
-#include "chrome/browser/extensions/activity_log/dom_actions.h"
#include "chrome/browser/extensions/api/messaging/message_service.h"
#include "chrome/browser/extensions/event_router.h"
#include "chrome/browser/extensions/extension_process_manager.h"
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index a233a96..724e640 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -66,8 +66,10 @@
'browser/apps/shortcut_manager_factory.h',
'browser/extensions/active_tab_permission_granter.cc',
'browser/extensions/active_tab_permission_granter.h',
- 'browser/extensions/activity_log/activity_actions.h',
+ 'browser/extensions/activity_log/activity_action_constants.cc',
+ 'browser/extensions/activity_log/activity_action_constants.h',
'browser/extensions/activity_log/activity_actions.cc',
+ 'browser/extensions/activity_log/activity_actions.h',
'browser/extensions/activity_log/activity_database.cc',
'browser/extensions/activity_log/activity_database.h',
'browser/extensions/activity_log/activity_log.cc',
@@ -78,13 +80,7 @@
'browser/extensions/activity_log/fullstream_ui_policy.h',
'browser/extensions/activity_log/stream_noargs_ui_policy.cc',
'browser/extensions/activity_log/stream_noargs_ui_policy.h',
- 'browser/extensions/activity_log/api_actions.cc',
- 'browser/extensions/activity_log/api_actions.h',
'browser/extensions/activity_log/api_name_constants.h',
- 'browser/extensions/activity_log/blocked_actions.cc',
- 'browser/extensions/activity_log/blocked_actions.h',
- 'browser/extensions/activity_log/dom_actions.cc',
- 'browser/extensions/activity_log/dom_actions.h',
'browser/extensions/activity_log/web_request_constants.cc',
'browser/extensions/activity_log/web_request_constants.h',
'browser/extensions/admin_policy.cc',