1 // Copyright 2013 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_POLICY_H_
6 #define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_POLICY_H_
13 #include "base/bind.h"
14 #include "base/bind_helpers.h"
15 #include "base/callback.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/values.h"
18 #include "chrome/browser/extensions/activity_log/activity_actions.h"
19 #include "chrome/browser/extensions/activity_log/activity_database.h"
20 #include "chrome/common/extensions/api/activity_log_private.h"
21 #include "content/public/browser/browser_thread.h"
31 namespace extensions
{
35 // An abstract class for processing and summarizing activity log data.
36 // Subclasses will generally store data in an SQLite database (the
37 // ActivityLogDatabasePolicy subclass includes some helper methods to assist
38 // with this case), but this is not absolutely required.
40 // Implementations should support:
41 // (1) Receiving Actions to process, and summarizing, compression, and storing
42 // these as appropriate.
43 // (2) Reading Actions back from storage.
44 // (3) Cleaning of URLs
46 // Implementations based on a database should likely implement
47 // ActivityDatabase::Delegate, which provides hooks on database events and
48 // allows the database to periodically request that actions (which the policy
49 // is responsible for queueing) be flushed to storage.
51 // Since every policy implementation might summarize data differently, the
52 // database implementation is policy-specific and therefore completely
53 // encapsulated in the policy class. All the member functions can be called
55 class ActivityLogPolicy
{
63 // Parameters are the profile and the thread that will be used to execute
64 // the callback when ReadData is called.
65 // TODO(felt,dbabic) Since only ReadData uses thread_id, it would be
66 // cleaner to pass thread_id as a param of ReadData directly.
67 explicit ActivityLogPolicy(Profile
* profile
);
69 // Instead of a public destructor, ActivityLogPolicy objects have a Close()
70 // method which will cause the object to be deleted (but may do so on another
71 // thread or in a deferred fashion).
72 virtual void Close() = 0;
74 // Updates the internal state of the model summarizing actions and possibly
75 // writes to the database. Implements the default policy storing internal
76 // state to memory every 5 min.
77 virtual void ProcessAction(scoped_refptr
<Action
> action
) = 0;
79 // For unit testing only.
80 void SetClockForTesting(scoped_ptr
<base::Clock
> clock
);
82 // A collection of methods that are useful for implementing policies. These
83 // are all static methods; the ActivityLogPolicy::Util class cannot be
84 // instantiated. This is nested within ActivityLogPolicy to make calling
85 // these methods more convenient from within a policy, but they are public.
88 // A collection of API calls, used to specify whitelists for argument
90 typedef std::set
<std::pair
<Action::ActionType
, std::string
> > ApiSet
;
92 // Serialize a Value as a JSON string. Returns an empty string if value is
94 static std::string
Serialize(const base::Value
* value
);
96 // Removes potentially privacy-sensitive data that should not be logged.
97 // This should generally be called on an Action before logging, unless
98 // debugging flags are enabled. Modifies the Action object in place; if
99 // the action might be shared with other users, it is up to the caller to
100 // call ->Clone() first.
101 static void StripPrivacySensitiveFields(scoped_refptr
<Action
> action
);
103 // Strip arguments from most API actions, preserving actions only for a
104 // whitelisted set. Modifies the Action object in-place.
105 static void StripArguments(const ApiSet
& api_whitelist
,
106 scoped_refptr
<Action
> action
);
108 // Given a base day (timestamp at local midnight), computes the timestamp
109 // at midnight the given number of days before or after.
110 static base::Time
AddDays(const base::Time
& base_date
, int days
);
112 // Compute the time bounds that should be used for a database query to
113 // cover a time range days_ago days in the past, relative to the specified
115 static void ComputeDatabaseTimeBounds(const base::Time
& now
,
120 // Deletes obsolete database tables from an activity log database. This
121 // can be used in InitDatabase() methods of ActivityLogDatabasePolicy
122 // subclasses to clean up data from old versions of the activity logging
123 // code. Returns true on success, false on database error.
124 static bool DropObsoleteTables(sql::Connection
* db
);
127 DISALLOW_IMPLICIT_CONSTRUCTORS(Util
);
131 // An ActivityLogPolicy is not directly destroyed. Instead, call Close()
132 // which will cause the object to be deleted when it is safe.
133 virtual ~ActivityLogPolicy();
135 // Returns Time::Now() unless a mock clock has been installed with
136 // SetClockForTesting, in which case the time according to that clock is used
138 base::Time
Now() const;
141 // Support for a mock clock for testing purposes. This is used by ReadData
142 // to determine the date for "today" when when interpreting date ranges to
143 // fetch. This has no effect on batching of writes to the database.
144 scoped_ptr
<base::Clock
> testing_clock_
;
146 DISALLOW_COPY_AND_ASSIGN(ActivityLogPolicy
);
149 // A subclass of ActivityLogPolicy which is designed for policies that use
150 // database storage; it contains several useful helper methods.
151 class ActivityLogDatabasePolicy
: public ActivityLogPolicy
,
152 public ActivityDatabase::Delegate
{
154 ActivityLogDatabasePolicy(Profile
* profile
,
155 const base::FilePath
& database_name
);
157 // Initializes an activity log policy database. This needs to be called after
158 // constructing ActivityLogDatabasePolicy.
161 // Requests that in-memory state be written to the database. This method can
162 // be called from any thread, but the database writes happen asynchronously
163 // on the database thread.
164 virtual void Flush();
166 // Gets all actions that match the specified fields. URLs are treated like
167 // prefixes; other fields are exact matches. Empty strings are not matched to
168 // anything. For the date: 0 = today, 1 = yesterday, etc.; if the data is
169 // negative, it will be treated as missing.
170 virtual void ReadFilteredData(
171 const std::string
& extension_id
,
172 const Action::ActionType type
,
173 const std::string
& api_name
,
174 const std::string
& page_url
,
175 const std::string
& arg_url
,
178 <void(scoped_ptr
<Action::ActionVector
>)>& callback
) = 0;
180 // Remove actions (rows) which IDs are in the action_ids array.
181 virtual void RemoveActions(const std::vector
<int64
>& action_ids
) = 0;
183 // Clean the relevant URL data. The cleaning may need to be different for
184 // different policies. If restrict_urls is empty then all URLs are removed.
185 virtual void RemoveURLs(const std::vector
<GURL
>& restrict_urls
) = 0;
187 // Remove all rows relating to a given extension.
188 virtual void RemoveExtensionData(const std::string
& extension_id
) = 0;
190 // Deletes everything in the database.
191 virtual void DeleteDatabase() = 0;
194 // The Schedule methods dispatch the calls to the database on a
196 template<typename DatabaseType
, typename DatabaseFunc
>
197 void ScheduleAndForget(DatabaseType db
, DatabaseFunc func
) {
198 content::BrowserThread::PostTask(
199 content::BrowserThread::DB
,
201 base::Bind(func
, base::Unretained(db
)));
204 template<typename DatabaseType
, typename DatabaseFunc
, typename ArgA
>
205 void ScheduleAndForget(DatabaseType db
, DatabaseFunc func
, ArgA a
) {
206 content::BrowserThread::PostTask(
207 content::BrowserThread::DB
,
209 base::Bind(func
, base::Unretained(db
), a
));
212 template<typename DatabaseType
, typename DatabaseFunc
,
213 typename ArgA
, typename ArgB
>
214 void ScheduleAndForget(DatabaseType db
, DatabaseFunc func
, ArgA a
, ArgB b
) {
215 content::BrowserThread::PostTask(
216 content::BrowserThread::DB
,
218 base::Bind(func
, base::Unretained(db
), a
, b
));
221 // Access to the underlying ActivityDatabase.
222 ActivityDatabase
* activity_database() const { return db_
; }
224 // Access to the SQL connection in the ActivityDatabase. This should only be
225 // called from the database thread. May return NULL if the database is not
227 sql::Connection
* GetDatabaseConnection() const;
230 // See the comments for the ActivityDatabase class for a discussion of how
231 // database cleanup runs.
232 ActivityDatabase
* db_
;
233 base::FilePath database_path_
;
236 } // namespace extensions
238 #endif // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_ACTIVITY_LOG_POLICY_H_