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.
5 #ifndef CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_
6 #define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_
12 #include "base/callback.h"
13 #include "base/observer_list_threadsafe.h"
14 #include "base/scoped_observer.h"
15 #include "base/synchronization/lock.h"
16 #include "base/threading/thread.h"
17 #include "chrome/browser/extensions/activity_log/activity_actions.h"
18 #include "chrome/browser/extensions/activity_log/activity_log_policy.h"
19 #include "extensions/browser/api_activity_monitor.h"
20 #include "extensions/browser/browser_context_keyed_api_factory.h"
21 #include "extensions/browser/extension_registry_observer.h"
22 #include "extensions/browser/script_execution_observer.h"
23 #include "extensions/common/dom_action_types.h"
31 namespace user_prefs
{
32 class PrefRegistrySyncable
;
35 namespace extensions
{
37 class ExtensionRegistry
;
39 // A utility for tracing interesting activity for each extension.
40 // It writes to an ActivityDatabase on a separate thread to record the activity.
41 // Each profile has different extensions, so we keep a different database for
44 class ActivityLog
: public BrowserContextKeyedAPI
,
45 public ApiActivityMonitor
,
46 public ScriptExecutionObserver
,
47 public ExtensionRegistryObserver
{
49 // Observers can listen for activity events. There is probably only one
50 // observer: the activityLogPrivate API.
53 virtual void OnExtensionActivity(scoped_refptr
<Action
> activity
) = 0;
56 static BrowserContextKeyedAPIFactory
<ActivityLog
>* GetFactoryInstance();
58 // ActivityLog is a KeyedService, so don't instantiate it with
59 // the constructor; use GetInstance instead.
60 static ActivityLog
* GetInstance(content::BrowserContext
* context
);
62 // Add/remove observer: the activityLogPrivate API only listens when the
63 // ActivityLog extension is registered for an event.
64 void AddObserver(Observer
* observer
);
65 void RemoveObserver(Observer
* observer
);
67 // Logs an extension action: passes it to any installed policy to be logged
68 // to the database, to any observers, and logs to the console if in testing
70 void LogAction(scoped_refptr
<Action
> action
);
72 // Gets all actions that match the specified fields. URLs are treated like
73 // prefixes; other fields are exact matches. Empty strings are not matched to
74 // anything. For daysAgo, today is 0, yesterday is 1, etc.; a negative number
75 // of days is treated as a missing parameter.
76 void GetFilteredActions(
77 const std::string
& extension_id
,
78 const Action::ActionType type
,
79 const std::string
& api_name
,
80 const std::string
& page_url
,
81 const std::string
& arg_url
,
84 <void(scoped_ptr
<std::vector
<scoped_refptr
<Action
> > >)>& callback
);
86 // ExtensionRegistryObserver.
87 // We keep track of whether the whitelisted extension is installed; if it is,
88 // we want to recompute whether to have logging enabled.
89 void OnExtensionLoaded(content::BrowserContext
* browser_context
,
90 const Extension
* extension
) override
;
91 void OnExtensionUnloaded(content::BrowserContext
* browser_context
,
92 const Extension
* extension
,
93 UnloadedExtensionInfo::Reason reason
) override
;
94 void OnExtensionUninstalled(content::BrowserContext
* browser_context
,
95 const Extension
* extension
,
96 extensions::UninstallReason reason
) override
;
98 // ApiActivityMonitor.
99 void OnApiEventDispatched(const std::string
& extension_id
,
100 const std::string
& event_name
,
101 scoped_ptr
<base::ListValue
> event_args
) override
;
102 void OnApiFunctionCalled(const std::string
& extension_id
,
103 const std::string
& api_name
,
104 scoped_ptr
<base::ListValue
> event_args
) override
;
106 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable
* registry
);
108 // Remove actions from the activity log database which IDs specified in the
110 void RemoveActions(const std::vector
<int64
>& action_ids
);
112 // Clean up URLs from the activity log database.
113 // If restrict_urls is empty then all URLs in the activity log database are
114 // removed, otherwise only those in restrict_urls are removed.
115 void RemoveURLs(const std::vector
<GURL
>& restrict_urls
);
116 void RemoveURLs(const std::set
<GURL
>& restrict_urls
);
117 void RemoveURL(const GURL
& url
);
119 // Deletes the database associated with the policy that's currently in use.
120 void DeleteDatabase();
122 // If we're in a browser test, we need to pretend that the watchdog app is
124 void SetWatchdogAppActiveForTesting(bool active
);
127 friend class ActivityLogTest
;
128 friend class BrowserContextKeyedAPIFactory
<ActivityLog
>;
130 explicit ActivityLog(content::BrowserContext
* context
);
131 ~ActivityLog() override
;
133 // Specifies if the Watchdog app is active (installed & enabled).
134 // If so, we need to log to the database and stream to the API.
135 bool IsWatchdogAppActive();
137 // Specifies if we need to record actions to the db. If so, we need to log to
138 // the database. This is true if the Watchdog app is active *or* the
139 // --enable-extension-activity-logging flag is set.
140 bool IsDatabaseEnabled();
142 // ScriptExecutionObserver implementation.
143 // Fires when a ContentScript is executed.
144 void OnScriptsExecuted(const content::WebContents
* web_contents
,
145 const ExecutingScriptsMap
& extension_ids
,
146 const GURL
& on_url
) override
;
148 // At the moment, ActivityLog will use only one policy for summarization.
149 // These methods are used to choose and set the most appropriate policy.
150 // Changing policies at runtime is not recommended, and likely only should be
151 // done for unit tests.
152 void ChooseDatabasePolicy();
153 void SetDatabasePolicy(ActivityLogPolicy::PolicyType policy_type
);
155 // BrowserContextKeyedAPI implementation.
156 static const char* service_name() { return "ActivityLog"; }
157 static const bool kServiceRedirectedInIncognito
= true;
158 static const bool kServiceIsCreatedWithBrowserContext
= false;
160 typedef base::ObserverListThreadSafe
<Observer
> ObserverList
;
161 scoped_refptr
<ObserverList
> observers_
;
163 // Policy objects are owned by the ActivityLog, but cannot be scoped_ptrs
164 // since they may need to do some cleanup work on the database thread.
165 // Calling policy->Close() will free the object; see the comments on the
166 // ActivityDatabase class for full details.
168 // The database policy object takes care of recording & looking up data:
169 // data summarization, compression, and logging. There should only be a
170 // database_policy_ if the Watchdog app is installed or flag is set.
171 ActivityLogDatabasePolicy
* database_policy_
;
172 ActivityLogPolicy::PolicyType database_policy_type_
;
174 // The UMA policy is used for recording statistics about extension behavior.
175 // This policy is always in use, except for Incognito profiles.
176 ActivityLogPolicy
* uma_policy_
;
179 bool db_enabled_
; // Whether logging to disk is currently enabled.
180 // testing_mode_ controls which policy is selected.
181 // * By default, we choose a policy that doesn't log most arguments to avoid
182 // saving too much data. We also elide some arguments for privacy reasons.
183 // * In testing mode, we choose a policy that logs all arguments.
184 // testing_mode_ also causes us to print to the console.
186 // We need the DB, FILE, and IO threads to write to the database.
187 // In some cases (tests), these threads might not exist, so we avoid
188 // dispatching anything to the policies/database to prevent things from
192 // Used to track whether the whitelisted extension is installed. If it's
193 // added or removed, enabled_ may change.
194 ScopedObserver
<extensions::ExtensionRegistry
,
195 extensions::ExtensionRegistryObserver
>
196 extension_registry_observer_
;
198 // Set if the watchdog app is installed and enabled. Maintained by
199 // kWatchdogExtensionActive pref variable. Since there are multiple valid
200 // extension IDs, this needs to be an int to count how many are installed.
201 int watchdog_apps_active_
;
203 FRIEND_TEST_ALL_PREFIXES(ActivityLogApiTest
, TriggerEvent
);
204 FRIEND_TEST_ALL_PREFIXES(ActivityLogEnabledTest
, AppAndCommandLine
);
205 FRIEND_TEST_ALL_PREFIXES(ActivityLogEnabledTest
, CommandLineSwitch
);
206 FRIEND_TEST_ALL_PREFIXES(ActivityLogEnabledTest
, NoSwitch
);
207 FRIEND_TEST_ALL_PREFIXES(ActivityLogEnabledTest
, PrefSwitch
);
208 FRIEND_TEST_ALL_PREFIXES(ActivityLogEnabledTest
, WatchdogSwitch
);
209 DISALLOW_COPY_AND_ASSIGN(ActivityLog
);
213 void BrowserContextKeyedAPIFactory
<ActivityLog
>::DeclareFactoryDependencies();
215 } // namespace extensions
217 #endif // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_H_