| 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 WHERE %s ORDER BY time DESC", | 164 "arg_url,other FROM %s WHERE %s ORDER BY time DESC", |
| 162 kTableName, | 165 kTableName, |
| 163 where_str.c_str()); | 166 where_str.c_str()); |
| 164 sql::Statement query(db->GetUniqueStatement(query_str.c_str())); | 167 sql::Statement query(db->GetUniqueStatement(query_str.c_str())); |
| 165 int i = -1; | 168 int i = -1; |
| 166 if (!extension_id.empty()) | 169 if (!extension_id.empty()) |
| 167 query.BindString(++i, extension_id); | 170 query.BindString(++i, extension_id); |
| 168 if (!api_name.empty()) | 171 if (!api_name.empty()) |
| 169 query.BindString(++i, api_name); | 172 query.BindString(++i, api_name); |
| 170 if (type != Action::ACTION_ANY) | 173 if (type != Action::ACTION_ANY) |
| 171 query.BindInt(++i, static_cast<int>(type)); | 174 query.BindInt(++i, static_cast<int>(type)); |
| 172 if (!page_url.empty()) | 175 if (!page_url.empty()) |
| 173 query.BindString(++i, page_url + "%"); | 176 query.BindString(++i, page_url + "%"); |
| 174 if (!arg_url.empty()) | 177 if (!arg_url.empty()) |
| 175 query.BindString(++i, arg_url + "%"); | 178 query.BindString(++i, arg_url + "%"); |
| 179 if (days_ago >= 0) { |
| 180 int64 early_bound; |
| 181 int64 late_bound; |
| 182 Util::ComputeDatabaseTimeBounds(Now(), days_ago, &early_bound, &late_bound); |
| 183 query.BindInt64(++i, early_bound); |
| 184 query.BindInt64(++i, late_bound); |
| 185 } |
| 176 | 186 |
| 177 // Execute the query and get results. | 187 // Execute the query and get results. |
| 178 while (query.is_valid() && query.Step()) { | 188 while (query.is_valid() && query.Step()) { |
| 179 scoped_refptr<Action> action = | 189 scoped_refptr<Action> action = |
| 180 new Action(query.ColumnString(0), | 190 new Action(query.ColumnString(0), |
| 181 base::Time::FromInternalValue(query.ColumnInt64(1)), | 191 base::Time::FromInternalValue(query.ColumnInt64(1)), |
| 182 static_cast<Action::ActionType>(query.ColumnInt(2)), | 192 static_cast<Action::ActionType>(query.ColumnInt(2)), |
| 183 query.ColumnString(3)); | 193 query.ColumnString(3)); |
| 184 | 194 |
| 185 if (query.ColumnType(4) != sql::COLUMN_TYPE_NULL) { | 195 if (query.ColumnType(4) != sql::COLUMN_TYPE_NULL) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 202 action->set_other(make_scoped_ptr( | 212 action->set_other(make_scoped_ptr( |
| 203 static_cast<DictionaryValue*>(parsed_value.release()))); | 213 static_cast<DictionaryValue*>(parsed_value.release()))); |
| 204 } | 214 } |
| 205 } | 215 } |
| 206 actions->push_back(action); | 216 actions->push_back(action); |
| 207 } | 217 } |
| 208 | 218 |
| 209 return actions.Pass(); | 219 return actions.Pass(); |
| 210 } | 220 } |
| 211 | 221 |
| 212 scoped_ptr<Action::ActionVector> FullStreamUIPolicy::DoReadData( | |
| 213 const std::string& extension_id, | |
| 214 const int days_ago) { | |
| 215 // Ensure data is flushed to the database first so that we query over all | |
| 216 // data. | |
| 217 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately); | |
| 218 | |
| 219 DCHECK_GE(days_ago, 0); | |
| 220 scoped_ptr<Action::ActionVector> actions(new Action::ActionVector()); | |
| 221 | |
| 222 sql::Connection* db = GetDatabaseConnection(); | |
| 223 if (!db) { | |
| 224 return actions.Pass(); | |
| 225 } | |
| 226 | |
| 227 int64 early_bound; | |
| 228 int64 late_bound; | |
| 229 Util::ComputeDatabaseTimeBounds(Now(), days_ago, &early_bound, &late_bound); | |
| 230 std::string query_str = base::StringPrintf( | |
| 231 "SELECT time, action_type, api_name, args, page_url, page_title, " | |
| 232 "arg_url, other " | |
| 233 "FROM %s WHERE extension_id=? AND time>? AND time<=? " | |
| 234 "ORDER BY time DESC", | |
| 235 kTableName); | |
| 236 sql::Statement query(db->GetCachedStatement(SQL_FROM_HERE, | |
| 237 query_str.c_str())); | |
| 238 query.BindString(0, extension_id); | |
| 239 query.BindInt64(1, early_bound); | |
| 240 query.BindInt64(2, late_bound); | |
| 241 while (query.is_valid() && query.Step()) { | |
| 242 scoped_refptr<Action> action = | |
| 243 new Action(extension_id, | |
| 244 base::Time::FromInternalValue(query.ColumnInt64(0)), | |
| 245 static_cast<Action::ActionType>(query.ColumnInt(1)), | |
| 246 query.ColumnString(2)); | |
| 247 | |
| 248 if (query.ColumnType(3) != sql::COLUMN_TYPE_NULL) { | |
| 249 scoped_ptr<Value> parsed_value( | |
| 250 base::JSONReader::Read(query.ColumnString(3))); | |
| 251 if (parsed_value && parsed_value->IsType(Value::TYPE_LIST)) { | |
| 252 action->set_args( | |
| 253 make_scoped_ptr(static_cast<ListValue*>(parsed_value.release()))); | |
| 254 } else { | |
| 255 LOG(WARNING) << "Unable to parse args: '" << query.ColumnString(3) | |
| 256 << "'"; | |
| 257 } | |
| 258 } | |
| 259 | |
| 260 action->ParsePageUrl(query.ColumnString(4)); | |
| 261 action->set_page_title(query.ColumnString(5)); | |
| 262 action->ParseArgUrl(query.ColumnString(6)); | |
| 263 | |
| 264 if (query.ColumnType(7) != sql::COLUMN_TYPE_NULL) { | |
| 265 scoped_ptr<Value> parsed_value( | |
| 266 base::JSONReader::Read(query.ColumnString(7))); | |
| 267 if (parsed_value && parsed_value->IsType(Value::TYPE_DICTIONARY)) { | |
| 268 action->set_other(make_scoped_ptr( | |
| 269 static_cast<DictionaryValue*>(parsed_value.release()))); | |
| 270 } else { | |
| 271 LOG(WARNING) << "Unable to parse other: '" << query.ColumnString(7) | |
| 272 << "'"; | |
| 273 } | |
| 274 } | |
| 275 | |
| 276 actions->push_back(action); | |
| 277 } | |
| 278 return actions.Pass(); | |
| 279 } | |
| 280 | |
| 281 void FullStreamUIPolicy::DoRemoveURLs(const std::vector<GURL>& restrict_urls) { | 222 void FullStreamUIPolicy::DoRemoveURLs(const std::vector<GURL>& restrict_urls) { |
| 282 sql::Connection* db = GetDatabaseConnection(); | 223 sql::Connection* db = GetDatabaseConnection(); |
| 283 if (!db) { | 224 if (!db) { |
| 284 LOG(ERROR) << "Unable to connect to database"; | 225 LOG(ERROR) << "Unable to connect to database"; |
| 285 return; | 226 return; |
| 286 } | 227 } |
| 287 | 228 |
| 288 // Make sure any queued in memory are sent to the database before cleaning. | 229 // Make sure any queued in memory are sent to the database before cleaning. |
| 289 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately); | 230 activity_database()->AdviseFlush(ActivityDatabase::kFlushImmediately); |
| 290 | 231 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 void FullStreamUIPolicy::OnDatabaseClose() { | 288 void FullStreamUIPolicy::OnDatabaseClose() { |
| 348 delete this; | 289 delete this; |
| 349 } | 290 } |
| 350 | 291 |
| 351 void FullStreamUIPolicy::Close() { | 292 void FullStreamUIPolicy::Close() { |
| 352 // The policy object should have never been created if there's no DB thread. | 293 // The policy object should have never been created if there's no DB thread. |
| 353 DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::DB)); | 294 DCHECK(BrowserThread::IsMessageLoopValid(BrowserThread::DB)); |
| 354 ScheduleAndForget(activity_database(), &ActivityDatabase::Close); | 295 ScheduleAndForget(activity_database(), &ActivityDatabase::Close); |
| 355 } | 296 } |
| 356 | 297 |
| 357 // Get data as a set of key-value pairs. The keys are policy-specific. | |
| 358 void FullStreamUIPolicy::ReadData( | |
| 359 const std::string& extension_id, | |
| 360 const int day, | |
| 361 const Callback<void(scoped_ptr<Action::ActionVector>)>& callback) { | |
| 362 BrowserThread::PostTaskAndReplyWithResult( | |
| 363 BrowserThread::DB, | |
| 364 FROM_HERE, | |
| 365 base::Bind(&FullStreamUIPolicy::DoReadData, | |
| 366 base::Unretained(this), | |
| 367 extension_id, | |
| 368 day), | |
| 369 callback); | |
| 370 } | |
| 371 | |
| 372 void FullStreamUIPolicy::ReadFilteredData( | 298 void FullStreamUIPolicy::ReadFilteredData( |
| 373 const std::string& extension_id, | 299 const std::string& extension_id, |
| 374 const Action::ActionType type, | 300 const Action::ActionType type, |
| 375 const std::string& api_name, | 301 const std::string& api_name, |
| 376 const std::string& page_url, | 302 const std::string& page_url, |
| 377 const std::string& arg_url, | 303 const std::string& arg_url, |
| 304 const int days_ago, |
| 378 const base::Callback | 305 const base::Callback |
| 379 <void(scoped_ptr<Action::ActionVector>)>& callback) { | 306 <void(scoped_ptr<Action::ActionVector>)>& callback) { |
| 380 BrowserThread::PostTaskAndReplyWithResult( | 307 BrowserThread::PostTaskAndReplyWithResult( |
| 381 BrowserThread::DB, | 308 BrowserThread::DB, |
| 382 FROM_HERE, | 309 FROM_HERE, |
| 383 base::Bind(&FullStreamUIPolicy::DoReadFilteredData, | 310 base::Bind(&FullStreamUIPolicy::DoReadFilteredData, |
| 384 base::Unretained(this), | 311 base::Unretained(this), |
| 385 extension_id, | 312 extension_id, |
| 386 type, | 313 type, |
| 387 api_name, | 314 api_name, |
| 388 page_url, | 315 page_url, |
| 389 arg_url), | 316 arg_url, |
| 317 days_ago), |
| 390 callback); | 318 callback); |
| 391 } | 319 } |
| 392 | 320 |
| 393 void FullStreamUIPolicy::RemoveURLs(const std::vector<GURL>& restrict_urls) { | 321 void FullStreamUIPolicy::RemoveURLs(const std::vector<GURL>& restrict_urls) { |
| 394 ScheduleAndForget(this, &FullStreamUIPolicy::DoRemoveURLs, restrict_urls); | 322 ScheduleAndForget(this, &FullStreamUIPolicy::DoRemoveURLs, restrict_urls); |
| 395 } | 323 } |
| 396 | 324 |
| 397 scoped_refptr<Action> FullStreamUIPolicy::ProcessArguments( | 325 scoped_refptr<Action> FullStreamUIPolicy::ProcessArguments( |
| 398 scoped_refptr<Action> action) const { | 326 scoped_refptr<Action> action) const { |
| 399 return action; | 327 return action; |
| 400 } | 328 } |
| 401 | 329 |
| 402 void FullStreamUIPolicy::ProcessAction(scoped_refptr<Action> action) { | 330 void FullStreamUIPolicy::ProcessAction(scoped_refptr<Action> action) { |
| 403 // TODO(mvrable): Right now this argument stripping updates the Action object | 331 // TODO(mvrable): Right now this argument stripping updates the Action object |
| 404 // in place, which isn't good if there are other users of the object. When | 332 // in place, which isn't good if there are other users of the object. When |
| 405 // database writing is moved to policy class, the modifications should be | 333 // database writing is moved to policy class, the modifications should be |
| 406 // made locally. | 334 // made locally. |
| 407 action = ProcessArguments(action); | 335 action = ProcessArguments(action); |
| 408 ScheduleAndForget(this, &FullStreamUIPolicy::QueueAction, action); | 336 ScheduleAndForget(this, &FullStreamUIPolicy::QueueAction, action); |
| 409 } | 337 } |
| 410 | 338 |
| 411 void FullStreamUIPolicy::QueueAction(scoped_refptr<Action> action) { | 339 void FullStreamUIPolicy::QueueAction(scoped_refptr<Action> action) { |
| 412 if (activity_database()->is_db_valid()) { | 340 if (activity_database()->is_db_valid()) { |
| 413 queued_actions_.push_back(action); | 341 queued_actions_.push_back(action); |
| 414 activity_database()->AdviseFlush(queued_actions_.size()); | 342 activity_database()->AdviseFlush(queued_actions_.size()); |
| 415 } | 343 } |
| 416 } | 344 } |
| 417 | 345 |
| 418 } // namespace extensions | 346 } // namespace extensions |
| OLD | NEW |