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