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 <set> | 5 #include <set> |
6 #include <vector> | 6 #include <vector> |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/json/json_string_value_serializer.h" | 8 #include "base/json/json_string_value_serializer.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 | 150 |
151 void ActivityLog::SetArgumentLoggingForTesting(bool log_arguments) { | 151 void ActivityLog::SetArgumentLoggingForTesting(bool log_arguments) { |
152 testing_mode_ = log_arguments; | 152 testing_mode_ = log_arguments; |
153 } | 153 } |
154 | 154 |
155 // static | 155 // static |
156 ActivityLog* ActivityLog::GetInstance(Profile* profile) { | 156 ActivityLog* ActivityLog::GetInstance(Profile* profile) { |
157 return ActivityLogFactory::GetForProfile(profile); | 157 return ActivityLogFactory::GetForProfile(profile); |
158 } | 158 } |
159 | 159 |
160 void ActivityLog::AddObserver(const Extension* extension, | 160 void ActivityLog::AddObserver(ActivityLog::Observer* observer) { |
161 ActivityLog::Observer* observer) { | |
162 if (!IsLogEnabled()) return; | 161 if (!IsLogEnabled()) return; |
163 if (observers_.count(extension) == 0) | 162 // TODO(felt) Re-implement Observer notification HERE for the API. |
164 observers_[extension] = new ObserverListThreadSafe<Observer>; | |
165 observers_[extension]->AddObserver(observer); | |
166 } | 163 } |
167 | 164 |
168 void ActivityLog::RemoveObserver(const Extension* extension, | 165 void ActivityLog::RemoveObserver(ActivityLog::Observer* observer) { |
169 ActivityLog::Observer* observer) { | 166 // TODO(felt) Re-implement Observer notification HERE for the API. |
170 if (observers_.count(extension) == 1) | |
171 observers_[extension]->RemoveObserver(observer); | |
172 } | 167 } |
173 | 168 |
174 void ActivityLog::LogAPIActionInternal(const Extension* extension, | 169 void ActivityLog::LogAPIActionInternal(const std::string& extension_id, |
175 const std::string& api_call, | 170 const std::string& api_call, |
176 ListValue* args, | 171 ListValue* args, |
177 const std::string& extra, | 172 const std::string& extra, |
178 const APIAction::Type type) { | 173 const APIAction::Type type) { |
179 std::string verb, manager; | 174 std::string verb, manager; |
180 bool matches = RE2::FullMatch(api_call, "(.*?)\\.(.*)", &manager, &verb); | 175 bool matches = RE2::FullMatch(api_call, "(.*?)\\.(.*)", &manager, &verb); |
181 if (matches) { | 176 if (matches) { |
182 if (!args->empty() && manager == "tabs") { | 177 if (!args->empty() && manager == "tabs") { |
183 APIAction::LookupTabId(api_call, args, profile_); | 178 APIAction::LookupTabId(api_call, args, profile_); |
184 } | 179 } |
185 scoped_refptr<APIAction> action = new APIAction( | 180 scoped_refptr<APIAction> action = new APIAction( |
186 extension->id(), | 181 extension_id, |
187 base::Time::Now(), | 182 base::Time::Now(), |
188 type, | 183 type, |
189 api_call, | 184 api_call, |
190 MakeArgList(args), | 185 MakeArgList(args), |
191 extra); | 186 extra); |
192 ScheduleAndForget(&ActivityDatabase::RecordAction, action); | 187 ScheduleAndForget(&ActivityDatabase::RecordAction, action); |
193 | 188 // TODO(felt) Re-implement Observer notification HERE for the API. |
194 // Display the action. | |
195 ObserverMap::const_iterator iter = observers_.find(extension); | |
196 if (iter != observers_.end()) { | |
197 if (type == APIAction::CALL) { | |
198 iter->second->Notify(&Observer::OnExtensionActivity, | |
199 extension, | |
200 ActivityLog::ACTIVITY_EXTENSION_API_CALL, | |
201 MakeCallSignature(api_call, args)); | |
202 } else if (type == APIAction::EVENT_CALLBACK) { | |
203 iter->second->Notify(&Observer::OnExtensionActivity, | |
204 extension, | |
205 ActivityLog::ACTIVITY_EVENT_DISPATCH, | |
206 MakeCallSignature(api_call, args)); | |
207 } | |
208 } | |
209 if (log_activity_to_stdout_) | 189 if (log_activity_to_stdout_) |
210 LOG(INFO) << action->PrintForDebug(); | 190 LOG(INFO) << action->PrintForDebug(); |
211 } else { | 191 } else { |
212 LOG(ERROR) << "Unknown API call! " << api_call; | 192 LOG(ERROR) << "Unknown API call! " << api_call; |
213 } | 193 } |
214 } | 194 } |
215 | 195 |
216 // A wrapper around LogAPIActionInternal, but we know it's an API call. | 196 // A wrapper around LogAPIActionInternal, but we know it's an API call. |
217 void ActivityLog::LogAPIAction(const Extension* extension, | 197 void ActivityLog::LogAPIAction(const std::string& extension_id, |
218 const std::string& api_call, | 198 const std::string& api_call, |
219 ListValue* args, | 199 ListValue* args, |
220 const std::string& extra) { | 200 const std::string& extra) { |
221 if (!IsLogEnabled()) return; | 201 if (!IsLogEnabled()) return; |
222 if (!testing_mode_ && | 202 if (!testing_mode_ && |
223 arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) | 203 arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) |
224 args->Clear(); | 204 args->Clear(); |
225 LogAPIActionInternal(extension, | 205 LogAPIActionInternal(extension_id, |
226 api_call, | 206 api_call, |
227 args, | 207 args, |
228 extra, | 208 extra, |
229 APIAction::CALL); | 209 APIAction::CALL); |
230 } | 210 } |
231 | 211 |
232 // A wrapper around LogAPIActionInternal, but we know it's actually an event | 212 // A wrapper around LogAPIActionInternal, but we know it's actually an event |
233 // being fired and triggering extension code. Having the two separate methods | 213 // being fired and triggering extension code. Having the two separate methods |
234 // (LogAPIAction vs LogEventAction) lets us hide how we actually choose to | 214 // (LogAPIAction vs LogEventAction) lets us hide how we actually choose to |
235 // handle them. Right now they're being handled almost the same. | 215 // handle them. Right now they're being handled almost the same. |
236 void ActivityLog::LogEventAction(const Extension* extension, | 216 void ActivityLog::LogEventAction(const std::string& extension_id, |
237 const std::string& api_call, | 217 const std::string& api_call, |
238 ListValue* args, | 218 ListValue* args, |
239 const std::string& extra) { | 219 const std::string& extra) { |
240 if (!IsLogEnabled()) return; | 220 if (!IsLogEnabled()) return; |
241 if (!testing_mode_ && | 221 if (!testing_mode_ && |
242 arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) | 222 arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) |
243 args->Clear(); | 223 args->Clear(); |
244 LogAPIActionInternal(extension, | 224 LogAPIActionInternal(extension_id, |
245 api_call, | 225 api_call, |
246 args, | 226 args, |
247 extra, | 227 extra, |
248 APIAction::EVENT_CALLBACK); | 228 APIAction::EVENT_CALLBACK); |
249 } | 229 } |
250 | 230 |
251 void ActivityLog::LogBlockedAction(const Extension* extension, | 231 void ActivityLog::LogBlockedAction(const std::string& extension_id, |
252 const std::string& blocked_call, | 232 const std::string& blocked_call, |
253 ListValue* args, | 233 ListValue* args, |
254 BlockedAction::Reason reason, | 234 BlockedAction::Reason reason, |
255 const std::string& extra) { | 235 const std::string& extra) { |
256 if (!IsLogEnabled()) return; | 236 if (!IsLogEnabled()) return; |
257 if (!testing_mode_ && | 237 if (!testing_mode_ && |
258 arg_whitelist_api_.find(blocked_call) == arg_whitelist_api_.end()) | 238 arg_whitelist_api_.find(blocked_call) == arg_whitelist_api_.end()) |
259 args->Clear(); | 239 args->Clear(); |
260 scoped_refptr<BlockedAction> action = new BlockedAction(extension->id(), | 240 scoped_refptr<BlockedAction> action = new BlockedAction(extension_id, |
261 base::Time::Now(), | 241 base::Time::Now(), |
262 blocked_call, | 242 blocked_call, |
263 MakeArgList(args), | 243 MakeArgList(args), |
264 reason, | 244 reason, |
265 extra); | 245 extra); |
266 ScheduleAndForget(&ActivityDatabase::RecordAction, action); | 246 ScheduleAndForget(&ActivityDatabase::RecordAction, action); |
267 // Display the action. | 247 // TODO(felt) Re-implement Observer notification HERE for the API. |
268 ObserverMap::const_iterator iter = observers_.find(extension); | |
269 if (iter != observers_.end()) { | |
270 std::string blocked_str = MakeCallSignature(blocked_call, args); | |
271 iter->second->Notify(&Observer::OnExtensionActivity, | |
272 extension, | |
273 ActivityLog::ACTIVITY_EXTENSION_API_BLOCK, | |
274 blocked_str); | |
275 } | |
276 if (log_activity_to_stdout_) | 248 if (log_activity_to_stdout_) |
277 LOG(INFO) << action->PrintForDebug(); | 249 LOG(INFO) << action->PrintForDebug(); |
278 } | 250 } |
279 | 251 |
280 void ActivityLog::LogDOMAction(const Extension* extension, | 252 void ActivityLog::LogDOMAction(const std::string& extension_id, |
281 const GURL& url, | 253 const GURL& url, |
282 const string16& url_title, | 254 const string16& url_title, |
283 const std::string& api_call, | 255 const std::string& api_call, |
284 const ListValue* args, | 256 const ListValue* args, |
285 DomActionType::Type call_type, | 257 DomActionType::Type call_type, |
286 const std::string& extra) { | 258 const std::string& extra) { |
287 if (!IsLogEnabled()) return; | 259 if (!IsLogEnabled()) return; |
288 if (call_type == DomActionType::METHOD && api_call == "XMLHttpRequest.open") | 260 if (call_type == DomActionType::METHOD && api_call == "XMLHttpRequest.open") |
289 call_type = DomActionType::XHR; | 261 call_type = DomActionType::XHR; |
290 scoped_refptr<DOMAction> action = new DOMAction( | 262 scoped_refptr<DOMAction> action = new DOMAction( |
291 extension->id(), | 263 extension_id, |
292 base::Time::Now(), | 264 base::Time::Now(), |
293 call_type, | 265 call_type, |
294 url, | 266 url, |
295 url_title, | 267 url_title, |
296 api_call, | 268 api_call, |
297 MakeArgList(args), | 269 MakeArgList(args), |
298 extra); | 270 extra); |
299 ScheduleAndForget(&ActivityDatabase::RecordAction, action); | 271 ScheduleAndForget(&ActivityDatabase::RecordAction, action); |
300 | 272 // TODO(felt) Re-implement Observer notification HERE for the API. |
301 // Display the action. | |
302 ObserverMap::const_iterator iter = observers_.find(extension); | |
303 if (iter != observers_.end()) { | |
304 // TODO(felt): This is a kludge, planning to update this when new | |
305 // UI is in place. | |
306 if (call_type == DomActionType::INSERTED) { | |
307 iter->second->Notify(&Observer::OnExtensionActivity, | |
308 extension, | |
309 ActivityLog::ACTIVITY_CONTENT_SCRIPT, | |
310 action->PrintForDebug()); | |
311 } else { | |
312 iter->second->Notify(&Observer::OnExtensionActivity, | |
313 extension, | |
314 ActivityLog::ACTIVITY_CONTENT_SCRIPT, | |
315 MakeCallSignature(api_call, args)); | |
316 } | |
317 } | |
318 if (log_activity_to_stdout_) | 273 if (log_activity_to_stdout_) |
319 LOG(INFO) << action->PrintForDebug(); | 274 LOG(INFO) << action->PrintForDebug(); |
320 } | 275 } |
321 | 276 |
322 void ActivityLog::LogWebRequestAction(const Extension* extension, | 277 void ActivityLog::LogWebRequestAction(const std::string& extension_id, |
323 const GURL& url, | 278 const GURL& url, |
324 const std::string& api_call, | 279 const std::string& api_call, |
325 scoped_ptr<DictionaryValue> details, | 280 scoped_ptr<DictionaryValue> details, |
326 const std::string& extra) { | 281 const std::string& extra) { |
327 string16 null_title; | 282 string16 null_title; |
328 if (!IsLogEnabled()) return; | 283 if (!IsLogEnabled()) return; |
329 | 284 |
330 // Strip details of the web request modifications (for privacy reasons), | 285 // Strip details of the web request modifications (for privacy reasons), |
331 // unless testing is enabled. | 286 // unless testing is enabled. |
332 if (!testing_mode_) { | 287 if (!testing_mode_) { |
333 DictionaryValue::Iterator details_iterator(*details); | 288 DictionaryValue::Iterator details_iterator(*details); |
334 while (!details_iterator.IsAtEnd()) { | 289 while (!details_iterator.IsAtEnd()) { |
335 details->SetBoolean(details_iterator.key(), true); | 290 details->SetBoolean(details_iterator.key(), true); |
336 details_iterator.Advance(); | 291 details_iterator.Advance(); |
337 } | 292 } |
338 } | 293 } |
339 std::string details_string; | 294 std::string details_string; |
340 JSONStringValueSerializer serializer(&details_string); | 295 JSONStringValueSerializer serializer(&details_string); |
341 serializer.SerializeAndOmitBinaryValues(*details); | 296 serializer.SerializeAndOmitBinaryValues(*details); |
342 | 297 |
343 scoped_refptr<DOMAction> action = new DOMAction( | 298 scoped_refptr<DOMAction> action = new DOMAction( |
344 extension->id(), | 299 extension_id, |
345 base::Time::Now(), | 300 base::Time::Now(), |
346 DomActionType::WEBREQUEST, | 301 DomActionType::WEBREQUEST, |
347 url, | 302 url, |
348 null_title, | 303 null_title, |
349 api_call, | 304 api_call, |
350 details_string, | 305 details_string, |
351 extra); | 306 extra); |
352 ScheduleAndForget(&ActivityDatabase::RecordAction, action); | 307 ScheduleAndForget(&ActivityDatabase::RecordAction, action); |
353 | 308 // TODO(felt) Re-implement Observer notification HERE for the API. |
354 // Display the action. | |
355 ObserverMap::const_iterator iter = observers_.find(extension); | |
356 if (iter != observers_.end()) { | |
357 iter->second->Notify(&Observer::OnExtensionActivity, | |
358 extension, | |
359 ActivityLog::ACTIVITY_CONTENT_SCRIPT, | |
360 action->PrintForDebug()); | |
361 } | |
362 if (log_activity_to_stdout_) | 309 if (log_activity_to_stdout_) |
363 LOG(INFO) << action->PrintForDebug(); | 310 LOG(INFO) << action->PrintForDebug(); |
364 } | 311 } |
365 | 312 |
366 void ActivityLog::GetActions( | 313 void ActivityLog::GetActions( |
367 const std::string& extension_id, | 314 const std::string& extension_id, |
368 const int day, | 315 const int day, |
369 const base::Callback | 316 const base::Callback |
370 <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback) { | 317 <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback) { |
371 BrowserThread::PostTaskAndReplyWithResult( | 318 BrowserThread::PostTaskAndReplyWithResult( |
(...skipping 30 matching lines...) Expand all Loading... |
402 if (!it->second.empty()) { | 349 if (!it->second.empty()) { |
403 std::string ext_scripts_str; | 350 std::string ext_scripts_str; |
404 for (std::set<std::string>::const_iterator it2 = it->second.begin(); | 351 for (std::set<std::string>::const_iterator it2 = it->second.begin(); |
405 it2 != it->second.end(); | 352 it2 != it->second.end(); |
406 ++it2) { | 353 ++it2) { |
407 ext_scripts_str += *it2; | 354 ext_scripts_str += *it2; |
408 ext_scripts_str += " "; | 355 ext_scripts_str += " "; |
409 } | 356 } |
410 scoped_ptr<ListValue> script_names(new ListValue()); | 357 scoped_ptr<ListValue> script_names(new ListValue()); |
411 script_names->Set(0, new StringValue(ext_scripts_str)); | 358 script_names->Set(0, new StringValue(ext_scripts_str)); |
412 LogDOMAction(extension, | 359 LogDOMAction(extension->id(), |
413 on_url, | 360 on_url, |
414 web_contents->GetTitle(), | 361 web_contents->GetTitle(), |
415 std::string(), // no api call here | 362 std::string(), // no api call here |
416 script_names.get(), | 363 script_names.get(), |
417 DomActionType::INSERTED, | 364 DomActionType::INSERTED, |
418 std::string()); // no extras either | 365 std::string()); // no extras either |
419 } | 366 } |
420 } | 367 } |
421 } | 368 } |
422 | 369 |
423 void ActivityLog::DatabaseErrorCallback(int error, sql::Statement* stmt) { | 370 void ActivityLog::DatabaseErrorCallback(int error, sql::Statement* stmt) { |
424 if (sql::IsErrorCatastrophic(error)) | 371 if (sql::IsErrorCatastrophic(error)) |
425 ScheduleAndForget(&ActivityDatabase::KillDatabase); | 372 ScheduleAndForget(&ActivityDatabase::KillDatabase); |
426 } | 373 } |
427 | 374 |
428 // static | |
429 const char* ActivityLog::ActivityToString(Activity activity) { | |
430 switch (activity) { | |
431 case ActivityLog::ACTIVITY_EXTENSION_API_CALL: | |
432 return "api_call"; | |
433 case ActivityLog::ACTIVITY_EXTENSION_API_BLOCK: | |
434 return "api_block"; | |
435 case ActivityLog::ACTIVITY_CONTENT_SCRIPT: | |
436 return "content_script"; | |
437 case ActivityLog::ACTIVITY_EVENT_DISPATCH: | |
438 return "event_dispatch"; | |
439 default: | |
440 NOTREACHED(); | |
441 return ""; | |
442 } | |
443 } | |
444 | |
445 } // namespace extensions | 375 } // namespace extensions |
OLD | NEW |