| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h" | 5 #include "chrome/browser/extensions/activity_log/fullstream_ui_policy.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 | 116 |
| 117 queued_actions_.clear(); | 117 queued_actions_.clear(); |
| 118 return true; | 118 return true; |
| 119 } | 119 } |
| 120 | 120 |
| 121 scoped_ptr<Action::ActionVector> FullStreamUIPolicy::DoReadFilteredData( | 121 scoped_ptr<Action::ActionVector> FullStreamUIPolicy::DoReadFilteredData( |
| 122 const std::string& extension_id, | 122 const std::string& extension_id, |
| 123 const Action::ActionType type, | 123 const Action::ActionType type, |
| 124 const std::string& api_name, | 124 const std::string& api_name, |
| 125 const std::string& page_url, | 125 const std::string& page_url, |
| 126 const std::string& arg_url) { | 126 const std::string& arg_url, |
| 127 const int days_ago) { |
| 127 // Ensure data is flushed to the database first so that we query over all | 128 // Ensure data is flushed to the database first so that we query over all |
| 128 // data. | 129 // data. |
| 129 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately); | 130 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately); |
| 130 scoped_ptr<Action::ActionVector> actions(new Action::ActionVector()); | 131 scoped_ptr<Action::ActionVector> actions(new Action::ActionVector()); |
| 131 | 132 |
| 132 sql::Connection* db = GetDatabaseConnection(); | 133 sql::Connection* db = GetDatabaseConnection(); |
| 133 if (!db) { | 134 if (!db) { |
| 134 return actions.Pass(); | 135 return actions.Pass(); |
| 135 } | 136 } |
| 136 | 137 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 149 where_str += where_next + "action_type=?"; | 150 where_str += where_next + "action_type=?"; |
| 150 where_next = " AND "; | 151 where_next = " AND "; |
| 151 } | 152 } |
| 152 if (!page_url.empty()) { | 153 if (!page_url.empty()) { |
| 153 where_str += where_next + "page_url LIKE ?"; | 154 where_str += where_next + "page_url LIKE ?"; |
| 154 where_next = " AND "; | 155 where_next = " AND "; |
| 155 } | 156 } |
| 156 if (!arg_url.empty()) { | 157 if (!arg_url.empty()) { |
| 157 where_str += where_next + "arg_url LIKE ?"; | 158 where_str += where_next + "arg_url LIKE ?"; |
| 158 } | 159 } |
| 160 if (days_ago >= 0) |
| 161 where_str += where_next + "time BETWEEN ? AND ?"; |
| 159 std::string query_str = base::StringPrintf( | 162 std::string query_str = base::StringPrintf( |
| 160 "SELECT extension_id,time,action_type,api_name,args,page_url,page_title," | 163 "SELECT extension_id,time,action_type,api_name,args,page_url,page_title," |
| 161 "arg_url,other FROM %s %s %s ORDER BY time DESC LIMIT 300", | 164 "arg_url,other FROM %s %s %s ORDER BY time DESC LIMIT 300", |
| 162 kTableName, | 165 kTableName, |
| 163 where_str.empty() ? "" : "WHERE", | 166 where_str.empty() ? "" : "WHERE", |
| 164 where_str.c_str()); | 167 where_str.c_str()); |
| 165 sql::Statement query(db->GetUniqueStatement(query_str.c_str())); | 168 sql::Statement query(db->GetUniqueStatement(query_str.c_str())); |
| 166 int i = -1; | 169 int i = -1; |
| 167 if (!extension_id.empty()) | 170 if (!extension_id.empty()) |
| 168 query.BindString(++i, extension_id); | 171 query.BindString(++i, extension_id); |
| 169 if (!api_name.empty()) | 172 if (!api_name.empty()) |
| 170 query.BindString(++i, api_name); | 173 query.BindString(++i, api_name); |
| 171 if (type != Action::ACTION_ANY) | 174 if (type != Action::ACTION_ANY) |
| 172 query.BindInt(++i, static_cast<int>(type)); | 175 query.BindInt(++i, static_cast<int>(type)); |
| 173 if (!page_url.empty()) | 176 if (!page_url.empty()) |
| 174 query.BindString(++i, page_url + "%"); | 177 query.BindString(++i, page_url + "%"); |
| 175 if (!arg_url.empty()) | 178 if (!arg_url.empty()) |
| 176 query.BindString(++i, arg_url + "%"); | 179 query.BindString(++i, arg_url + "%"); |
| 180 if (days_ago >= 0) { |
| 181 int64 early_bound; |
| 182 int64 late_bound; |
| 183 Util::ComputeDatabaseTimeBounds(Now(), days_ago, &early_bound, &late_bound); |
| 184 query.BindInt64(++i, early_bound); |
| 185 query.BindInt64(++i, late_bound); |
| 186 } |
| 177 | 187 |
| 178 // Execute the query and get results. | 188 // Execute the query and get results. |
| 179 while (query.is_valid() && query.Step()) { | 189 while (query.is_valid() && query.Step()) { |
| 180 scoped_refptr<Action> action = | 190 scoped_refptr<Action> action = |
| 181 new Action(query.ColumnString(0), | 191 new Action(query.ColumnString(0), |
| 182 base::Time::FromInternalValue(query.ColumnInt64(1)), | 192 base::Time::FromInternalValue(query.ColumnInt64(1)), |
| 183 static_cast<Action::ActionType>(query.ColumnInt(2)), | 193 static_cast<Action::ActionType>(query.ColumnInt(2)), |
| 184 query.ColumnString(3)); | 194 query.ColumnString(3)); |
| 185 | 195 |
| 186 if (query.ColumnType(4) != sql::COLUMN_TYPE_NULL) { | 196 if (query.ColumnType(4) != sql::COLUMN_TYPE_NULL) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 203 action->set_other(make_scoped_ptr( | 213 action->set_other(make_scoped_ptr( |
| 204 static_cast<DictionaryValue*>(parsed_value.release()))); | 214 static_cast<DictionaryValue*>(parsed_value.release()))); |
| 205 } | 215 } |
| 206 } | 216 } |
| 207 actions->push_back(action); | 217 actions->push_back(action); |
| 208 } | 218 } |
| 209 | 219 |
| 210 return actions.Pass(); | 220 return actions.Pass(); |
| 211 } | 221 } |
| 212 | 222 |
| 213 scoped_ptr<Action::ActionVector> FullStreamUIPolicy::DoReadData( | |
| 214 const std::string& extension_id, | |
| 215 const int days_ago) { | |
| 216 // Ensure data is flushed to the database first so that we query over all | |
| 217 // data. | |
| 218 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately); | |
| 219 | |
| 220 DCHECK_GE(days_ago, 0); | |
| 221 scoped_ptr<Action::ActionVector> actions(new Action::ActionVector()); | |
| 222 | |
| 223 sql::Connection* db = GetDatabaseConnection(); | |
| 224 if (!db) { | |
| 225 return actions.Pass(); | |
| 226 } | |
| 227 | |
| 228 int64 early_bound; | |
| 229 int64 late_bound; | |
| 230 Util::ComputeDatabaseTimeBounds(Now(), days_ago, &early_bound, &late_bound); | |
| 231 std::string query_str = base::StringPrintf( | |
| 232 "SELECT time, action_type, api_name, args, page_url, page_title, " | |
| 233 "arg_url, other " | |
| 234 "FROM %s WHERE extension_id=? AND time>? AND time<=? " | |
| 235 "ORDER BY time DESC", | |
| 236 kTableName); | |
| 237 sql::Statement query(db->GetCachedStatement(SQL_FROM_HERE, | |
| 238 query_str.c_str())); | |
| 239 query.BindString(0, extension_id); | |
| 240 query.BindInt64(1, early_bound); | |
| 241 query.BindInt64(2, late_bound); | |
| 242 while (query.is_valid() && query.Step()) { | |
| 243 scoped_refptr<Action> action = | |
| 244 new Action(extension_id, | |
| 245 base::Time::FromInternalValue(query.ColumnInt64(0)), | |
| 246 static_cast<Action::ActionType>(query.ColumnInt(1)), | |
| 247 query.ColumnString(2)); | |
| 248 | |
| 249 if (query.ColumnType(3) != sql::COLUMN_TYPE_NULL) { | |
| 250 scoped_ptr<Value> parsed_value( | |
| 251 base::JSONReader::Read(query.ColumnString(3))); | |
| 252 if (parsed_value && parsed_value->IsType(Value::TYPE_LIST)) { | |
| 253 action->set_args( | |
| 254 make_scoped_ptr(static_cast<ListValue*>(parsed_value.release()))); | |
| 255 } else { | |
| 256 LOG(WARNING) << "Unable to parse args: '" << query.ColumnString(3) | |
| 257 << "'"; | |
| 258 } | |
| 259 } | |
| 260 | |
| 261 action->ParsePageUrl(query.ColumnString(4)); | |
| 262 action->set_page_title(query.ColumnString(5)); | |
| 263 action->ParseArgUrl(query.ColumnString(6)); | |
| 264 | |
| 265 if (query.ColumnType(7) != sql::COLUMN_TYPE_NULL) { | |
| 266 scoped_ptr<Value> parsed_value( | |
| 267 base::JSONReader::Read(query.ColumnString(7))); | |
| 268 if (parsed_value && parsed_value->IsType(Value::TYPE_DICTIONARY)) { | |
| 269 action->set_other(make_scoped_ptr( | |
| 270 static_cast<DictionaryValue*>(parsed_value.release()))); | |
| 271 } else { | |
| 272 LOG(WARNING) << "Unable to parse other: '" << query.ColumnString(7) | |
| 273 << "'"; | |
| 274 } | |
| 275 } | |
| 276 | |
| 277 actions->push_back(action); | |
| 278 } | |
| 279 return actions.Pass(); | |
| 280 } | |
| 281 | |
| 282 void FullStreamUIPolicy::DoRemoveURLs(const std::vector<GURL>& restrict_urls) { | 223 void FullStreamUIPolicy::DoRemoveURLs(const std::vector<GURL>& restrict_urls) { |
| 283 sql::Connection* db = GetDatabaseConnection(); | 224 sql::Connection* db = GetDatabaseConnection(); |
| 284 if (!db) { | 225 if (!db) { |
| 285 LOG(ERROR) << "Unable to connect to database"; | 226 LOG(ERROR) << "Unable to connect to database"; |
| 286 return; | 227 return; |
| 287 } | 228 } |
| 288 | 229 |
| 289 // Make sure any queued in memory are sent to the database before cleaning. | 230 // Make sure any queued in memory are sent to the database before cleaning. |
| 290 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately); | 231 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately); |
| 291 | 232 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 void FullStreamUIPolicy::OnDatabaseClose() { | 317 void FullStreamUIPolicy::OnDatabaseClose() { |
| 377 delete this; | 318 delete this; |
| 378 } | 319 } |
| 379 | 320 |
| 380 void FullStreamUIPolicy::Close() { | 321 void FullStreamUIPolicy::Close() { |
| 381 // The policy object should have never been created if there's no DB thread. | 322 // The policy object should have never been created if there's no DB thread. |
| 382 DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::DB)); | 323 DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::DB)); |
| 383 ScheduleAndForget(activity_database(), &ActivityDatabase::Close); | 324 ScheduleAndForget(activity_database(), &ActivityDatabase::Close); |
| 384 } | 325 } |
| 385 | 326 |
| 386 // Get data as a set of key-value pairs. The keys are policy-specific. | |
| 387 void FullStreamUIPolicy::ReadData( | |
| 388 const std::string& extension_id, | |
| 389 const int day, | |
| 390 const Callback<void(scoped_ptr<Action::ActionVector>)>& callback) { | |
| 391 BrowserThread::PostTaskAndReplyWithResult( | |
| 392 BrowserThread::DB, | |
| 393 FROM_HERE, | |
| 394 base::Bind(&FullStreamUIPolicy::DoReadData, | |
| 395 base::Unretained(this), | |
| 396 extension_id, | |
| 397 day), | |
| 398 callback); | |
| 399 } | |
| 400 | |
| 401 void FullStreamUIPolicy::ReadFilteredData( | 327 void FullStreamUIPolicy::ReadFilteredData( |
| 402 const std::string& extension_id, | 328 const std::string& extension_id, |
| 403 const Action::ActionType type, | 329 const Action::ActionType type, |
| 404 const std::string& api_name, | 330 const std::string& api_name, |
| 405 const std::string& page_url, | 331 const std::string& page_url, |
| 406 const std::string& arg_url, | 332 const std::string& arg_url, |
| 333 const int days_ago, |
| 407 const base::Callback | 334 const base::Callback |
| 408 <void(scoped_ptr<Action::ActionVector>)>& callback) { | 335 <void(scoped_ptr<Action::ActionVector>)>& callback) { |
| 409 BrowserThread::PostTaskAndReplyWithResult( | 336 BrowserThread::PostTaskAndReplyWithResult( |
| 410 BrowserThread::DB, | 337 BrowserThread::DB, |
| 411 FROM_HERE, | 338 FROM_HERE, |
| 412 base::Bind(&FullStreamUIPolicy::DoReadFilteredData, | 339 base::Bind(&FullStreamUIPolicy::DoReadFilteredData, |
| 413 base::Unretained(this), | 340 base::Unretained(this), |
| 414 extension_id, | 341 extension_id, |
| 415 type, | 342 type, |
| 416 api_name, | 343 api_name, |
| 417 page_url, | 344 page_url, |
| 418 arg_url), | 345 arg_url, |
| 346 days_ago), |
| 419 callback); | 347 callback); |
| 420 } | 348 } |
| 421 | 349 |
| 422 void FullStreamUIPolicy::RemoveURLs(const std::vector<GURL>& restrict_urls) { | 350 void FullStreamUIPolicy::RemoveURLs(const std::vector<GURL>& restrict_urls) { |
| 423 ScheduleAndForget(this, &FullStreamUIPolicy::DoRemoveURLs, restrict_urls); | 351 ScheduleAndForget(this, &FullStreamUIPolicy::DoRemoveURLs, restrict_urls); |
| 424 } | 352 } |
| 425 | 353 |
| 426 void FullStreamUIPolicy::DeleteDatabase() { | 354 void FullStreamUIPolicy::DeleteDatabase() { |
| 427 ScheduleAndForget(this, &FullStreamUIPolicy::DoDeleteDatabase); | 355 ScheduleAndForget(this, &FullStreamUIPolicy::DoDeleteDatabase); |
| 428 } | 356 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 442 } | 370 } |
| 443 | 371 |
| 444 void FullStreamUIPolicy::QueueAction(scoped_refptr<Action> action) { | 372 void FullStreamUIPolicy::QueueAction(scoped_refptr<Action> action) { |
| 445 if (activity_database()->is_db_valid()) { | 373 if (activity_database()->is_db_valid()) { |
| 446 queued_actions_.push_back(action); | 374 queued_actions_.push_back(action); |
| 447 activity_database()->AdviseFlush(queued_actions_.size()); | 375 activity_database()->AdviseFlush(queued_actions_.size()); |
| 448 } | 376 } |
| 449 } | 377 } |
| 450 | 378 |
| 451 } // namespace extensions | 379 } // namespace extensions |
| OLD | NEW |