OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/extensions/activity_log.h" | 5 #include "chrome/browser/extensions/activity_log.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/json/json_string_value_serializer.h" | 9 #include "base/json/json_string_value_serializer.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 if (serializer.SerializeAndOmitBinaryValues(**it)) { | 34 if (serializer.SerializeAndOmitBinaryValues(**it)) { |
35 if (it != args->begin()) | 35 if (it != args->begin()) |
36 call_signature += ", "; | 36 call_signature += ", "; |
37 call_signature += arg; | 37 call_signature += arg; |
38 } | 38 } |
39 } | 39 } |
40 call_signature += ")"; | 40 call_signature += ")"; |
41 return call_signature; | 41 return call_signature; |
42 } | 42 } |
43 | 43 |
| 44 // Computes whether the activity log is enabled in this browser (controlled by |
| 45 // command-line flags) and caches the value (which is assumed never to change). |
| 46 class LogIsEnabled { |
| 47 public: |
| 48 LogIsEnabled() { |
| 49 ComputeIsEnabled(); |
| 50 } |
| 51 |
| 52 void ComputeIsEnabled() { |
| 53 enabled_ = CommandLine::ForCurrentProcess()-> |
| 54 HasSwitch(switches::kEnableExtensionActivityLogging) || |
| 55 CommandLine::ForCurrentProcess()-> |
| 56 HasSwitch(switches::kEnableExtensionActivityUI); |
| 57 } |
| 58 |
| 59 static LogIsEnabled* GetInstance() { |
| 60 return Singleton<LogIsEnabled>::get(); |
| 61 } |
| 62 |
| 63 bool enabled() { return enabled_; } |
| 64 |
| 65 private: |
| 66 bool enabled_; |
| 67 }; |
| 68 |
44 } // namespace | 69 } // namespace |
45 | 70 |
46 namespace extensions { | 71 namespace extensions { |
47 | 72 |
| 73 // static |
| 74 bool ActivityLog::IsLogEnabled() { |
| 75 return LogIsEnabled::GetInstance()->enabled(); |
| 76 } |
| 77 |
| 78 // static |
| 79 void ActivityLog::RecomputeLoggingIsEnabled() { |
| 80 return LogIsEnabled::GetInstance()->ComputeIsEnabled(); |
| 81 } |
| 82 |
48 // This handles errors from the database. | 83 // This handles errors from the database. |
49 class KillActivityDatabaseErrorDelegate : public sql::ErrorDelegate { | 84 class KillActivityDatabaseErrorDelegate : public sql::ErrorDelegate { |
50 public: | 85 public: |
51 explicit KillActivityDatabaseErrorDelegate(ActivityLog* backend) | 86 explicit KillActivityDatabaseErrorDelegate(ActivityLog* backend) |
52 : backend_(backend), | 87 : backend_(backend), |
53 scheduled_death_(false) {} | 88 scheduled_death_(false) {} |
54 | 89 |
55 virtual int OnError(int error, | 90 virtual int OnError(int error, |
56 sql::Connection* connection, | 91 sql::Connection* connection, |
57 sql::Statement* stmt) OVERRIDE { | 92 sql::Statement* stmt) OVERRIDE { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 log_activity_to_stdout_ = CommandLine::ForCurrentProcess()-> | 138 log_activity_to_stdout_ = CommandLine::ForCurrentProcess()-> |
104 HasSwitch(switches::kEnableExtensionActivityLogging); | 139 HasSwitch(switches::kEnableExtensionActivityLogging); |
105 log_activity_to_ui_ = CommandLine::ForCurrentProcess()-> | 140 log_activity_to_ui_ = CommandLine::ForCurrentProcess()-> |
106 HasSwitch(switches::kEnableExtensionActivityUI); | 141 HasSwitch(switches::kEnableExtensionActivityUI); |
107 | 142 |
108 // If the database cannot be initialized for some reason, we keep | 143 // If the database cannot be initialized for some reason, we keep |
109 // chugging along but nothing will get recorded. If the UI is | 144 // chugging along but nothing will get recorded. If the UI is |
110 // available, things will still get sent to the UI even if nothing | 145 // available, things will still get sent to the UI even if nothing |
111 // is being written to the database. | 146 // is being written to the database. |
112 db_ = new ActivityDatabase(); | 147 db_ = new ActivityDatabase(); |
113 if (!IsLoggingEnabled()) return; | 148 if (!IsLogEnabled()) return; |
114 FilePath base_dir = profile->GetPath(); | 149 FilePath base_dir = profile->GetPath(); |
115 FilePath database_name = base_dir.Append( | 150 FilePath database_name = base_dir.Append( |
116 chrome::kExtensionActivityLogFilename); | 151 chrome::kExtensionActivityLogFilename); |
117 KillActivityDatabaseErrorDelegate* error_delegate = | 152 KillActivityDatabaseErrorDelegate* error_delegate = |
118 new KillActivityDatabaseErrorDelegate(this); | 153 new KillActivityDatabaseErrorDelegate(this); |
119 db_->SetErrorDelegate(error_delegate); | 154 db_->SetErrorDelegate(error_delegate); |
120 ScheduleAndForget(&ActivityDatabase::Init, | 155 ScheduleAndForget(&ActivityDatabase::Init, |
121 database_name); | 156 database_name); |
122 } | 157 } |
123 | 158 |
124 ActivityLog::~ActivityLog() { | 159 ActivityLog::~ActivityLog() { |
125 } | 160 } |
126 | 161 |
127 // static | 162 // static |
128 ActivityLog* ActivityLog::GetInstance(Profile* profile) { | 163 ActivityLog* ActivityLog::GetInstance(Profile* profile) { |
129 return ActivityLogFactory::GetForProfile(profile); | 164 return ActivityLogFactory::GetForProfile(profile); |
130 } | 165 } |
131 | 166 |
132 bool ActivityLog::IsLoggingEnabled() { | |
133 return (log_activity_to_stdout_ || log_activity_to_ui_); | |
134 } | |
135 | |
136 void ActivityLog::AddObserver(const Extension* extension, | 167 void ActivityLog::AddObserver(const Extension* extension, |
137 ActivityLog::Observer* observer) { | 168 ActivityLog::Observer* observer) { |
138 if (!IsLoggingEnabled()) return; | 169 if (!IsLogEnabled()) return; |
139 if (observers_.count(extension) == 0) { | 170 if (observers_.count(extension) == 0) { |
140 observers_[extension] = new ObserverListThreadSafe<Observer>; | 171 observers_[extension] = new ObserverListThreadSafe<Observer>; |
141 } | 172 } |
142 observers_[extension]->AddObserver(observer); | 173 observers_[extension]->AddObserver(observer); |
143 } | 174 } |
144 | 175 |
145 void ActivityLog::RemoveObserver(const Extension* extension, | 176 void ActivityLog::RemoveObserver(const Extension* extension, |
146 ActivityLog::Observer* observer) { | 177 ActivityLog::Observer* observer) { |
147 if (observers_.count(extension) == 1) { | 178 if (observers_.count(extension) == 1) { |
148 observers_[extension]->RemoveObserver(observer); | 179 observers_[extension]->RemoveObserver(observer); |
149 } | 180 } |
150 } | 181 } |
151 | 182 |
152 void ActivityLog::LogAPIAction(const Extension* extension, | 183 void ActivityLog::LogAPIAction(const Extension* extension, |
153 const std::string& name, | 184 const std::string& name, |
154 const ListValue* args, | 185 const ListValue* args, |
155 const std::string& extra) { | 186 const std::string& extra) { |
156 if (!IsLoggingEnabled()) return; | 187 if (!IsLogEnabled()) return; |
157 std::string verb, manager; | 188 std::string verb, manager; |
158 bool matches = RE2::FullMatch(name, "(.*?)\\.(.*)", &manager, &verb); | 189 bool matches = RE2::FullMatch(name, "(.*?)\\.(.*)", &manager, &verb); |
159 if (matches) { | 190 if (matches) { |
160 std::string call_signature = MakeCallSignature(name, args); | 191 std::string call_signature = MakeCallSignature(name, args); |
161 scoped_refptr<APIAction> action = new APIAction( | 192 scoped_refptr<APIAction> action = new APIAction( |
162 extension->id(), | 193 extension->id(), |
163 base::Time::Now(), | 194 base::Time::Now(), |
164 APIAction::StringAsActionType(verb), | 195 APIAction::CALL, |
165 APIAction::StringAsTargetType(manager), | 196 APIAction::StringAsVerb(verb), |
| 197 APIAction::StringAsTarget(manager), |
166 call_signature, | 198 call_signature, |
167 extra); | 199 extra); |
168 ScheduleAndForget(&ActivityDatabase::RecordAction, action); | 200 ScheduleAndForget(&ActivityDatabase::RecordAction, action); |
169 | 201 |
170 // Display the action. | 202 // Display the action. |
171 ObserverMap::const_iterator iter = observers_.find(extension); | 203 ObserverMap::const_iterator iter = observers_.find(extension); |
172 if (iter != observers_.end()) { | 204 if (iter != observers_.end()) { |
173 iter->second->Notify(&Observer::OnExtensionActivity, | 205 iter->second->Notify(&Observer::OnExtensionActivity, |
174 extension, | 206 extension, |
175 ActivityLog::ACTIVITY_EXTENSION_API_CALL, | 207 ActivityLog::ACTIVITY_EXTENSION_API_CALL, |
176 call_signature); | 208 call_signature); |
177 } | 209 } |
| 210 if (log_activity_to_stdout_) { |
| 211 LOG(INFO) << action->PrettyPrintForDebug(); |
| 212 } |
| 213 } else { |
| 214 LOG(ERROR) << "Unknown API call! " << name; |
| 215 } |
| 216 } |
| 217 |
| 218 void ActivityLog::LogEventAction(const Extension* extension, |
| 219 const std::string& name, |
| 220 const ListValue* args, |
| 221 const std::string& extra) { |
| 222 std::string verb, manager; |
| 223 bool matches = RE2::FullMatch(name, "(.*?)\\.(.*)", &manager, &verb); |
| 224 if (matches) { |
| 225 std::string call_signature = MakeCallSignature(name, args); |
| 226 scoped_refptr<APIAction> action = new APIAction( |
| 227 extension->id(), |
| 228 base::Time::Now(), |
| 229 APIAction::EVENT_CALLBACK, |
| 230 APIAction::StringAsVerb(verb), |
| 231 APIAction::StringAsTarget(manager), |
| 232 call_signature, |
| 233 extra); |
| 234 ScheduleAndForget(&ActivityDatabase::RecordAction, action); |
| 235 |
| 236 // Display the action. |
| 237 ObserverMap::const_iterator iter = observers_.find(extension); |
| 238 if (iter != observers_.end()) { |
| 239 iter->second->Notify(&Observer::OnExtensionActivity, |
| 240 extension, |
| 241 ActivityLog::ACTIVITY_EVENT_DISPATCH, |
| 242 call_signature); |
| 243 } |
178 if (log_activity_to_stdout_) | 244 if (log_activity_to_stdout_) |
179 LOG(INFO) << action->PrettyPrintForDebug(); | 245 LOG(INFO) << action->PrettyPrintForDebug(); |
180 } else { | 246 } else { |
181 LOG(ERROR) << "Unknown API call! " << name; | 247 LOG(ERROR) << "Unknown event type! " << name; |
182 } | 248 } |
183 } | 249 } |
184 | 250 |
185 void ActivityLog::LogBlockedAction(const Extension* extension, | 251 void ActivityLog::LogBlockedAction(const Extension* extension, |
186 const std::string& blocked_name, | 252 const std::string& blocked_name, |
187 const ListValue* args, | 253 const ListValue* args, |
188 const char* reason, | 254 const char* reason, |
189 const std::string& extra) { | 255 const std::string& extra) { |
190 if (!IsLoggingEnabled()) return; | 256 if (!IsLogEnabled()) return; |
191 std::string blocked_call = MakeCallSignature(blocked_name, args); | 257 std::string blocked_call = MakeCallSignature(blocked_name, args); |
192 scoped_refptr<BlockedAction> action = new BlockedAction(extension->id(), | 258 scoped_refptr<BlockedAction> action = new BlockedAction(extension->id(), |
193 base::Time::Now(), | 259 base::Time::Now(), |
194 blocked_call, | 260 blocked_call, |
195 std::string(reason), | 261 std::string(reason), |
196 extra); | 262 extra); |
197 ScheduleAndForget(&ActivityDatabase::RecordAction, action); | 263 ScheduleAndForget(&ActivityDatabase::RecordAction, action); |
198 // Display the action. | 264 // Display the action. |
199 ObserverMap::const_iterator iter = observers_.find(extension); | 265 ObserverMap::const_iterator iter = observers_.find(extension); |
200 if (iter != observers_.end()) { | 266 if (iter != observers_.end()) { |
201 iter->second->Notify(&Observer::OnExtensionActivity, | 267 iter->second->Notify(&Observer::OnExtensionActivity, |
202 extension, | 268 extension, |
203 ActivityLog::ACTIVITY_EXTENSION_API_BLOCK, | 269 ActivityLog::ACTIVITY_EXTENSION_API_BLOCK, |
204 blocked_call); | 270 blocked_call); |
205 } | 271 } |
206 if (log_activity_to_stdout_) | 272 if (log_activity_to_stdout_) |
207 LOG(INFO) << action->PrettyPrintForDebug(); | 273 LOG(INFO) << action->PrettyPrintForDebug(); |
208 } | 274 } |
209 | 275 |
210 void ActivityLog::LogUrlAction(const Extension* extension, | 276 void ActivityLog::LogUrlAction(const Extension* extension, |
211 const UrlAction::UrlActionType verb, | 277 const UrlAction::UrlActionType verb, |
212 const GURL& url, | 278 const GURL& url, |
213 const string16& url_title, | 279 const string16& url_title, |
214 const std::string& technical_message, | 280 const std::string& technical_message, |
215 const std::string& extra) { | 281 const std::string& extra) { |
216 if (!IsLoggingEnabled()) return; | 282 if (!IsLogEnabled()) return; |
217 scoped_refptr<UrlAction> action = new UrlAction( | 283 scoped_refptr<UrlAction> action = new UrlAction( |
218 extension->id(), | 284 extension->id(), |
219 base::Time::Now(), | 285 base::Time::Now(), |
220 verb, | 286 verb, |
221 url, | 287 url, |
222 url_title, | 288 url_title, |
223 technical_message, | 289 technical_message, |
224 extra); | 290 extra); |
225 ScheduleAndForget(&ActivityDatabase::RecordAction, action); | 291 ScheduleAndForget(&ActivityDatabase::RecordAction, action); |
226 | 292 |
227 // Display the action. | 293 // Display the action. |
228 ObserverMap::const_iterator iter = observers_.find(extension); | 294 ObserverMap::const_iterator iter = observers_.find(extension); |
229 if (iter != observers_.end()) { | 295 if (iter != observers_.end()) { |
230 iter->second->Notify(&Observer::OnExtensionActivity, | 296 iter->second->Notify(&Observer::OnExtensionActivity, |
231 extension, | 297 extension, |
232 ActivityLog::ACTIVITY_CONTENT_SCRIPT, | 298 ActivityLog::ACTIVITY_CONTENT_SCRIPT, |
233 action->PrettyPrintForDebug()); | 299 action->PrettyPrintForDebug()); |
234 } | 300 } |
235 if (log_activity_to_stdout_) | 301 if (log_activity_to_stdout_) |
236 LOG(INFO) << action->PrettyPrintForDebug(); | 302 LOG(INFO) << action->PrettyPrintForDebug(); |
237 } | 303 } |
238 | 304 |
239 void ActivityLog::OnScriptsExecuted( | 305 void ActivityLog::OnScriptsExecuted( |
240 const content::WebContents* web_contents, | 306 const content::WebContents* web_contents, |
241 const ExecutingScriptsMap& extension_ids, | 307 const ExecutingScriptsMap& extension_ids, |
242 int32 on_page_id, | 308 int32 on_page_id, |
243 const GURL& on_url) { | 309 const GURL& on_url) { |
244 if (!IsLoggingEnabled()) return; | 310 if (!IsLogEnabled()) return; |
245 Profile* profile = | 311 Profile* profile = |
246 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 312 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
247 const ExtensionService* extension_service = | 313 const ExtensionService* extension_service = |
248 ExtensionSystem::Get(profile)->extension_service(); | 314 ExtensionSystem::Get(profile)->extension_service(); |
249 const ExtensionSet* extensions = extension_service->extensions(); | 315 const ExtensionSet* extensions = extension_service->extensions(); |
250 | 316 |
251 for (ExecutingScriptsMap::const_iterator it = extension_ids.begin(); | 317 for (ExecutingScriptsMap::const_iterator it = extension_ids.begin(); |
252 it != extension_ids.end(); ++it) { | 318 it != extension_ids.end(); ++it) { |
253 const Extension* extension = extensions->GetByID(it->first); | 319 const Extension* extension = extensions->GetByID(it->first); |
254 if (!extension) | 320 if (!extension) |
(...skipping 27 matching lines...) Expand all Loading... |
282 | 348 |
283 // static | 349 // static |
284 const char* ActivityLog::ActivityToString(Activity activity) { | 350 const char* ActivityLog::ActivityToString(Activity activity) { |
285 switch (activity) { | 351 switch (activity) { |
286 case ActivityLog::ACTIVITY_EXTENSION_API_CALL: | 352 case ActivityLog::ACTIVITY_EXTENSION_API_CALL: |
287 return "api_call"; | 353 return "api_call"; |
288 case ActivityLog::ACTIVITY_EXTENSION_API_BLOCK: | 354 case ActivityLog::ACTIVITY_EXTENSION_API_BLOCK: |
289 return "api_block"; | 355 return "api_block"; |
290 case ActivityLog::ACTIVITY_CONTENT_SCRIPT: | 356 case ActivityLog::ACTIVITY_CONTENT_SCRIPT: |
291 return "content_script"; | 357 return "content_script"; |
| 358 case ActivityLog::ACTIVITY_EVENT_DISPATCH: |
| 359 return "event_dispatch"; |
292 default: | 360 default: |
293 NOTREACHED(); | 361 NOTREACHED(); |
294 return ""; | 362 return ""; |
295 } | 363 } |
296 } | 364 } |
297 | 365 |
298 } // namespace extensions | 366 } // namespace extensions |
299 | |
OLD | NEW |