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

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

Powered by Google App Engine
This is Rietveld 408576698