Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(379)

Side by Side Diff: chrome/browser/extensions/activity_log/activity_log.cc

Issue 15573003: New architecture of the activity logging: Policies for summarization (and compression) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed Adrienne's final comments. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "base/threading/thread_checker.h" 11 #include "base/threading/thread_checker.h"
12 #include "chrome/browser/extensions/activity_log/activity_log.h" 12 #include "chrome/browser/extensions/activity_log/activity_log.h"
13 #include "chrome/browser/extensions/activity_log/api_actions.h" 13 #include "chrome/browser/extensions/activity_log/api_actions.h"
14 #include "chrome/browser/extensions/activity_log/blocked_actions.h" 14 #include "chrome/browser/extensions/activity_log/blocked_actions.h"
15 #include "chrome/browser/extensions/activity_log/stream_noargs_ui_policy.h"
15 #include "chrome/browser/extensions/extension_service.h" 16 #include "chrome/browser/extensions/extension_service.h"
16 #include "chrome/browser/extensions/extension_system.h" 17 #include "chrome/browser/extensions/extension_system.h"
17 #include "chrome/browser/profiles/incognito_helpers.h" 18 #include "chrome/browser/profiles/incognito_helpers.h"
18 #include "chrome/common/chrome_constants.h" 19 #include "chrome/common/chrome_constants.h"
19 #include "chrome/common/chrome_switches.h" 20 #include "chrome/common/chrome_switches.h"
20 #include "chrome/common/extensions/extension.h" 21 #include "chrome/common/extensions/extension.h"
21 #include "content/public/browser/web_contents.h" 22 #include "content/public/browser/web_contents.h"
22 #include "googleurl/src/gurl.h" 23 #include "googleurl/src/gurl.h"
23 #include "sql/error_delegate_util.h" 24 #include "sql/error_delegate_util.h"
24 #include "third_party/re2/re2/re2.h" 25 #include "third_party/re2/re2/re2.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 // static 80 // static
80 bool ActivityLog::IsLogEnabled() { 81 bool ActivityLog::IsLogEnabled() {
81 return LogIsEnabled::GetInstance()->enabled(); 82 return LogIsEnabled::GetInstance()->enabled();
82 } 83 }
83 84
84 // static 85 // static
85 void ActivityLog::RecomputeLoggingIsEnabled() { 86 void ActivityLog::RecomputeLoggingIsEnabled() {
86 return LogIsEnabled::GetInstance()->ComputeIsEnabled(); 87 return LogIsEnabled::GetInstance()->ComputeIsEnabled();
87 } 88 }
88 89
89 // This handles errors from the database.
90 class KillActivityDatabaseErrorDelegate : public sql::ErrorDelegate {
91 public:
92 explicit KillActivityDatabaseErrorDelegate(ActivityLog* backend)
93 : backend_(backend),
94 scheduled_death_(false) {}
95
96 virtual int OnError(int error,
97 sql::Connection* connection,
98 sql::Statement* stmt) OVERRIDE {
99 if (!scheduled_death_ && sql::IsErrorCatastrophic(error)) {
100 ScheduleDeath();
101 }
102 return error;
103 }
104
105 // Schedules death if an error wasn't already reported.
106 void ScheduleDeath() {
107 if (!scheduled_death_) {
108 scheduled_death_ = true;
109 backend_->KillActivityLogDatabase();
110 }
111 }
112
113 bool scheduled_death() const {
114 return scheduled_death_;
115 }
116
117 private:
118 ActivityLog* backend_;
119 bool scheduled_death_;
120
121 DISALLOW_COPY_AND_ASSIGN(KillActivityDatabaseErrorDelegate);
122 };
123
124 // ActivityLogFactory 90 // ActivityLogFactory
125 91
126 ActivityLogFactory* ActivityLogFactory::GetInstance() { 92 ActivityLogFactory* ActivityLogFactory::GetInstance() {
127 return Singleton<ActivityLogFactory>::get(); 93 return Singleton<ActivityLogFactory>::get();
128 } 94 }
129 95
130 BrowserContextKeyedService* ActivityLogFactory::BuildServiceInstanceFor( 96 BrowserContextKeyedService* ActivityLogFactory::BuildServiceInstanceFor(
131 content::BrowserContext* profile) const { 97 content::BrowserContext* profile) const {
132 return new ActivityLog(static_cast<Profile*>(profile)); 98 return new ActivityLog(static_cast<Profile*>(profile));
133 } 99 }
134 100
135 content::BrowserContext* ActivityLogFactory::GetBrowserContextToUse( 101 content::BrowserContext* ActivityLogFactory::GetBrowserContextToUse(
136 content::BrowserContext* context) const { 102 content::BrowserContext* context) const {
137 return chrome::GetBrowserContextRedirectedInIncognito(context); 103 return chrome::GetBrowserContextRedirectedInIncognito(context);
138 } 104 }
139 105
140 // ActivityLog 106 // ActivityLog
141 107
142 // Use GetInstance instead of directly creating an ActivityLog. 108 // Use GetInstance instead of directly creating an ActivityLog.
143 ActivityLog::ActivityLog(Profile* profile) : profile_(profile) { 109 ActivityLog::ActivityLog(Profile* profile) : policy_(NULL), profile_(profile) {
144 // enable-extension-activity-logging and enable-extension-activity-ui 110 // enable-extension-activity-logging and enable-extension-activity-ui
145 log_activity_to_stdout_ = CommandLine::ForCurrentProcess()->HasSwitch( 111 log_activity_to_stdout_ = CommandLine::ForCurrentProcess()->HasSwitch(
146 switches::kEnableExtensionActivityLogging); 112 switches::kEnableExtensionActivityLogging);
147 113
148 // enable-extension-activity-log-testing
149 // This controls whether arguments are collected.
150 testing_mode_ = CommandLine::ForCurrentProcess()->HasSwitch(
151 switches::kEnableExtensionActivityLogTesting);
152 if (!testing_mode_) {
153 for (int i = 0; i < APIAction::kSizeAlwaysLog; i++) {
154 arg_whitelist_api_.insert(std::string(APIAction::kAlwaysLog[i]));
155 }
156 }
157
158 // We normally dispatch DB requests to the DB thread, but the thread might 114 // We normally dispatch DB requests to the DB thread, but the thread might
159 // not exist if we are under test conditions. Substitute the UI thread for 115 // not exist if we are under test conditions. Substitute the UI thread for
160 // this case. 116 // this case.
117 content::BrowserThread::ID dispatch_thread;
161 if (BrowserThread::IsMessageLoopValid(BrowserThread::DB)) { 118 if (BrowserThread::IsMessageLoopValid(BrowserThread::DB)) {
162 dispatch_thread_ = BrowserThread::DB; 119 dispatch_thread = BrowserThread::DB;
163 } else { 120 } else {
164 LOG(ERROR) << "BrowserThread::DB does not exist, running on UI thread!"; 121 LOG(ERROR) << "BrowserThread::DB does not exist, running on UI thread!";
165 dispatch_thread_ = BrowserThread::UI; 122 dispatch_thread = BrowserThread::UI;
166 } 123 }
167 124
168 // If the database cannot be initialized for some reason, we keep 125 // TODO(dbabic) In the next iteration, we should support multiple policies,
169 // chugging along but nothing will get recorded. If the UI is 126 // which are then polled by the ActivityLog object
170 // available, things will still get sent to the UI even if nothing 127 if (IsLogEnabled()) {
171 // is being written to the database. 128 switch (policy_type_) {
172 db_ = new ActivityDatabase(); 129 case ActivityLogPolicy::POLICY_FULLSTREAM:
173 if (!IsLogEnabled()) return; 130 policy_ = new FullStreamUIPolicy(profile, dispatch_thread);
174 base::FilePath base_dir = profile->GetPath(); 131 break;
175 base::FilePath database_name = base_dir.Append( 132 case ActivityLogPolicy::POLICY_NOARGS:
176 chrome::kExtensionActivityLogFilename); 133 policy_ = new StreamWithoutArgsUIPolicy(profile, dispatch_thread);
177 KillActivityDatabaseErrorDelegate* error_delegate = 134 break;
178 new KillActivityDatabaseErrorDelegate(this); 135 }
179 db_->SetErrorDelegate(error_delegate); 136 }
180 ScheduleAndForget(&ActivityDatabase::Init, database_name);
181 } 137 }
182 138
183 ActivityLog::~ActivityLog() { 139 ActivityLog::~ActivityLog() {
184 ScheduleAndForget(&ActivityDatabase::Close); 140 delete policy_;
185 }
186
187 void ActivityLog::SetArgumentLoggingForTesting(bool log_arguments) {
188 testing_mode_ = log_arguments;
189 } 141 }
190 142
191 // static 143 // static
192 ActivityLog* ActivityLog::GetInstance(Profile* profile) { 144 ActivityLog* ActivityLog::GetInstance(Profile* profile) {
193 return ActivityLogFactory::GetForProfile(profile); 145 return ActivityLogFactory::GetForProfile(profile);
194 } 146 }
195 147
196 void ActivityLog::AddObserver(const Extension* extension, 148 void ActivityLog::AddObserver(const Extension* extension,
197 ActivityLog::Observer* observer) { 149 ActivityLog::Observer* observer) {
198 if (!IsLogEnabled()) return; 150 if (!IsLogEnabled()) return;
199 if (observers_.count(extension) == 0) 151 if (observers_.count(extension) == 0)
200 observers_[extension] = new ObserverListThreadSafe<Observer>; 152 observers_[extension] = new ObserverListThreadSafe<Observer>;
201 observers_[extension]->AddObserver(observer); 153 observers_[extension]->AddObserver(observer);
202 } 154 }
203 155
204 void ActivityLog::RemoveObserver(const Extension* extension, 156 void ActivityLog::RemoveObserver(const Extension* extension,
205 ActivityLog::Observer* observer) { 157 ActivityLog::Observer* observer) {
206 if (observers_.count(extension) == 1) 158 if (observers_.count(extension) == 1)
207 observers_[extension]->RemoveObserver(observer); 159 observers_[extension]->RemoveObserver(observer);
208 } 160 }
209 161
210 void ActivityLog::LogAPIActionInternal(const Extension* extension, 162 void ActivityLog::LogAPIActionInternal(const Extension* extension,
211 const std::string& api_call, 163 const std::string& api_call,
212 ListValue* args, 164 ListValue* args,
213 const std::string& extra, 165 const std::string& extra,
214 const APIAction::Type type) { 166 const APIAction::Type type) {
167 // TODO(felt) This doesn't solve the TOCTOU problem, pass extension ID
168 // instead of a pointer to extension. That will fix the problem.
169 if (!extension)
170 return;
171
215 std::string verb, manager; 172 std::string verb, manager;
216 bool matches = RE2::FullMatch(api_call, "(.*?)\\.(.*)", &manager, &verb); 173 bool matches = RE2::FullMatch(api_call, "(.*?)\\.(.*)", &manager, &verb);
217 if (matches) { 174 if (matches) {
218 if (!args->empty() && manager == "tabs") { 175 if (!args->empty() && manager == "tabs") {
219 APIAction::LookupTabId(api_call, args, profile_); 176 APIAction::LookupTabId(api_call, args, profile_);
220 } 177 }
178
179 if (policy_) {
180 DCHECK((type == APIAction::CALL || type == APIAction::EVENT_CALLBACK) &&
181 "Unexpected APIAction call type.");
182 policy_->ProcessAction(
183 type == APIAction::CALL ? ActivityLogPolicy::ACTION_API :
184 ActivityLogPolicy::ACTION_EVENT,
185 *extension,
186 api_call,
187 NULL,
188 args,
189 NULL);
190 }
191
192 // TODO(felt) Logging should be done more efficiently, so that it
193 // doesn't require construction of the action object.
221 scoped_refptr<APIAction> action = new APIAction( 194 scoped_refptr<APIAction> action = new APIAction(
222 extension->id(), 195 extension->id(),
223 base::Time::Now(), 196 base::Time::Now(),
224 type, 197 type,
225 api_call, 198 api_call,
226 MakeArgList(args), 199 MakeArgList(args),
227 extra); 200 extra);
228 ScheduleAndForget(&ActivityDatabase::RecordAction, action);
229 201
230 // Display the action. 202 // Display the action.
231 ObserverMap::const_iterator iter = observers_.find(extension); 203 ObserverMap::const_iterator iter = observers_.find(extension);
232 if (iter != observers_.end()) { 204 if (iter != observers_.end()) {
233 if (type == APIAction::CALL) { 205 if (type == APIAction::CALL) {
234 iter->second->Notify(&Observer::OnExtensionActivity, 206 iter->second->Notify(&Observer::OnExtensionActivity,
235 extension, 207 extension,
236 ActivityLog::ACTIVITY_EXTENSION_API_CALL, 208 ActivityLog::ACTIVITY_EXTENSION_API_CALL,
237 MakeCallSignature(api_call, args)); 209 MakeCallSignature(api_call, args));
238 } else if (type == APIAction::EVENT_CALLBACK) { 210 } else if (type == APIAction::EVENT_CALLBACK) {
239 iter->second->Notify(&Observer::OnExtensionActivity, 211 iter->second->Notify(&Observer::OnExtensionActivity,
240 extension, 212 extension,
241 ActivityLog::ACTIVITY_EVENT_DISPATCH, 213 ActivityLog::ACTIVITY_EVENT_DISPATCH,
242 MakeCallSignature(api_call, args)); 214 MakeCallSignature(api_call, args));
243 } 215 }
244 } 216 }
245 if (log_activity_to_stdout_) 217 if (log_activity_to_stdout_)
246 LOG(INFO) << action->PrintForDebug(); 218 LOG(INFO) << action->PrintForDebug();
247 } else { 219 } else {
248 LOG(ERROR) << "Unknown API call! " << api_call; 220 LOG(ERROR) << "Unknown API call! " << api_call;
249 } 221 }
250 } 222 }
251 223
252 // A wrapper around LogAPIActionInternal, but we know it's an API call. 224 // A wrapper around LogAPIActionInternal, but we know it's an API call.
253 void ActivityLog::LogAPIAction(const Extension* extension, 225 void ActivityLog::LogAPIAction(const Extension* extension,
254 const std::string& api_call, 226 const std::string& api_call,
255 ListValue* args, 227 ListValue* args,
256 const std::string& extra) { 228 const std::string& extra) {
257 if (!IsLogEnabled()) return; 229 if (!IsLogEnabled() || !extension)
258 if (!testing_mode_ && 230 return;
259 arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) 231
260 args->Clear();
261 LogAPIActionInternal(extension, 232 LogAPIActionInternal(extension,
262 api_call, 233 api_call,
263 args, 234 args,
264 extra, 235 extra,
265 APIAction::CALL); 236 APIAction::CALL);
266 } 237 }
267 238
268 // A wrapper around LogAPIActionInternal, but we know it's actually an event 239 // A wrapper around LogAPIActionInternal, but we know it's actually an event
269 // being fired and triggering extension code. Having the two separate methods 240 // being fired and triggering extension code. Having the two separate methods
270 // (LogAPIAction vs LogEventAction) lets us hide how we actually choose to 241 // (LogAPIAction vs LogEventAction) lets us hide how we actually choose to
271 // handle them. Right now they're being handled almost the same. 242 // handle them. Right now they're being handled almost the same.
272 void ActivityLog::LogEventAction(const Extension* extension, 243 void ActivityLog::LogEventAction(const Extension* extension,
273 const std::string& api_call, 244 const std::string& api_call,
274 ListValue* args, 245 ListValue* args,
275 const std::string& extra) { 246 const std::string& extra) {
276 if (!IsLogEnabled()) return; 247 if (!IsLogEnabled() || !extension)
277 if (!testing_mode_ && 248 return;
278 arg_whitelist_api_.find(api_call) == arg_whitelist_api_.end()) 249
279 args->Clear();
280 LogAPIActionInternal(extension, 250 LogAPIActionInternal(extension,
281 api_call, 251 api_call,
282 args, 252 args,
283 extra, 253 extra,
284 APIAction::EVENT_CALLBACK); 254 APIAction::EVENT_CALLBACK);
285 } 255 }
286 256
287 void ActivityLog::LogBlockedAction(const Extension* extension, 257 void ActivityLog::LogBlockedAction(const Extension* extension,
288 const std::string& blocked_call, 258 const std::string& blocked_call,
289 ListValue* args, 259 ListValue* args,
290 BlockedAction::Reason reason, 260 BlockedAction::Reason reason,
291 const std::string& extra) { 261 const std::string& extra) {
292 if (!IsLogEnabled()) return; 262 if (!IsLogEnabled() || !extension)
293 if (!testing_mode_ && 263 return;
294 arg_whitelist_api_.find(blocked_call) == arg_whitelist_api_.end()) 264
295 args->Clear(); 265 if (policy_) {
266 scoped_ptr<base::DictionaryValue> details(new DictionaryValue());
267 std::string key;
268 policy_->GetKey(ActivityLogPolicy::PARAM_KEY_REASON, &key);
269 details->SetInteger(key, static_cast<int>(reason));
270 policy_->ProcessAction(
271 ActivityLogPolicy::ACTION_BLOCKED,
272 *extension,
273 blocked_call,
274 NULL,
275 args,
276 details.get());
277 }
278
279 // TODO(felt) Logging should be done more efficiently, so that it
280 // doesn't require construction of the action object.
296 scoped_refptr<BlockedAction> action = new BlockedAction(extension->id(), 281 scoped_refptr<BlockedAction> action = new BlockedAction(extension->id(),
297 base::Time::Now(), 282 base::Time::Now(),
298 blocked_call, 283 blocked_call,
299 MakeArgList(args), 284 MakeArgList(args),
300 reason, 285 reason,
301 extra); 286 extra);
302 ScheduleAndForget(&ActivityDatabase::RecordAction, action);
303 // Display the action. 287 // Display the action.
304 ObserverMap::const_iterator iter = observers_.find(extension); 288 ObserverMap::const_iterator iter = observers_.find(extension);
305 if (iter != observers_.end()) { 289 if (iter != observers_.end()) {
306 std::string blocked_str = MakeCallSignature(blocked_call, args); 290 std::string blocked_str = MakeCallSignature(blocked_call, args);
307 iter->second->Notify(&Observer::OnExtensionActivity, 291 iter->second->Notify(&Observer::OnExtensionActivity,
308 extension, 292 extension,
309 ActivityLog::ACTIVITY_EXTENSION_API_BLOCK, 293 ActivityLog::ACTIVITY_EXTENSION_API_BLOCK,
310 blocked_str); 294 blocked_str);
311 } 295 }
312 if (log_activity_to_stdout_) 296 if (log_activity_to_stdout_)
313 LOG(INFO) << action->PrintForDebug(); 297 LOG(INFO) << action->PrintForDebug();
314 } 298 }
315 299
316 void ActivityLog::LogDOMActionInternal(const Extension* extension, 300 void ActivityLog::LogDOMActionInternal(const Extension* extension,
317 const GURL& url, 301 const GURL& url,
318 const string16& url_title, 302 const string16& url_title,
319 const std::string& api_call, 303 const std::string& api_call,
320 const ListValue* args, 304 const ListValue* args,
321 const std::string& extra, 305 const std::string& extra,
322 DOMAction::DOMActionType verb) { 306 DOMAction::DOMActionType verb) {
307 if (!extension)
308 return;
309
310 if (policy_) {
311 scoped_ptr<base::DictionaryValue> details(new DictionaryValue());
312 std::string key;
313 policy_->GetKey(ActivityLogPolicy::PARAM_KEY_DOM_ACTION, &key);
314 details->SetInteger(key, static_cast<int>(verb));
315 policy_->GetKey(ActivityLogPolicy::PARAM_KEY_URL_TITLE, &key);
316 details->SetString(key, url_title);
317 policy_->ProcessAction(
318 ActivityLogPolicy::ACTION_DOM,
319 *extension,
320 api_call,
321 &url,
322 args,
323 details.get());
324 }
325
326
327 // TODO(felt) Logging should be done more efficiently, so that it
328 // doesn't require construction of the action object.
323 scoped_refptr<DOMAction> action = new DOMAction( 329 scoped_refptr<DOMAction> action = new DOMAction(
324 extension->id(), 330 extension->id(),
325 base::Time::Now(), 331 base::Time::Now(),
326 verb, 332 verb,
327 url, 333 url,
328 url_title, 334 url_title,
329 api_call, 335 api_call,
330 MakeArgList(args), 336 MakeArgList(args),
331 extra); 337 extra);
332 ScheduleAndForget(&ActivityDatabase::RecordAction, action);
333 338
334 // Display the action. 339 // Display the action.
335 ObserverMap::const_iterator iter = observers_.find(extension); 340 ObserverMap::const_iterator iter = observers_.find(extension);
336 if (iter != observers_.end()) { 341 if (iter != observers_.end()) {
337 // TODO(felt): This is a kludge, planning to update this when new 342 // TODO(felt): This is a kludge, planning to update this when new
338 // UI is in place. 343 // UI is in place.
339 if (verb == DOMAction::INSERTED) { 344 if (verb == DOMAction::INSERTED) {
340 iter->second->Notify(&Observer::OnExtensionActivity, 345 iter->second->Notify(&Observer::OnExtensionActivity,
341 extension, 346 extension,
342 ActivityLog::ACTIVITY_CONTENT_SCRIPT, 347 ActivityLog::ACTIVITY_CONTENT_SCRIPT,
343 action->PrintForDebug()); 348 action->PrintForDebug());
344 } else { 349 } else {
345 iter->second->Notify(&Observer::OnExtensionActivity, 350 iter->second->Notify(&Observer::OnExtensionActivity,
346 extension, 351 extension,
347 ActivityLog::ACTIVITY_CONTENT_SCRIPT, 352 ActivityLog::ACTIVITY_CONTENT_SCRIPT,
348 MakeCallSignature(api_call, args)); 353 MakeCallSignature(api_call, args));
349 } 354 }
350 } 355 }
351 if (log_activity_to_stdout_) 356 if (log_activity_to_stdout_)
352 LOG(INFO) << action->PrintForDebug(); 357 LOG(INFO) << action->PrintForDebug();
353 } 358 }
354 359
355 void ActivityLog::LogDOMAction(const Extension* extension, 360 void ActivityLog::LogDOMAction(const Extension* extension,
356 const GURL& url, 361 const GURL& url,
357 const string16& url_title, 362 const string16& url_title,
358 const std::string& api_call, 363 const std::string& api_call,
359 const ListValue* args, 364 const ListValue* args,
360 const std::string& extra) { 365 const std::string& extra) {
361 if (!IsLogEnabled()) return; 366 if (!IsLogEnabled() || !extension)
367 return;
368
362 DOMAction::DOMActionType action = DOMAction::MODIFIED; 369 DOMAction::DOMActionType action = DOMAction::MODIFIED;
363 if (extra == "Getter") { 370 if (extra == "Getter") {
364 action = DOMAction::GETTER; 371 action = DOMAction::GETTER;
365 } else if (extra == "Setter") { 372 } else if (extra == "Setter") {
366 action = DOMAction::SETTER; 373 action = DOMAction::SETTER;
367 } else if (api_call == "XMLHttpRequest.open") { 374 } else if (api_call == "XMLHttpRequest.open") {
368 // Has to come before the Method check because XHR is also a Method. 375 // Has to come before the Method check because XHR is also a Method.
369 action = DOMAction::XHR; 376 action = DOMAction::XHR;
370 } else if (extra == "Method") { 377 } else if (extra == "Method") {
371 action = DOMAction::METHOD; 378 action = DOMAction::METHOD;
372 } 379 }
380
373 LogDOMActionInternal(extension, 381 LogDOMActionInternal(extension,
374 url, 382 url,
375 url_title, 383 url_title,
376 api_call, 384 api_call,
377 args, 385 args,
378 extra, 386 extra,
379 action); 387 action);
380 } 388 }
381 389
382 void ActivityLog::LogWebRequestAction(const Extension* extension, 390 void ActivityLog::LogWebRequestAction(const Extension* extension,
383 const GURL& url, 391 const GURL& url,
384 const std::string& api_call, 392 const std::string& api_call,
385 scoped_ptr<DictionaryValue> details, 393 scoped_ptr<DictionaryValue> details,
386 const std::string& extra) { 394 const std::string& extra) {
387 string16 null_title; 395 string16 null_title;
388 if (!IsLogEnabled()) return; 396 if (!IsLogEnabled() || !extension)
397 return;
389 398
390 // Strip details of the web request modifications (for privacy reasons), 399 std::string details_string;
391 // unless testing is enabled. 400 if (policy_) {
392 if (!testing_mode_) { 401 scoped_ptr<base::DictionaryValue> details(new DictionaryValue());
393 DictionaryValue::Iterator details_iterator(*details); 402 std::string key;
394 while (!details_iterator.IsAtEnd()) { 403 policy_->GetKey(ActivityLogPolicy::PARAM_KEY_DETAILS_STRING, &key);
395 details->SetBoolean(details_iterator.key(), true); 404 details->SetString(key, details_string);
396 details_iterator.Advance(); 405 policy_->ProcessAction(
397 } 406 ActivityLogPolicy::ACTION_WEB_REQUEST,
407 *extension,
408 api_call,
409 &url,
410 NULL,
411 details.get());
398 } 412 }
399 std::string details_string; 413
400 JSONStringValueSerializer serializer(&details_string); 414 JSONStringValueSerializer serializer(&details_string);
401 serializer.SerializeAndOmitBinaryValues(*details); 415 serializer.SerializeAndOmitBinaryValues(*details);
402 416
417 // TODO(felt) Logging should be done more efficiently, so that it
418 // doesn't require construction of the action object.
403 scoped_refptr<DOMAction> action = new DOMAction( 419 scoped_refptr<DOMAction> action = new DOMAction(
404 extension->id(), 420 extension->id(),
405 base::Time::Now(), 421 base::Time::Now(),
406 DOMAction::WEBREQUEST, 422 DOMAction::WEBREQUEST,
407 url, 423 url,
408 null_title, 424 null_title,
409 api_call, 425 api_call,
410 details_string, 426 details_string,
411 extra); 427 extra);
412 ScheduleAndForget(&ActivityDatabase::RecordAction, action);
413 428
414 // Display the action. 429 // Display the action.
415 ObserverMap::const_iterator iter = observers_.find(extension); 430 ObserverMap::const_iterator iter = observers_.find(extension);
416 if (iter != observers_.end()) { 431 if (iter != observers_.end()) {
417 iter->second->Notify(&Observer::OnExtensionActivity, 432 iter->second->Notify(&Observer::OnExtensionActivity,
418 extension, 433 extension,
419 ActivityLog::ACTIVITY_CONTENT_SCRIPT, 434 ActivityLog::ACTIVITY_CONTENT_SCRIPT,
420 action->PrintForDebug()); 435 action->PrintForDebug());
421 } 436 }
422 if (log_activity_to_stdout_) 437 if (log_activity_to_stdout_)
423 LOG(INFO) << action->PrintForDebug(); 438 LOG(INFO) << action->PrintForDebug();
424 } 439 }
425 440
426 void ActivityLog::GetActions( 441 void ActivityLog::GetActions(
427 const std::string& extension_id, 442 const std::string& extension_id,
428 const int day, 443 const int day,
429 const base::Callback 444 const base::Callback
430 <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback) { 445 <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback) {
431 BrowserThread::PostTaskAndReplyWithResult( 446 if (policy_) {
432 dispatch_thread_, 447 policy_->ReadData(extension_id, day, callback);
433 FROM_HERE, 448 }
434 base::Bind(&ActivityDatabase::GetActions,
435 base::Unretained(db_),
436 extension_id,
437 day),
438 callback);
439 } 449 }
440 450
441 void ActivityLog::OnScriptsExecuted( 451 void ActivityLog::OnScriptsExecuted(
442 const content::WebContents* web_contents, 452 const content::WebContents* web_contents,
443 const ExecutingScriptsMap& extension_ids, 453 const ExecutingScriptsMap& extension_ids,
444 int32 on_page_id, 454 int32 on_page_id,
445 const GURL& on_url) { 455 const GURL& on_url) {
446 if (!IsLogEnabled()) return; 456 if (!IsLogEnabled()) return;
447 Profile* profile = 457 Profile* profile =
448 Profile::FromBrowserContext(web_contents->GetBrowserContext()); 458 Profile::FromBrowserContext(web_contents->GetBrowserContext());
(...skipping 18 matching lines...) Expand all
467 ext_scripts_str += *it2; 477 ext_scripts_str += *it2;
468 ext_scripts_str += " "; 478 ext_scripts_str += " ";
469 } 479 }
470 scoped_ptr<ListValue> script_names(new ListValue()); 480 scoped_ptr<ListValue> script_names(new ListValue());
471 script_names->Set(0, new StringValue(ext_scripts_str)); 481 script_names->Set(0, new StringValue(ext_scripts_str));
472 LogDOMActionInternal(extension, 482 LogDOMActionInternal(extension,
473 on_url, 483 on_url,
474 web_contents->GetTitle(), 484 web_contents->GetTitle(),
475 std::string(), // no api call here 485 std::string(), // no api call here
476 script_names.get(), 486 script_names.get(),
477 std::string(), // no extras either 487 std::string(),
478 DOMAction::INSERTED); 488 DOMAction::INSERTED); // no extras either
479 } 489 }
480 } 490 }
481 } 491 }
482 492
483 void ActivityLog::KillActivityLogDatabase() {
484 ScheduleAndForget(&ActivityDatabase::KillDatabase);
485 }
486
487 // static 493 // static
488 const char* ActivityLog::ActivityToString(Activity activity) { 494 const char* ActivityLog::ActivityToString(Activity activity) {
489 switch (activity) { 495 switch (activity) {
490 case ActivityLog::ACTIVITY_EXTENSION_API_CALL: 496 case ActivityLog::ACTIVITY_EXTENSION_API_CALL:
491 return "api_call"; 497 return "api_call";
492 case ActivityLog::ACTIVITY_EXTENSION_API_BLOCK: 498 case ActivityLog::ACTIVITY_EXTENSION_API_BLOCK:
493 return "api_block"; 499 return "api_block";
494 case ActivityLog::ACTIVITY_CONTENT_SCRIPT: 500 case ActivityLog::ACTIVITY_CONTENT_SCRIPT:
495 return "content_script"; 501 return "content_script";
496 case ActivityLog::ACTIVITY_EVENT_DISPATCH: 502 case ActivityLog::ACTIVITY_EVENT_DISPATCH:
497 return "event_dispatch"; 503 return "event_dispatch";
498 default: 504 default:
499 NOTREACHED(); 505 NOTREACHED();
500 return ""; 506 return "";
501 } 507 }
502 } 508 }
503 509
510 ActivityLogPolicy::PolicyType ActivityLog::policy_type_(
511 ActivityLogPolicy::POLICY_NOARGS);
512
504 } // namespace extensions 513 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698