1ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// found in the LICENSE file.
4ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
5ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#ifndef CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_COUNTING_POLICY_H_
6ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#define CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_COUNTING_POLICY_H_
7ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
8ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include <string>
9ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
10ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "base/containers/hash_tables.h"
11ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "chrome/browser/extensions/activity_log/activity_database.h"
12ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "chrome/browser/extensions/activity_log/activity_log_policy.h"
13ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "chrome/browser/extensions/activity_log/database_string_table.h"
14ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
15ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochnamespace extensions {
16ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// A policy for logging the stream of actions, but with most arguments stripped
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// out (to improve privacy and reduce database size) and with multiple
1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// identical rows combined together using a count column to track the total
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// number of repetitions.  Identical rows within the same day are merged, but
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// actions on separate days are kept distinct.  Data is kept for up to a few
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// days then deleted.
23ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass CountingPolicy : public ActivityLogDatabasePolicy {
24ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch public:
25ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  explicit CountingPolicy(Profile* profile);
26ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual ~CountingPolicy();
27ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
28ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual void ProcessAction(scoped_refptr<Action> action) OVERRIDE;
29ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void ReadFilteredData(
31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      const std::string& extension_id,
32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      const Action::ActionType type,
33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      const std::string& api_name,
34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      const std::string& page_url,
35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      const std::string& arg_url,
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const int days_ago,
37424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      const base::Callback
38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          <void(scoped_ptr<Action::ActionVector>)>& callback) OVERRIDE;
39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
40ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual void Close() OVERRIDE;
41ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
42ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Gets or sets the amount of time that old records are kept in the database.
43ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const base::TimeDelta& retention_time() const { return retention_time_; }
44ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void set_retention_time(const base::TimeDelta& delta) {
45ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    retention_time_ = delta;
46ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
47ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Remove actions (rows) which IDs are specified in the action_ids array.
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void RemoveActions(const std::vector<int64>& action_ids) OVERRIDE;
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Clean the URL data stored for this policy.
52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  virtual void RemoveURLs(const std::vector<GURL>&) OVERRIDE;
53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Clean the data related to this extension for this policy.
55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void RemoveExtensionData(const std::string& extension_id) OVERRIDE;
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Delete everything in the database.
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void DeleteDatabase() OVERRIDE;
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
60ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // The main database table, and the name for a read-only view that
61ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // decompresses string values for easier parsing.
62ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  static const char* kTableName;
63ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  static const char* kReadViewName;
64ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
65ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch protected:
66ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // The ActivityDatabase::Delegate interface.  These are always called from
67ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // the database thread.
68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual bool InitDatabase(sql::Connection* db) OVERRIDE;
69ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual bool FlushDatabase(sql::Connection* db) OVERRIDE;
70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual void OnDatabaseFailure() OVERRIDE;
71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual void OnDatabaseClose() OVERRIDE;
72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch private:
743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // A type used to track pending writes to the database.  The key is an action
753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // to write; the value is the amount by which the count field should be
763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // incremented in the database.
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef std::map<
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_refptr<Action>,
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      int,
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ActionComparatorExcludingTimeAndActionId>
813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ActionQueue;
823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
83ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Adds an Action to those to be written out; this is an internal method used
84ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // by ProcessAction and is called on the database thread.
85ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void QueueAction(scoped_refptr<Action> action);
86ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
87ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Internal method to read data from the database; called on the database
88ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // thread.
89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  scoped_ptr<Action::ActionVector> DoReadFilteredData(
90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      const std::string& extension_id,
91424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      const Action::ActionType type,
92424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      const std::string& api_name,
93424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      const std::string& page_url,
9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const std::string& arg_url,
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      const int days_ago);
96424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The implementation of RemoveActions; this must only run on the database
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // thread.
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void DoRemoveActions(const std::vector<int64>& action_ids);
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
101424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // The implementation of RemoveURLs; this must only run on the database
102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // thread.
103424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void DoRemoveURLs(const std::vector<GURL>& restrict_urls);
104424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // The implementation of RemoveExtensionData; this must only run on the
106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // database thread.
107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void DoRemoveExtensionData(const std::string& extension_id);
108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // The implementation of DeleteDatabase; called on the database thread.
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void DoDeleteDatabase();
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
112ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Cleans old records from the activity log database.
113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  bool CleanOlderThan(sql::Connection* db, const base::Time& cutoff);
114ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
115ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Cleans unused interned strings from the database.  This should be run
116ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // after deleting rows from the main log table to clean out stale values.
117ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  bool CleanStringTables(sql::Connection* db);
118ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
119ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // API calls for which complete arguments should be logged.
12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Util::ApiSet api_arg_whitelist_;
121ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
122ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Tables for mapping strings to integers for shrinking database storage
123ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // requirements.  URLs are kept in a separate table from other strings to
124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // make history clearing simpler.
125ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DatabaseStringTable string_table_;
126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DatabaseStringTable url_table_;
127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
128ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Tracks any pending updates to be written to the database, if write
129ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // batching is turned on.  Should only be accessed from the database thread.
1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ActionQueue queued_actions_;
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // All queued actions must fall on the same day, so that we do not
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // accidentally aggregate actions that should be kept separate.
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // queued_actions_date_ is the date (timestamp at local midnight) of all the
1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // actions in queued_actions_.
1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::Time queued_actions_date_;
137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // The amount of time old activity log records should be kept in the
139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // database.  This time is subtracted from the current time, rounded down to
140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // midnight, and rows older than this are deleted from the database when
141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // cleaning runs.
142ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  base::TimeDelta retention_time_;
143ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
144ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // The time at which old activity log records were last cleaned out of the
145ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // database (only tracked for this browser session).  Old records are deleted
146ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // on the first database flush, and then every 12 hours subsequently.
147ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  base::Time last_database_cleaning_time_;
148ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  friend class CountingPolicyTest;
150424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(CountingPolicyTest, EarlyFlush);
151ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  FRIEND_TEST_ALL_PREFIXES(CountingPolicyTest, MergingAndExpiring);
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(CountingPolicyTest, StringTableCleaning);
153ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch};
154ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
155ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}  // namespace extensions
156ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
157ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#endif  // CHROME_BROWSER_EXTENSIONS_ACTIVITY_LOG_COUNTING_POLICY_H_
158