17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file.
47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h"
6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/callback.h"
8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/command_line.h"
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/files/file_path.h"
10a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/json/json_reader.h"
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/json/json_string_value_serializer.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/logging.h"
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/string16.h"
14ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/strings/stringprintf.h"
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/extensions/activity_log/activity_action_constants.h"
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/extensions/activity_log/activity_database.h"
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "extensions/common/dom_action_types.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "sql/error_delegate_util.h"
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "sql/transaction.h"
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using base::Callback;
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using base::FilePath;
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using base::Time;
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using base::Unretained;
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)using content::BrowserThread;
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace constants = activity_log_constants;
33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace extensions {
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
36ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochconst char* FullStreamUIPolicy::kTableName = "activitylog_full";
37ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochconst char* FullStreamUIPolicy::kTableContentFields[] = {
38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  "extension_id", "time", "action_type", "api_name", "args", "page_url",
39558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  "page_title", "arg_url", "other"
40ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch};
41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochconst char* FullStreamUIPolicy::kTableFieldTypes[] = {
42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  "LONGVARCHAR NOT NULL", "INTEGER", "INTEGER", "LONGVARCHAR", "LONGVARCHAR",
43558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR", "LONGVARCHAR"
44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch};
45ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochconst int FullStreamUIPolicy::kTableFieldCount =
46ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    arraysize(FullStreamUIPolicy::kTableContentFields);
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)FullStreamUIPolicy::FullStreamUIPolicy(Profile* profile)
49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : ActivityLogDatabasePolicy(
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          profile,
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          FilePath(chrome::kExtensionActivityLogFilename)) {}
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)FullStreamUIPolicy::~FullStreamUIPolicy() {}
54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool FullStreamUIPolicy::InitDatabase(sql::Connection* db) {
56ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  if (!Util::DropObsoleteTables(db))
57ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return false;
58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
59ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Create the unified activity log entry table.
60ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return ActivityDatabase::InitializeTable(db,
61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                           kTableName,
62ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                           kTableContentFields,
63ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                           kTableFieldTypes,
64ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                           arraysize(kTableContentFields));
657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool FullStreamUIPolicy::FlushDatabase(sql::Connection* db) {
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (queued_actions_.empty())
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return true;
70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  sql::Transaction transaction(db);
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!transaction.Begin())
73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return false;
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::string sql_str =
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      "INSERT INTO " + std::string(FullStreamUIPolicy::kTableName) +
77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      " (extension_id, time, action_type, api_name, args, "
78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      "page_url, page_title, arg_url, other) VALUES (?,?,?,?,?,?,?,?,?)";
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  sql::Statement statement(db->GetCachedStatement(
80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      sql::StatementID(SQL_FROM_HERE), sql_str.c_str()));
81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  Action::ActionVector::size_type i;
83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  for (i = 0; i != queued_actions_.size(); ++i) {
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const Action& action = *queued_actions_[i].get();
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    statement.Reset(true);
86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    statement.BindString(0, action.extension_id());
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    statement.BindInt64(1, action.time().ToInternalValue());
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    statement.BindInt(2, static_cast<int>(action.action_type()));
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    statement.BindString(3, action.api_name());
90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (action.args()) {
91ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      statement.BindString(4, Util::Serialize(action.args()));
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
93ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    std::string page_url_string = action.SerializePageUrl();
94ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (!page_url_string.empty()) {
95ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      statement.BindString(5, page_url_string);
96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
97ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (!action.page_title().empty()) {
98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      statement.BindString(6, action.page_title());
99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    std::string arg_url_string = action.SerializeArgUrl();
101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (!arg_url_string.empty()) {
102424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      statement.BindString(7, arg_url_string);
103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (action.other()) {
105ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      statement.BindString(8, Util::Serialize(action.other()));
106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (!statement.Run()) {
109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      LOG(ERROR) << "Activity log database I/O failed: " << sql_str;
110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return false;
111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!transaction.Commit())
115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return false;
116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  queued_actions_.clear();
118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return true;
119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
121424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)scoped_ptr<Action::ActionVector> FullStreamUIPolicy::DoReadFilteredData(
122424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const std::string& extension_id,
123424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const Action::ActionType type,
124424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const std::string& api_name,
125424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const std::string& page_url,
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& arg_url,
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const int days_ago) {
128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Ensure data is flushed to the database first so that we query over all
129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // data.
130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately);
131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  scoped_ptr<Action::ActionVector> actions(new Action::ActionVector());
132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
133424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  sql::Connection* db = GetDatabaseConnection();
134424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!db) {
135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return actions.Pass();
136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Build up the query based on which parameters were specified.
139424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  std::string where_str = "";
140424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  std::string where_next = "";
141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!extension_id.empty()) {
142424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    where_str += "extension_id=?";
143424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    where_next = " AND ";
144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!api_name.empty()) {
146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    where_str += where_next + "api_name=?";
147424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    where_next = " AND ";
148424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
149424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (type != Action::ACTION_ANY) {
150424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    where_str += where_next + "action_type=?";
151424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    where_next = " AND ";
152424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
153424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!page_url.empty()) {
154424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    where_str += where_next + "page_url LIKE ?";
155424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    where_next = " AND ";
156424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
157424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!arg_url.empty()) {
158424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    where_str += where_next + "arg_url LIKE ?";
159424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (days_ago >= 0)
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    where_str += where_next + "time BETWEEN ? AND ?";
162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  std::string query_str = base::StringPrintf(
163424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      "SELECT extension_id,time,action_type,api_name,args,page_url,page_title,"
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "arg_url,other,rowid FROM %s %s %s ORDER BY time DESC LIMIT 300",
165424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      kTableName,
16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      where_str.empty() ? "" : "WHERE",
167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      where_str.c_str());
168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  sql::Statement query(db->GetUniqueStatement(query_str.c_str()));
169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  int i = -1;
170424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!extension_id.empty())
171424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    query.BindString(++i, extension_id);
172424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!api_name.empty())
173424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    query.BindString(++i, api_name);
174424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (type != Action::ACTION_ANY)
175424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    query.BindInt(++i, static_cast<int>(type));
176424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!page_url.empty())
177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    query.BindString(++i, page_url + "%");
178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!arg_url.empty())
179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    query.BindString(++i, arg_url + "%");
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (days_ago >= 0) {
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int64 early_bound;
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int64 late_bound;
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    Util::ComputeDatabaseTimeBounds(Now(), days_ago, &early_bound, &late_bound);
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    query.BindInt64(++i, early_bound);
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    query.BindInt64(++i, late_bound);
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Execute the query and get results.
189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  while (query.is_valid() && query.Step()) {
190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    scoped_refptr<Action> action =
191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        new Action(query.ColumnString(0),
192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   base::Time::FromInternalValue(query.ColumnInt64(1)),
193424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                   static_cast<Action::ActionType>(query.ColumnInt(2)),
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   query.ColumnString(3), query.ColumnInt64(9));
195424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (query.ColumnType(4) != sql::COLUMN_TYPE_NULL) {
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_ptr<base::Value> parsed_value(
198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          base::JSONReader::Read(query.ColumnString(4)));
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (parsed_value && parsed_value->IsType(base::Value::TYPE_LIST)) {
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        action->set_args(make_scoped_ptr(
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            static_cast<base::ListValue*>(parsed_value.release())));
202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      }
203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    action->ParsePageUrl(query.ColumnString(5));
206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    action->set_page_title(query.ColumnString(6));
207424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    action->ParseArgUrl(query.ColumnString(7));
208424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
209424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (query.ColumnType(8) != sql::COLUMN_TYPE_NULL) {
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      scoped_ptr<base::Value> parsed_value(
211424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)          base::JSONReader::Read(query.ColumnString(8)));
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (parsed_value && parsed_value->IsType(base::Value::TYPE_DICTIONARY)) {
213424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        action->set_other(make_scoped_ptr(
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            static_cast<base::DictionaryValue*>(parsed_value.release())));
215424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      }
216424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    actions->push_back(action);
218424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
220424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return actions.Pass();
221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FullStreamUIPolicy::DoRemoveActions(const std::vector<int64>& action_ids) {
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (action_ids.empty())
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sql::Connection* db = GetDatabaseConnection();
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!db) {
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LOG(ERROR) << "Unable to connect to database";
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Flush data first so the activity removal affects queued-up data as well.
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately);
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sql::Transaction transaction(db);
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!transaction.Begin())
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string statement_str =
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::StringPrintf("DELETE FROM %s WHERE rowid = ?", kTableName);
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sql::Statement statement(db->GetCachedStatement(
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      sql::StatementID(SQL_FROM_HERE), statement_str.c_str()));
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < action_ids.size(); i++) {
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    statement.Reset(true);
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    statement.BindInt64(0, action_ids[i]);
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!statement.Run()) {
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LOG(ERROR) << "Removing activities from database failed: "
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 << statement.GetSQLStatement();
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!transaction.Commit()) {
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LOG(ERROR) << "Removing activities from database failed";
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
259424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void FullStreamUIPolicy::DoRemoveURLs(const std::vector<GURL>& restrict_urls) {
260424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  sql::Connection* db = GetDatabaseConnection();
261424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!db) {
262424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    LOG(ERROR) << "Unable to connect to database";
263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Make sure any queued in memory are sent to the database before cleaning.
267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately);
268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // If no restrictions then then all URLs need to be removed.
270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (restrict_urls.empty()) {
271424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    sql::Statement statement;
272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    std::string sql_str = base::StringPrintf(
273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        "UPDATE %s SET page_url=NULL,page_title=NULL,arg_url=NULL",
274424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        kTableName);
275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    statement.Assign(db->GetCachedStatement(
276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        sql::StatementID(SQL_FROM_HERE), sql_str.c_str()));
277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!statement.Run()) {
279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      LOG(ERROR) << "Removing URLs from database failed: "
280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 << statement.GetSQLStatement();
281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // If URLs are specified then restrict to only those URLs.
286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  for (size_t i = 0; i < restrict_urls.size(); ++i) {
287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!restrict_urls[i].is_valid()) {
288424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      continue;
289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Remove any matching page url info.
292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    sql::Statement statement;
293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    std::string sql_str = base::StringPrintf(
294424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      "UPDATE %s SET page_url=NULL,page_title=NULL WHERE page_url=?",
295424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      kTableName);
296424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    statement.Assign(db->GetCachedStatement(
297424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        sql::StatementID(SQL_FROM_HERE), sql_str.c_str()));
298424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    statement.BindString(0, restrict_urls[i].spec());
299424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!statement.Run()) {
301424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      LOG(ERROR) << "Removing page URL from database failed: "
302424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 << statement.GetSQLStatement();
303424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      return;
304424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
305424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
306424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Remove any matching arg urls.
307424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    sql_str = base::StringPrintf("UPDATE %s SET arg_url=NULL WHERE arg_url=?",
308424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                 kTableName);
309424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    statement.Assign(db->GetCachedStatement(
310424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        sql::StatementID(SQL_FROM_HERE), sql_str.c_str()));
311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    statement.BindString(0, restrict_urls[i].spec());
312424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
313424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (!statement.Run()) {
314424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      LOG(ERROR) << "Removing arg URL from database failed: "
315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 << statement.GetSQLStatement();
316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      return;
317424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
319424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
320424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
321d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void FullStreamUIPolicy::DoRemoveExtensionData(
322d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const std::string& extension_id) {
323d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (extension_id.empty())
324d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
325d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
326d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  sql::Connection* db = GetDatabaseConnection();
327d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!db) {
328d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    LOG(ERROR) << "Unable to connect to database";
329d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
331d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
332d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Make sure any queued in memory are sent to the database before cleaning.
333d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately);
334d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
335d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  std::string sql_str = base::StringPrintf(
336d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      "DELETE FROM %s WHERE extension_id=?", kTableName);
337d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  sql::Statement statement;
338d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  statement.Assign(
339d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      db->GetCachedStatement(sql::StatementID(SQL_FROM_HERE), sql_str.c_str()));
340d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  statement.BindString(0, extension_id);
341d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!statement.Run()) {
342d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    LOG(ERROR) << "Removing URLs for extension "
343d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)               << extension_id << "from database failed: "
344d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)               << statement.GetSQLStatement();
345d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
346d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
347d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
34858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void FullStreamUIPolicy::DoDeleteDatabase() {
34958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  sql::Connection* db = GetDatabaseConnection();
35058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!db) {
35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    LOG(ERROR) << "Unable to connect to database";
35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
35358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
35558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  queued_actions_.clear();
35658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
35758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Not wrapped in a transaction because the deletion should happen even if
35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // the vacuuming fails.
35958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::string sql_str = base::StringPrintf("DELETE FROM %s;", kTableName);
36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  sql::Statement statement(db->GetCachedStatement(
36158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      sql::StatementID(SQL_FROM_HERE), sql_str.c_str()));
36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!statement.Run()) {
36358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    LOG(ERROR) << "Deleting the database failed: "
36458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)               << statement.GetSQLStatement();
36558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
36658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
36758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  statement.Clear();
36858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  statement.Assign(db->GetCachedStatement(sql::StatementID(SQL_FROM_HERE),
36958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                          "VACUUM"));
37058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!statement.Run()) {
37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    LOG(ERROR) << "Vacuuming the database failed: "
37258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)               << statement.GetSQLStatement();
37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
37458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
37558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void FullStreamUIPolicy::OnDatabaseFailure() {
377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  queued_actions_.clear();
378a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FullStreamUIPolicy::OnDatabaseClose() {
3817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  delete this;
3827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FullStreamUIPolicy::Close() {
3857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // The policy object should have never been created if there's no DB thread.
3867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::DB));
387a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ScheduleAndForget(activity_database(), &ActivityDatabase::Close);
3887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
3897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
390424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void FullStreamUIPolicy::ReadFilteredData(
391424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const std::string& extension_id,
392424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const Action::ActionType type,
393424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const std::string& api_name,
394424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const std::string& page_url,
395424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const std::string& arg_url,
39658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const int days_ago,
397424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const base::Callback
398424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        <void(scoped_ptr<Action::ActionVector>)>& callback) {
399424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  BrowserThread::PostTaskAndReplyWithResult(
400424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      BrowserThread::DB,
401424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      FROM_HERE,
402424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      base::Bind(&FullStreamUIPolicy::DoReadFilteredData,
403424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 base::Unretained(this),
404424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 extension_id,
405424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 type,
406424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 api_name,
407424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                 page_url,
40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 arg_url,
40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                 days_ago),
410424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      callback);
411424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
412424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void FullStreamUIPolicy::RemoveActions(const std::vector<int64>& action_ids) {
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScheduleAndForget(this, &FullStreamUIPolicy::DoRemoveActions, action_ids);
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
417424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void FullStreamUIPolicy::RemoveURLs(const std::vector<GURL>& restrict_urls) {
418424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  ScheduleAndForget(this, &FullStreamUIPolicy::DoRemoveURLs, restrict_urls);
419424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
420424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
421d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void FullStreamUIPolicy::RemoveExtensionData(const std::string& extension_id) {
422d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ScheduleAndForget(
423d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      this, &FullStreamUIPolicy::DoRemoveExtensionData, extension_id);
424d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
425d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void FullStreamUIPolicy::DeleteDatabase() {
42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ScheduleAndForget(this, &FullStreamUIPolicy::DoDeleteDatabase);
42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_refptr<Action> FullStreamUIPolicy::ProcessArguments(
431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    scoped_refptr<Action> action) const {
432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return action;
4337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
435558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid FullStreamUIPolicy::ProcessAction(scoped_refptr<Action> action) {
436558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // TODO(mvrable): Right now this argument stripping updates the Action object
437558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // in place, which isn't good if there are other users of the object.  When
438558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // database writing is moved to policy class, the modifications should be
439558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // made locally.
440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  action = ProcessArguments(action);
441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  ScheduleAndForget(this, &FullStreamUIPolicy::QueueAction, action);
442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void FullStreamUIPolicy::QueueAction(scoped_refptr<Action> action) {
445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (activity_database()->is_db_valid()) {
446a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    queued_actions_.push_back(action);
447ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    activity_database()->AdviseFlush(queued_actions_.size());
448a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace extensions
452