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/activity_log.h" | 5 #include "chrome/browser/extensions/activity_log/activity_log.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 | 176 |
177 // ActivityLog | 177 // ActivityLog |
178 | 178 |
179 // SET THINGS UP. -------------------------------------------------------------- | 179 // SET THINGS UP. -------------------------------------------------------------- |
180 | 180 |
181 // Use GetInstance instead of directly creating an ActivityLog. | 181 // Use GetInstance instead of directly creating an ActivityLog. |
182 ActivityLog::ActivityLog(Profile* profile) | 182 ActivityLog::ActivityLog(Profile* profile) |
183 : policy_(NULL), | 183 : policy_(NULL), |
184 policy_type_(ActivityLogPolicy::POLICY_INVALID), | 184 policy_type_(ActivityLogPolicy::POLICY_INVALID), |
185 profile_(profile), | 185 profile_(profile), |
186 enabled_(false), | 186 db_enabled_(false), |
187 policy_chosen_(false), | |
188 testing_mode_(false), | 187 testing_mode_(false), |
189 has_threads_(true), | 188 has_threads_(true), |
190 tracker_(NULL), | 189 tracker_(NULL), |
191 watchdog_extension_active_(false) { | 190 watchdog_app_active_(false) { |
192 // This controls whether logging statements are printed, which policy is set, | 191 // This controls whether logging statements are printed & which policy is set. |
193 // etc. | |
194 testing_mode_ = CommandLine::ForCurrentProcess()->HasSwitch( | 192 testing_mode_ = CommandLine::ForCurrentProcess()->HasSwitch( |
195 switches::kEnableExtensionActivityLogTesting); | 193 switches::kEnableExtensionActivityLogTesting); |
196 | 194 |
197 // Check if the watchdog extension is previously installed and active. | 195 // Check if the watchdog extension is previously installed and active. |
198 watchdog_extension_active_ = | 196 watchdog_app_active_ = |
199 profile_->GetPrefs()->GetBoolean(prefs::kWatchdogExtensionActive); | 197 profile_->GetPrefs()->GetBoolean(prefs::kWatchdogExtensionActive); |
200 | 198 |
201 observers_ = new ObserverListThreadSafe<Observer>; | 199 observers_ = new ObserverListThreadSafe<Observer>; |
202 | 200 |
203 // Check that the right threads exist. If not, we shouldn't try to do things | 201 // Check that the right threads exist for logging to the database. |
204 // that require them. | 202 // If not, we shouldn't try to do things that require them. |
205 if (!BrowserThread::IsMessageLoopValid(BrowserThread::DB) || | 203 if (!BrowserThread::IsMessageLoopValid(BrowserThread::DB) || |
206 !BrowserThread::IsMessageLoopValid(BrowserThread::FILE) || | 204 !BrowserThread::IsMessageLoopValid(BrowserThread::FILE) || |
207 !BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { | 205 !BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { |
208 LOG(ERROR) << "Missing threads, disabling Activity Logging!"; | |
209 has_threads_ = false; | 206 has_threads_ = false; |
210 } | 207 } |
211 | 208 |
212 enabled_ = has_threads_ | 209 db_enabled_ = has_threads_ |
213 && (CommandLine::ForCurrentProcess()-> | 210 && (CommandLine::ForCurrentProcess()-> |
214 HasSwitch(switches::kEnableExtensionActivityLogging) | 211 HasSwitch(switches::kEnableExtensionActivityLogging) |
215 || watchdog_extension_active_); | 212 || watchdog_app_active_); |
216 | |
217 if (enabled_) enabled_on_any_profile_ = true; | |
218 | 213 |
219 ExtensionSystem::Get(profile_)->ready().Post( | 214 ExtensionSystem::Get(profile_)->ready().Post( |
220 FROM_HERE, | 215 FROM_HERE, |
221 base::Bind(&ActivityLog::InitInstallTracker, base::Unretained(this))); | 216 base::Bind(&ActivityLog::InitInstallTracker, base::Unretained(this))); |
222 ChooseDefaultPolicy(); | 217 ChooseDefaultPolicy(); |
223 } | 218 } |
224 | 219 |
225 void ActivityLog::SetDefaultPolicy(ActivityLogPolicy::PolicyType policy_type) { | 220 void ActivityLog::SetDefaultPolicy(ActivityLogPolicy::PolicyType policy_type) { |
226 // Can't use IsLogEnabled() here because this is called from inside Init. | 221 if (policy_type == policy_type_) |
227 if (policy_type != policy_type_ && enabled_) { | 222 return; |
228 // Deleting the old policy takes place asynchronously, on the database | 223 if (!IsDatabaseEnabled() && !IsWatchdogAppActive()) |
229 // thread. Initializing a new policy below similarly happens | 224 return; |
230 // asynchronously. Since the two operations are both queued for the | |
231 // database, the queue ordering should ensure that the deletion completes | |
232 // before database initialization occurs. | |
233 // | |
234 // However, changing policies at runtime is still not recommended, and | |
235 // likely only should be done for unit tests. | |
236 if (policy_) | |
237 policy_->Close(); | |
238 | 225 |
239 switch (policy_type) { | 226 // Deleting the old policy takes place asynchronously, on the database |
240 case ActivityLogPolicy::POLICY_FULLSTREAM: | 227 // thread. Initializing a new policy below similarly happens |
241 policy_ = new FullStreamUIPolicy(profile_); | 228 // asynchronously. Since the two operations are both queued for the |
242 break; | 229 // database, the queue ordering should ensure that the deletion completes |
243 case ActivityLogPolicy::POLICY_COUNTS: | 230 // before database initialization occurs. |
244 policy_ = new CountingPolicy(profile_); | 231 // |
245 break; | 232 // However, changing policies at runtime is still not recommended, and |
246 default: | 233 // likely only should be done for unit tests. |
247 NOTREACHED(); | 234 if (policy_) |
248 } | 235 policy_->Close(); |
249 policy_type_ = policy_type; | 236 |
| 237 switch (policy_type) { |
| 238 case ActivityLogPolicy::POLICY_FULLSTREAM: |
| 239 policy_ = new FullStreamUIPolicy(profile_); |
| 240 break; |
| 241 case ActivityLogPolicy::POLICY_COUNTS: |
| 242 policy_ = new CountingPolicy(profile_); |
| 243 break; |
| 244 default: |
| 245 NOTREACHED(); |
250 } | 246 } |
| 247 policy_type_ = policy_type; |
251 } | 248 } |
252 | 249 |
253 // SHUT DOWN. ------------------------------------------------------------------ | 250 // SHUT DOWN. ------------------------------------------------------------------ |
254 | 251 |
255 void ActivityLog::Shutdown() { | 252 void ActivityLog::Shutdown() { |
256 if (tracker_) tracker_->RemoveObserver(this); | 253 if (tracker_) tracker_->RemoveObserver(this); |
257 } | 254 } |
258 | 255 |
259 ActivityLog::~ActivityLog() { | 256 ActivityLog::~ActivityLog() { |
260 if (policy_) | 257 if (policy_) |
261 policy_->Close(); | 258 policy_->Close(); |
262 } | 259 } |
263 | 260 |
264 // MAINTAIN STATUS. ------------------------------------------------------------ | 261 // MAINTAIN STATUS. ------------------------------------------------------------ |
265 | 262 |
266 void ActivityLog::InitInstallTracker() { | 263 void ActivityLog::InitInstallTracker() { |
267 tracker_ = InstallTrackerFactory::GetForProfile(profile_); | 264 tracker_ = InstallTrackerFactory::GetForProfile(profile_); |
268 tracker_->AddObserver(this); | 265 tracker_->AddObserver(this); |
269 } | 266 } |
270 | 267 |
271 void ActivityLog::ChooseDefaultPolicy() { | 268 void ActivityLog::ChooseDefaultPolicy() { |
272 if (policy_chosen_ || !enabled_) return; | 269 if (!(IsDatabaseEnabled() || IsWatchdogAppActive())) |
| 270 return; |
273 if (testing_mode_) | 271 if (testing_mode_) |
274 SetDefaultPolicy(ActivityLogPolicy::POLICY_FULLSTREAM); | 272 SetDefaultPolicy(ActivityLogPolicy::POLICY_FULLSTREAM); |
275 else | 273 else |
276 SetDefaultPolicy(ActivityLogPolicy::POLICY_COUNTS); | 274 SetDefaultPolicy(ActivityLogPolicy::POLICY_COUNTS); |
277 } | 275 } |
278 | 276 |
279 // static | 277 bool ActivityLog::IsDatabaseEnabled() { |
280 bool ActivityLog::enabled_on_any_profile_ = false; | 278 // Make sure we are not enabled when there are no threads. |
281 | 279 DCHECK(has_threads_ || !db_enabled_); |
282 // static | 280 return db_enabled_; |
283 bool ActivityLog::IsLogEnabledOnAnyProfile() { | |
284 return enabled_on_any_profile_; | |
285 } | 281 } |
286 | 282 |
287 bool ActivityLog::IsLogEnabled() { | 283 bool ActivityLog::IsWatchdogAppActive() { |
288 // Make sure we are not enabled when there are no threads. | 284 return watchdog_app_active_; |
289 DCHECK(has_threads_ || !enabled_); | 285 } |
290 return enabled_; | 286 |
| 287 void ActivityLog::SetWatchdogAppActive(bool active) { |
| 288 watchdog_app_active_ = active; |
291 } | 289 } |
292 | 290 |
293 void ActivityLog::OnExtensionLoaded(const Extension* extension) { | 291 void ActivityLog::OnExtensionLoaded(const Extension* extension) { |
294 if (extension->id() != kActivityLogExtensionId) return; | 292 if (extension->id() != kActivityLogExtensionId) return; |
295 if (has_threads_) { | 293 if (has_threads_) |
296 enabled_ = true; | 294 db_enabled_ = true; |
297 enabled_on_any_profile_ = true; | 295 if (!watchdog_app_active_) { |
298 } | 296 watchdog_app_active_ = true; |
299 if (!watchdog_extension_active_) { | |
300 watchdog_extension_active_ = true; | |
301 profile_->GetPrefs()->SetBoolean(prefs::kWatchdogExtensionActive, true); | 297 profile_->GetPrefs()->SetBoolean(prefs::kWatchdogExtensionActive, true); |
302 } | 298 } |
303 ChooseDefaultPolicy(); | 299 ChooseDefaultPolicy(); |
304 } | 300 } |
305 | 301 |
306 void ActivityLog::OnExtensionUnloaded(const Extension* extension) { | 302 void ActivityLog::OnExtensionUnloaded(const Extension* extension) { |
307 if (extension->id() != kActivityLogExtensionId) return; | 303 if (extension->id() != kActivityLogExtensionId) return; |
308 // Make sure we are not enabled when there are no threads. | |
309 DCHECK(has_threads_ || !enabled_); | |
310 if (!CommandLine::ForCurrentProcess()->HasSwitch( | 304 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
311 switches::kEnableExtensionActivityLogging)) | 305 switches::kEnableExtensionActivityLogging)) { |
312 enabled_ = false; | 306 db_enabled_ = false; |
313 if (watchdog_extension_active_) { | 307 } |
314 watchdog_extension_active_ = false; | 308 if (watchdog_app_active_) { |
| 309 watchdog_app_active_ = false; |
315 profile_->GetPrefs()->SetBoolean(prefs::kWatchdogExtensionActive, | 310 profile_->GetPrefs()->SetBoolean(prefs::kWatchdogExtensionActive, |
316 false); | 311 false); |
317 } | 312 } |
318 } | 313 } |
319 | 314 |
320 // static | 315 // static |
321 ActivityLog* ActivityLog::GetInstance(Profile* profile) { | 316 ActivityLog* ActivityLog::GetInstance(Profile* profile) { |
322 return ActivityLogFactory::GetForProfile(profile); | 317 return ActivityLogFactory::GetForProfile(profile); |
323 } | 318 } |
324 | 319 |
(...skipping 10 matching lines...) Expand all Loading... |
335 user_prefs::PrefRegistrySyncable* registry) { | 330 user_prefs::PrefRegistrySyncable* registry) { |
336 registry->RegisterBooleanPref( | 331 registry->RegisterBooleanPref( |
337 prefs::kWatchdogExtensionActive, | 332 prefs::kWatchdogExtensionActive, |
338 false, | 333 false, |
339 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); | 334 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); |
340 } | 335 } |
341 | 336 |
342 // LOG ACTIONS. ---------------------------------------------------------------- | 337 // LOG ACTIONS. ---------------------------------------------------------------- |
343 | 338 |
344 void ActivityLog::LogAction(scoped_refptr<Action> action) { | 339 void ActivityLog::LogAction(scoped_refptr<Action> action) { |
345 if (!IsLogEnabled() || | 340 if (ActivityLogAPI::IsExtensionWhitelisted(action->extension_id())) |
346 ActivityLogAPI::IsExtensionWhitelisted(action->extension_id())) | |
347 return; | 341 return; |
348 | 342 |
349 // Perform some preprocessing of the Action data: convert tab IDs to URLs and | 343 // Perform some preprocessing of the Action data: convert tab IDs to URLs and |
350 // mask out incognito URLs if appropriate. | 344 // mask out incognito URLs if appropriate. |
351 if ((action->action_type() == Action::ACTION_API_CALL || | 345 if ((action->action_type() == Action::ACTION_API_CALL || |
352 action->action_type() == Action::ACTION_API_EVENT) && | 346 action->action_type() == Action::ACTION_API_EVENT) && |
353 StartsWithASCII(action->api_name(), "tabs.", true)) { | 347 StartsWithASCII(action->api_name(), "tabs.", true)) { |
354 LookupTabIds(action, profile_); | 348 LookupTabIds(action, profile_); |
355 } | 349 } |
356 | 350 |
357 // TODO(mvrable): Add any necessary processing of incognito URLs here, for | 351 // TODO(mvrable): Add any necessary processing of incognito URLs here, for |
358 // crbug.com/253368 | 352 // crbug.com/253368 |
359 | 353 |
360 if (policy_) | 354 if (IsDatabaseEnabled() && policy_) |
361 policy_->ProcessAction(action); | 355 policy_->ProcessAction(action); |
362 observers_->Notify(&Observer::OnExtensionActivity, action); | 356 if (IsWatchdogAppActive()) |
| 357 observers_->Notify(&Observer::OnExtensionActivity, action); |
363 if (testing_mode_) | 358 if (testing_mode_) |
364 LOG(INFO) << action->PrintForDebug(); | 359 LOG(INFO) << action->PrintForDebug(); |
365 } | 360 } |
366 | 361 |
367 void ActivityLog::OnScriptsExecuted( | 362 void ActivityLog::OnScriptsExecuted( |
368 const content::WebContents* web_contents, | 363 const content::WebContents* web_contents, |
369 const ExecutingScriptsMap& extension_ids, | 364 const ExecutingScriptsMap& extension_ids, |
370 int32 on_page_id, | 365 int32 on_page_id, |
371 const GURL& on_url) { | 366 const GURL& on_url) { |
372 if (!IsLogEnabled()) return; | |
373 Profile* profile = | 367 Profile* profile = |
374 Profile::FromBrowserContext(web_contents->GetBrowserContext()); | 368 Profile::FromBrowserContext(web_contents->GetBrowserContext()); |
375 const ExtensionService* extension_service = | 369 const ExtensionService* extension_service = |
376 ExtensionSystem::Get(profile)->extension_service(); | 370 ExtensionSystem::Get(profile)->extension_service(); |
377 const ExtensionSet* extensions = extension_service->extensions(); | 371 const ExtensionSet* extensions = extension_service->extensions(); |
378 const prerender::PrerenderManager* prerender_manager = | 372 const prerender::PrerenderManager* prerender_manager = |
379 prerender::PrerenderManagerFactory::GetForProfile( | 373 prerender::PrerenderManagerFactory::GetForProfile( |
380 Profile::FromBrowserContext(web_contents->GetBrowserContext())); | 374 Profile::FromBrowserContext(web_contents->GetBrowserContext())); |
381 | 375 |
382 for (ExecutingScriptsMap::const_iterator it = extension_ids.begin(); | 376 for (ExecutingScriptsMap::const_iterator it = extension_ids.begin(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback) { | 427 <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback) { |
434 if (policy_) { | 428 if (policy_) { |
435 policy_->ReadFilteredData( | 429 policy_->ReadFilteredData( |
436 extension_id, type, api_name, page_url, arg_url, callback); | 430 extension_id, type, api_name, page_url, arg_url, callback); |
437 } | 431 } |
438 } | 432 } |
439 | 433 |
440 // DELETE ACTIONS. ------------------------------------------------------------- | 434 // DELETE ACTIONS. ------------------------------------------------------------- |
441 | 435 |
442 void ActivityLog::RemoveURLs(const std::vector<GURL>& restrict_urls) { | 436 void ActivityLog::RemoveURLs(const std::vector<GURL>& restrict_urls) { |
443 if (!policy_ || !IsLogEnabled()) { | 437 if (!policy_) |
444 return; | 438 return; |
445 } | |
446 policy_->RemoveURLs(restrict_urls); | 439 policy_->RemoveURLs(restrict_urls); |
447 } | 440 } |
448 | 441 |
449 void ActivityLog::RemoveURLs(const std::set<GURL>& restrict_urls) { | 442 void ActivityLog::RemoveURLs(const std::set<GURL>& restrict_urls) { |
450 if (!policy_ || !IsLogEnabled()) { | 443 if (!policy_) |
451 return; | 444 return; |
452 } | |
453 | 445 |
454 std::vector<GURL> urls; | 446 std::vector<GURL> urls; |
455 for (std::set<GURL>::const_iterator it = restrict_urls.begin(); | 447 for (std::set<GURL>::const_iterator it = restrict_urls.begin(); |
456 it != restrict_urls.end(); ++it) { | 448 it != restrict_urls.end(); ++it) { |
457 urls.push_back(*it); | 449 urls.push_back(*it); |
458 } | 450 } |
459 policy_->RemoveURLs(urls); | 451 policy_->RemoveURLs(urls); |
460 } | 452 } |
461 | 453 |
462 void ActivityLog::RemoveURL(const GURL& url) { | 454 void ActivityLog::RemoveURL(const GURL& url) { |
463 if (url.is_empty()) | 455 if (url.is_empty()) |
464 return; | 456 return; |
465 std::vector<GURL> urls; | 457 std::vector<GURL> urls; |
466 urls.push_back(url); | 458 urls.push_back(url); |
467 RemoveURLs(urls); | 459 RemoveURLs(urls); |
468 } | 460 } |
469 | 461 |
470 } // namespace extensions | 462 } // namespace extensions |
OLD | NEW |