Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/logging.h" | 5 #include "base/logging.h" |
| 6 #include "base/string_number_conversions.h" | |
| 6 #include "base/stringprintf.h" | 7 #include "base/stringprintf.h" |
| 7 #include "chrome/browser/extensions/activity_log/api_actions.h" | 8 #include "chrome/browser/extensions/activity_log/api_actions.h" |
| 9 #include "chrome/browser/extensions/activity_log/api_name_constants.h" | |
| 8 #include "chrome/browser/extensions/extension_tab_util.h" | 10 #include "chrome/browser/extensions/extension_tab_util.h" |
| 9 #include "content/public/browser/browser_thread.h" | 11 #include "content/public/browser/browser_thread.h" |
| 10 #include "content/public/browser/web_contents.h" | 12 #include "content/public/browser/web_contents.h" |
| 11 #include "googleurl/src/gurl.h" | 13 #include "googleurl/src/gurl.h" |
| 12 | 14 |
| 13 using content::BrowserThread; | 15 using content::BrowserThread; |
| 14 | 16 |
| 15 namespace { | 17 namespace { |
| 16 | 18 |
| 17 // Gets the URL for a given tab ID. Helper method for APIAction::LookupTabId. | 19 // Gets the URL for a given tab ID. Helper method for APIAction::LookupTabId. |
| 18 std::string GetURLForTabId(const int tab_id, Profile* profile) { | 20 std::string GetURLForTabId(const int tab_id, Profile* profile) { |
| 19 content::WebContents* contents = NULL; | 21 content::WebContents* contents = NULL; |
| 20 bool found = ExtensionTabUtil::GetTabById(tab_id, | 22 bool found = ExtensionTabUtil::GetTabById(tab_id, |
| 21 profile, | 23 profile, |
| 22 false, // no incognito URLs | 24 false, // no incognito URLs |
| 23 NULL, | 25 NULL, |
| 24 NULL, | 26 NULL, |
| 25 &contents, | 27 &contents, |
| 26 NULL); | 28 NULL); |
| 27 if (found) { | 29 if (found) { |
| 28 GURL url = contents->GetURL(); | 30 GURL url = contents->GetURL(); |
| 29 return std::string(url.spec()); | 31 return std::string(url.spec()); |
| 30 } else { | 32 } else { |
| 31 return std::string(); | 33 return std::string(); |
| 32 } | 34 } |
| 33 } | 35 } |
| 34 | 36 |
| 37 // Sets up the hashmap for mapping extension strings to "ints". The hashmap is | |
| 38 // only set up once because it's quite long; the value is then cached. | |
| 39 class APINameMap { | |
| 40 public: | |
| 41 APINameMap() { | |
| 42 SetupMap(); | |
| 43 } | |
| 44 | |
| 45 // activity_log_api_name_constants.h lists all known API calls as of 5/17. | |
| 46 // This code maps each of those API calls (and events) to short strings | |
| 47 // (integers converted to strings). They're all strings because (1) sqlite | |
| 48 // databases are all strings underneath anyway and (2) the Lookup function | |
| 49 // will simply return the original api_call string if we don't have it in our | |
| 50 // lookup table. | |
| 51 void SetupMap() { | |
| 52 for (int i = 0; | |
|
Matt Perry
2013/05/20 21:20:48
use size_t here and you can drop the static_cast
felt
2013/05/20 22:34:37
Done.
| |
| 53 i < static_cast<int>arraysize(activity_log_api_name_constants::kNames); | |
| 54 ++i) { | |
| 55 std::string name = | |
| 56 std::string(activity_log_api_name_constants::kNames[i]); | |
| 57 std::string num = base::IntToString(i); | |
| 58 names_to_nums_.insert(std::pair<std::string, std::string>(name, num)); | |
| 59 nums_to_names_.insert(std::pair<std::string, std::string>(num, name)); | |
| 60 } | |
| 61 } | |
| 62 | |
| 63 static APINameMap* GetInstance() { | |
| 64 return Singleton<APINameMap>::get(); | |
| 65 } | |
| 66 | |
| 67 // This matches an api call to a number, if it's in the lookup table. If not, | |
| 68 // it returns the original api call. | |
| 69 const std::string ApiToShortname(const std::string api_call) { | |
|
Matt Perry
2013/05/20 21:20:48
const ref is:
"const std::string& ApiToShortname(c
felt
2013/05/20 22:34:37
Done.
| |
| 70 std::map<std::string, std::string>::iterator it = | |
| 71 names_to_nums_.find(api_call); | |
| 72 if (it == names_to_nums_.end()) | |
| 73 return api_call; | |
| 74 else | |
| 75 return it->second; | |
| 76 } | |
| 77 | |
| 78 // This matches a number to an API call -- it's the opposite of | |
| 79 // ApiToShortname. | |
| 80 const std::string ShortnameToApi(const std::string shortname) { | |
| 81 std::map<std::string, std::string>::iterator it = | |
| 82 nums_to_names_.find(shortname); | |
| 83 if (it == nums_to_names_.end()) | |
| 84 return shortname; | |
| 85 else | |
| 86 return it->second; | |
| 87 } | |
| 88 | |
| 89 private: | |
| 90 std::map<std::string, std::string> names_to_nums_; // <name, number label> | |
| 91 std::map<std::string, std::string> nums_to_names_; // <number label, name> | |
| 92 }; | |
| 93 | |
| 35 } // namespace | 94 } // namespace |
| 36 | 95 |
| 37 namespace extensions { | 96 namespace extensions { |
| 38 | 97 |
| 39 const char* APIAction::kTableName = "activitylog_apis"; | 98 const char* APIAction::kTableName = "activitylog_apis"; |
| 40 const char* APIAction::kTableContentFields[] = | 99 const char* APIAction::kTableContentFields[] = |
| 41 {"api_type", "api_call", "args", "extra"}; | 100 {"api_type", "api_call", "args", "extra"}; |
| 101 const char* APIAction::kTableFieldTypes[] = | |
| 102 {"INTEGER", "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR"}; | |
| 42 | 103 |
| 43 // We should log the arguments to these API calls, even if argument logging is | 104 // We should log the arguments to these API calls, even if argument logging is |
| 44 // disabled by default. | 105 // disabled by default. |
| 45 const char* APIAction::kAlwaysLog[] = | 106 const char* APIAction::kAlwaysLog[] = |
| 46 {"extension.connect", "extension.sendMessage", | 107 {"extension.connect", "extension.sendMessage", |
| 47 "tabs.executeScript", "tabs.insertCSS" }; | 108 "tabs.executeScript", "tabs.insertCSS" }; |
| 48 const int APIAction::kSizeAlwaysLog = arraysize(kAlwaysLog); | 109 const int APIAction::kSizeAlwaysLog = arraysize(kAlwaysLog); |
| 49 | 110 |
| 50 APIAction::APIAction(const std::string& extension_id, | 111 APIAction::APIAction(const std::string& extension_id, |
| 51 const base::Time& time, | 112 const base::Time& time, |
| 52 const Type type, | 113 const Type type, |
| 53 const std::string& api_call, | 114 const std::string& api_call, |
| 54 const std::string& args, | 115 const std::string& args, |
| 55 const std::string& extra) | 116 const std::string& extra) |
| 56 : Action(extension_id, time), | 117 : Action(extension_id, time), |
| 57 type_(type), | 118 type_(type), |
| 58 api_call_(api_call), | 119 api_call_(api_call), |
| 59 args_(args), | 120 args_(args), |
| 60 extra_(extra) { } | 121 extra_(extra) { } |
| 61 | 122 |
| 62 APIAction::APIAction(const sql::Statement& s) | 123 APIAction::APIAction(const sql::Statement& s) |
| 63 : Action(s.ColumnString(0), | 124 : Action(s.ColumnString(0), |
| 64 base::Time::FromInternalValue(s.ColumnInt64(1))), | 125 base::Time::FromInternalValue(s.ColumnInt64(1))), |
| 65 type_(StringAsType(s.ColumnString(2))), | 126 type_(static_cast<Type>(s.ColumnInt(2))), |
| 66 api_call_(s.ColumnString(3)), | 127 api_call_(APINameMap::GetInstance()->ShortnameToApi(s.ColumnString(3))), |
| 67 args_(s.ColumnString(4)), | 128 args_(s.ColumnString(4)), |
| 68 extra_(s.ColumnString(5)) { } | 129 extra_(s.ColumnString(5)) { } |
| 69 | 130 |
| 70 APIAction::~APIAction() { | 131 APIAction::~APIAction() { |
| 71 } | 132 } |
| 72 | 133 |
| 73 // static | 134 // static |
| 74 bool APIAction::InitializeTable(sql::Connection* db) { | 135 bool APIAction::InitializeTable(sql::Connection* db) { |
| 75 // The original table schema was different than the existing one. | 136 // The original table schema was different than the existing one. |
| 76 // We no longer want the api_action_type or target_type columns. | 137 // We no longer want the api_action_type or target_type columns. |
| 77 // Sqlite doesn't let you delete or modify existing columns, so we drop it. | 138 // Sqlite doesn't let you delete or modify existing columns, so we drop it. |
| 78 // Any data loss incurred here doesn't matter since these fields existed | 139 // Any data loss incurred here doesn't matter since these fields existed |
| 79 // before we started using the AL for anything. | 140 // before we started using the AL for anything. |
| 80 if (db->DoesColumnExist(kTableName, "api_action_type")) { | 141 if (db->DoesColumnExist(kTableName, "api_action_type")) { |
| 81 std::string drop_table = base::StringPrintf("DROP TABLE %s", kTableName); | 142 std::string drop_table = base::StringPrintf("DROP TABLE %s", kTableName); |
| 82 if (!db->Execute(drop_table.c_str())) | 143 if (!db->Execute(drop_table.c_str())) |
| 83 return false; | 144 return false; |
| 84 } | 145 } |
| 146 // We also now use INTEGER instead of VARCHAR for api_type. | |
| 147 if (db->DoesColumnExist(kTableName, "api_type")) { | |
| 148 std::string select = base::StringPrintf( | |
| 149 "SELECT api_type FROM %s ORDER BY rowid LIMIT 1", kTableName); | |
| 150 sql::Statement statement(db->GetUniqueStatement(select.c_str())); | |
| 151 if (statement.DeclaredColumnType(0) != sql::COLUMN_TYPE_INTEGER) { | |
| 152 std::string drop_table = base::StringPrintf("DROP TABLE %s", kTableName); | |
| 153 if (!db->Execute(drop_table.c_str())) | |
| 154 return false; | |
| 155 } | |
| 156 } | |
| 85 // Now initialize the table. | 157 // Now initialize the table. |
| 86 return InitializeTableInternal(db, | 158 return InitializeTableInternal(db, |
| 87 kTableName, | 159 kTableName, |
| 88 kTableContentFields, | 160 kTableContentFields, |
| 161 kTableFieldTypes, | |
| 89 arraysize(kTableContentFields)); | 162 arraysize(kTableContentFields)); |
| 90 } | 163 } |
| 91 | 164 |
| 92 void APIAction::Record(sql::Connection* db) { | 165 void APIAction::Record(sql::Connection* db) { |
| 93 std::string sql_str = "INSERT INTO " + std::string(kTableName) | 166 std::string sql_str = "INSERT INTO " + std::string(kTableName) |
| 94 + " (extension_id, time, api_type, api_call, args, extra) VALUES" | 167 + " (extension_id, time, api_type, api_call, args, extra) VALUES" |
| 95 " (?,?,?,?,?,?)"; | 168 " (?,?,?,?,?,?)"; |
| 96 sql::Statement statement(db->GetCachedStatement( | 169 sql::Statement statement(db->GetCachedStatement( |
| 97 sql::StatementID(SQL_FROM_HERE), sql_str.c_str())); | 170 sql::StatementID(SQL_FROM_HERE), sql_str.c_str())); |
| 98 statement.BindString(0, extension_id()); | 171 statement.BindString(0, extension_id()); |
| 99 statement.BindInt64(1, time().ToInternalValue()); | 172 statement.BindInt64(1, time().ToInternalValue()); |
| 100 statement.BindString(2, TypeAsString()); | 173 statement.BindInt(2, static_cast<int>(type_)); |
| 101 statement.BindString(3, api_call_); | 174 statement.BindString(3, APINameMap::GetInstance()->ApiToShortname(api_call_)); |
| 102 statement.BindString(4, args_); | 175 statement.BindString(4, args_); |
| 103 statement.BindString(5, extra_); | 176 statement.BindString(5, extra_); |
| 104 if (!statement.Run()) | 177 if (!statement.Run()) |
| 105 LOG(ERROR) << "Activity log database I/O failed: " << sql_str; | 178 LOG(ERROR) << "Activity log database I/O failed: " << sql_str; |
| 106 } | 179 } |
| 107 | 180 |
| 108 // static | 181 // static |
| 109 void APIAction::LookupTabId(const std::string& api_call, | 182 void APIAction::LookupTabId(const std::string& api_call, |
| 110 ListValue* args, | 183 ListValue* args, |
| 111 Profile* profile) { | 184 Profile* profile) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 156 switch (type_) { | 229 switch (type_) { |
| 157 case CALL: | 230 case CALL: |
| 158 return "CALL"; | 231 return "CALL"; |
| 159 case EVENT_CALLBACK: | 232 case EVENT_CALLBACK: |
| 160 return "EVENT_CALLBACK"; | 233 return "EVENT_CALLBACK"; |
| 161 default: | 234 default: |
| 162 return "UNKNOWN_TYPE"; | 235 return "UNKNOWN_TYPE"; |
| 163 } | 236 } |
| 164 } | 237 } |
| 165 | 238 |
| 166 APIAction::Type APIAction::StringAsType( | |
| 167 const std::string& str) { | |
| 168 if (str == "CALL") { | |
| 169 return CALL; | |
| 170 } else if (str == "EVENT_CALLBACK") { | |
| 171 return EVENT_CALLBACK; | |
| 172 } else { | |
| 173 return UNKNOWN_TYPE; | |
| 174 } | |
| 175 } | |
| 176 | |
| 177 } // namespace extensions | 239 } // namespace extensions |
| 178 | 240 |
| OLD | NEW |