activity_log.h revision 0529e5d033099cbfc42635f6f6183833b09dff6e
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_
6#define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "base/callback.h"
13#include "base/observer_list_threadsafe.h"
14#include "base/synchronization/lock.h"
15#include "base/threading/thread.h"
16#include "chrome/browser/extensions/activity_log/activity_actions.h"
17#include "chrome/browser/extensions/activity_log/activity_log_policy.h"
18#include "chrome/browser/extensions/install_observer.h"
19#include "chrome/browser/extensions/tab_helper.h"
20#include "chrome/common/extensions/dom_action_types.h"
21#include "extensions/browser/api_activity_monitor.h"
22#include "extensions/browser/browser_context_keyed_api_factory.h"
23
24class Profile;
25
26namespace content {
27class BrowserContext;
28}
29
30namespace user_prefs {
31class PrefRegistrySyncable;
32}
33
34namespace extensions {
35class Extension;
36class InstallTracker;
37
38// A utility for tracing interesting activity for each extension.
39// It writes to an ActivityDatabase on a separate thread to record the activity.
40// Each profile has different extensions, so we keep a different database for
41// each profile.
42class ActivityLog : public BrowserContextKeyedAPI,
43                    public ApiActivityMonitor,
44                    public TabHelper::ScriptExecutionObserver,
45                    public InstallObserver {
46 public:
47  // Observers can listen for activity events. There is probably only one
48  // observer: the activityLogPrivate API.
49  class Observer {
50   public:
51    virtual void OnExtensionActivity(scoped_refptr<Action> activity) = 0;
52  };
53
54  static BrowserContextKeyedAPIFactory<ActivityLog>* GetFactoryInstance();
55
56  // ActivityLog is a KeyedService, so don't instantiate it with
57  // the constructor; use GetInstance instead.
58  static ActivityLog* GetInstance(content::BrowserContext* context);
59
60  // Add/remove observer: the activityLogPrivate API only listens when the
61  // ActivityLog extension is registered for an event.
62  void AddObserver(Observer* observer);
63  void RemoveObserver(Observer* observer);
64
65  // Logs an extension action: passes it to any installed policy to be logged
66  // to the database, to any observers, and logs to the console if in testing
67  // mode.
68  void LogAction(scoped_refptr<Action> action);
69
70  // Gets all actions that match the specified fields. URLs are treated like
71  // prefixes; other fields are exact matches. Empty strings are not matched to
72  // anything. For daysAgo, today is 0, yesterday is 1, etc.; a negative number
73  // of days is treated as a missing parameter.
74  void GetFilteredActions(
75      const std::string& extension_id,
76      const Action::ActionType type,
77      const std::string& api_name,
78      const std::string& page_url,
79      const std::string& arg_url,
80      const int days_ago,
81      const base::Callback
82          <void(scoped_ptr<std::vector<scoped_refptr<Action> > >)>& callback);
83
84  // Extension::InstallObserver
85  // We keep track of whether the whitelisted extension is installed; if it is,
86  // we want to recompute whether to have logging enabled.
87  virtual void OnExtensionLoaded(const Extension* extension) OVERRIDE;
88  virtual void OnExtensionUnloaded(const Extension* extension) OVERRIDE;
89  virtual void OnExtensionUninstalled(const Extension* extension) OVERRIDE;
90
91  // ApiActivityMonitor
92  virtual void OnApiEventDispatched(
93      const std::string& extension_id,
94      const std::string& event_name,
95      scoped_ptr<base::ListValue> event_args) OVERRIDE;
96  virtual void OnApiFunctionCalled(
97      const std::string& extension_id,
98      const std::string& api_name,
99      scoped_ptr<base::ListValue> event_args) OVERRIDE;
100
101  // KeyedService
102  virtual void Shutdown() OVERRIDE;
103
104  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
105
106  // Remove actions from the activity log database which IDs specified in the
107  // action_ids array.
108  void RemoveActions(const std::vector<int64>& action_ids);
109
110  // Clean up URLs from the activity log database.
111  // If restrict_urls is empty then all URLs in the activity log database are
112  // removed, otherwise only those in restrict_urls are removed.
113  void RemoveURLs(const std::vector<GURL>& restrict_urls);
114  void RemoveURLs(const std::set<GURL>& restrict_urls);
115  void RemoveURL(const GURL& url);
116
117  // Deletes the database associated with the policy that's currently in use.
118  void DeleteDatabase();
119
120  // If we're in a browser test, we need to pretend that the watchdog app is
121  // active.
122  void SetWatchdogAppActiveForTesting(bool active);
123
124 private:
125  friend class ActivityLogTest;
126  friend class BrowserContextKeyedAPIFactory<ActivityLog>;
127
128  explicit ActivityLog(content::BrowserContext* context);
129  virtual ~ActivityLog();
130
131  // Specifies if the Watchdog app is active (installed & enabled).
132  // If so, we need to log to the database and stream to the API.
133  bool IsWatchdogAppActive();
134
135  // Specifies if we need to record actions to the db. If so, we need to log to
136  // the database. This is true if the Watchdog app is active *or* the
137  // --enable-extension-activity-logging flag is set.
138  bool IsDatabaseEnabled();
139
140  // Delayed initialization of Install Tracker which waits until after the
141  // ExtensionSystem/ExtensionService are done with their own setup.
142  void InitInstallTracker();
143
144  // TabHelper::ScriptExecutionObserver implementation.
145  // Fires when a ContentScript is executed.
146  virtual void OnScriptsExecuted(
147      const content::WebContents* web_contents,
148      const ExecutingScriptsMap& extension_ids,
149      int32 page_id,
150      const GURL& on_url) OVERRIDE;
151
152  // At the moment, ActivityLog will use only one policy for summarization.
153  // These methods are used to choose and set the most appropriate policy.
154  // Changing policies at runtime is not recommended, and likely only should be
155  // done for unit tests.
156  void ChooseDatabasePolicy();
157  void SetDatabasePolicy(ActivityLogPolicy::PolicyType policy_type);
158
159  // BrowserContextKeyedAPI implementation.
160  static const char* service_name() { return "ActivityLog"; }
161  static const bool kServiceRedirectedInIncognito = true;
162  static const bool kServiceIsCreatedWithBrowserContext = false;
163
164  typedef ObserverListThreadSafe<Observer> ObserverList;
165  scoped_refptr<ObserverList> observers_;
166
167  // Policy objects are owned by the ActivityLog, but cannot be scoped_ptrs
168  // since they may need to do some cleanup work on the database thread.
169  // Calling policy->Close() will free the object; see the comments on the
170  // ActivityDatabase class for full details.
171
172  // The database policy object takes care of recording & looking up data:
173  // data summarization, compression, and logging. There should only be a
174  // database_policy_ if the Watchdog app is installed or flag is set.
175  ActivityLogDatabasePolicy* database_policy_;
176  ActivityLogPolicy::PolicyType database_policy_type_;
177
178  // The UMA policy is used for recording statistics about extension behavior.
179  // This policy is always in use, except for Incognito profiles.
180  ActivityLogPolicy* uma_policy_;
181
182  Profile* profile_;
183  bool db_enabled_;  // Whether logging to disk is currently enabled.
184  // testing_mode_ controls which policy is selected.
185  // * By default, we choose a policy that doesn't log most arguments to avoid
186  // saving too much data. We also elide some arguments for privacy reasons.
187  // * In testing mode, we choose a policy that logs all arguments.
188  // testing_mode_ also causes us to print to the console.
189  bool testing_mode_;
190  // We need the DB, FILE, and IO threads to write to the database.
191  // In some cases (tests), these threads might not exist, so we avoid
192  // dispatching anything to the policies/database to prevent things from
193  // exploding.
194  bool has_threads_;
195
196  // Used to track whether the whitelisted extension is installed. If it's
197  // added or removed, enabled_ may change.
198  InstallTracker* tracker_;
199
200  // Set if the watchdog app is installed and enabled. Maintained by
201  // kWatchdogExtensionActive pref variable. Since there are multiple valid
202  // extension IDs, this needs to be an int to count how many are installed.
203  int watchdog_apps_active_;
204
205  FRIEND_TEST_ALL_PREFIXES(ActivityLogApiTest, TriggerEvent);
206  FRIEND_TEST_ALL_PREFIXES(ActivityLogEnabledTest, AppAndCommandLine);
207  FRIEND_TEST_ALL_PREFIXES(ActivityLogEnabledTest, CommandLineSwitch);
208  FRIEND_TEST_ALL_PREFIXES(ActivityLogEnabledTest, NoSwitch);
209  FRIEND_TEST_ALL_PREFIXES(ActivityLogEnabledTest, PrefSwitch);
210  FRIEND_TEST_ALL_PREFIXES(ActivityLogEnabledTest, WatchdogSwitch);
211  DISALLOW_COPY_AND_ASSIGN(ActivityLog);
212};
213
214template <>
215void BrowserContextKeyedAPIFactory<ActivityLog>::DeclareFactoryDependencies();
216
217}  // namespace extensions
218
219#endif  // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_
220