| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "components/history/core/browser/history_backend.h" | 5 #include "components/history/core/browser/history_backend.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <functional> | 8 #include <functional> |
| 9 #include <list> | 9 #include <list> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 scoped_refptr<base::SequencedTaskRunner> task_runner) | 210 scoped_refptr<base::SequencedTaskRunner> task_runner) |
| 211 : delegate_(delegate), | 211 : delegate_(delegate), |
| 212 scheduled_kill_db_(false), | 212 scheduled_kill_db_(false), |
| 213 expirer_(this, backend_client.get(), task_runner), | 213 expirer_(this, backend_client.get(), task_runner), |
| 214 recent_redirects_(kMaxRedirectCount), | 214 recent_redirects_(kMaxRedirectCount), |
| 215 segment_queried_(false), | 215 segment_queried_(false), |
| 216 backend_client_(std::move(backend_client)), | 216 backend_client_(std::move(backend_client)), |
| 217 task_runner_(task_runner) {} | 217 task_runner_(task_runner) {} |
| 218 | 218 |
| 219 HistoryBackend::~HistoryBackend() { | 219 HistoryBackend::~HistoryBackend() { |
| 220 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 221 DCHECK(!scheduled_commit_) << "Deleting without cleanup"; | 220 DCHECK(!scheduled_commit_) << "Deleting without cleanup"; |
| 222 queued_history_db_tasks_.clear(); | 221 queued_history_db_tasks_.clear(); |
| 223 | 222 |
| 224 // Release stashed embedder object before cleaning up the databases. | 223 // Release stashed embedder object before cleaning up the databases. |
| 225 supports_user_data_helper_.reset(); | 224 supports_user_data_helper_.reset(); |
| 226 | 225 |
| 227 // First close the databases before optionally running the "destroy" task. | 226 // First close the databases before optionally running the "destroy" task. |
| 228 CloseAllDatabases(); | 227 CloseAllDatabases(); |
| 229 | 228 |
| 230 if (!backend_destroy_task_.is_null()) { | 229 if (!backend_destroy_task_.is_null()) { |
| 231 // Notify an interested party (typically a unit test) that we're done. | 230 // Notify an interested party (typically a unit test) that we're done. |
| 232 DCHECK(backend_destroy_task_runner_); | 231 DCHECK(backend_destroy_task_runner_); |
| 233 backend_destroy_task_runner_->PostTask(FROM_HERE, backend_destroy_task_); | 232 backend_destroy_task_runner_->PostTask(FROM_HERE, backend_destroy_task_); |
| 234 } | 233 } |
| 235 | 234 |
| 236 #if defined(OS_ANDROID) | 235 #if defined(OS_ANDROID) |
| 237 if (backend_client_ && !history_dir_.empty()) | 236 if (backend_client_ && !history_dir_.empty()) |
| 238 backend_client_->OnHistoryBackendDestroyed(this, history_dir_); | 237 backend_client_->OnHistoryBackendDestroyed(this, history_dir_); |
| 239 #endif | 238 #endif |
| 240 } | 239 } |
| 241 | 240 |
| 242 void HistoryBackend::Init( | 241 void HistoryBackend::Init( |
| 243 bool force_fail, | 242 bool force_fail, |
| 244 const HistoryDatabaseParams& history_database_params) { | 243 const HistoryDatabaseParams& history_database_params) { |
| 245 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 246 | |
| 247 // HistoryBackend is created on the UI thread by HistoryService, then the | 244 // HistoryBackend is created on the UI thread by HistoryService, then the |
| 248 // HistoryBackend::Init() method is called on the DB thread. Create the | 245 // HistoryBackend::Init() method is called on the DB thread. Create the |
| 249 // base::SupportsUserData on the DB thread since it is not thread-safe. | 246 // base::SupportsUserData on the DB thread since it is not thread-safe. |
| 250 supports_user_data_helper_.reset(new HistoryBackendHelper); | 247 supports_user_data_helper_.reset(new HistoryBackendHelper); |
| 251 | 248 |
| 252 if (!force_fail) | 249 if (!force_fail) |
| 253 InitImpl(history_database_params); | 250 InitImpl(history_database_params); |
| 254 delegate_->DBLoaded(); | 251 delegate_->DBLoaded(); |
| 255 typed_url_syncable_service_.reset(new TypedUrlSyncableService(this)); | 252 typed_url_syncable_service_.reset(new TypedUrlSyncableService(this)); |
| 256 memory_pressure_listener_.reset(new base::MemoryPressureListener( | 253 memory_pressure_listener_.reset(new base::MemoryPressureListener( |
| 257 base::Bind(&HistoryBackend::OnMemoryPressure, base::Unretained(this)))); | 254 base::Bind(&HistoryBackend::OnMemoryPressure, base::Unretained(this)))); |
| 258 } | 255 } |
| 259 | 256 |
| 260 void HistoryBackend::SetOnBackendDestroyTask( | 257 void HistoryBackend::SetOnBackendDestroyTask( |
| 261 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | 258 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| 262 const base::Closure& task) { | 259 const base::Closure& task) { |
| 263 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 264 | |
| 265 if (!backend_destroy_task_.is_null()) | 260 if (!backend_destroy_task_.is_null()) |
| 266 DLOG(WARNING) << "Setting more than one destroy task, overriding"; | 261 DLOG(WARNING) << "Setting more than one destroy task, overriding"; |
| 267 backend_destroy_task_runner_ = std::move(task_runner); | 262 backend_destroy_task_runner_ = std::move(task_runner); |
| 268 backend_destroy_task_ = task; | 263 backend_destroy_task_ = task; |
| 269 } | 264 } |
| 270 | 265 |
| 271 void HistoryBackend::Closing() { | 266 void HistoryBackend::Closing() { |
| 272 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 273 | |
| 274 // Any scheduled commit will have a reference to us, we must make it | 267 // Any scheduled commit will have a reference to us, we must make it |
| 275 // release that reference before we can be destroyed. | 268 // release that reference before we can be destroyed. |
| 276 CancelScheduledCommit(); | 269 CancelScheduledCommit(); |
| 277 | 270 |
| 278 // Release our reference to the delegate, this reference will be keeping the | 271 // Release our reference to the delegate, this reference will be keeping the |
| 279 // history service alive. | 272 // history service alive. |
| 280 delegate_.reset(); | 273 delegate_.reset(); |
| 281 } | 274 } |
| 282 | 275 |
| 283 #if defined(OS_IOS) | 276 #if defined(OS_IOS) |
| 284 void HistoryBackend::PersistState() { | 277 void HistoryBackend::PersistState() { |
| 285 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 286 Commit(); | 278 Commit(); |
| 287 } | 279 } |
| 288 #endif | 280 #endif |
| 289 | 281 |
| 290 void HistoryBackend::ClearCachedDataForContextID(ContextID context_id) { | 282 void HistoryBackend::ClearCachedDataForContextID(ContextID context_id) { |
| 291 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 292 tracker_.ClearCachedDataForContextID(context_id); | 283 tracker_.ClearCachedDataForContextID(context_id); |
| 293 } | 284 } |
| 294 | 285 |
| 295 base::FilePath HistoryBackend::GetFaviconsFileName() const { | 286 base::FilePath HistoryBackend::GetFaviconsFileName() const { |
| 296 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 297 return history_dir_.Append(kFaviconsFilename); | 287 return history_dir_.Append(kFaviconsFilename); |
| 298 } | 288 } |
| 299 | 289 |
| 300 SegmentID HistoryBackend::GetLastSegmentID(VisitID from_visit) { | 290 SegmentID HistoryBackend::GetLastSegmentID(VisitID from_visit) { |
| 301 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 302 | |
| 303 // Set is used to detect referrer loops. Should not happen, but can | 291 // Set is used to detect referrer loops. Should not happen, but can |
| 304 // if the database is corrupt. | 292 // if the database is corrupt. |
| 305 std::set<VisitID> visit_set; | 293 std::set<VisitID> visit_set; |
| 306 VisitID visit_id = from_visit; | 294 VisitID visit_id = from_visit; |
| 307 while (visit_id) { | 295 while (visit_id) { |
| 308 VisitRow row; | 296 VisitRow row; |
| 309 if (!db_->GetRowForVisit(visit_id, &row)) | 297 if (!db_->GetRowForVisit(visit_id, &row)) |
| 310 return 0; | 298 return 0; |
| 311 if (row.segment_id) | 299 if (row.segment_id) |
| 312 return row.segment_id; // Found a visit in this change with a segment. | 300 return row.segment_id; // Found a visit in this change with a segment. |
| 313 | 301 |
| 314 // Check the referrer of this visit, if any. | 302 // Check the referrer of this visit, if any. |
| 315 visit_id = row.referring_visit; | 303 visit_id = row.referring_visit; |
| 316 | 304 |
| 317 if (visit_set.find(visit_id) != visit_set.end()) { | 305 if (visit_set.find(visit_id) != visit_set.end()) { |
| 318 NOTREACHED() << "Loop in referer chain, giving up"; | 306 NOTREACHED() << "Loop in referer chain, giving up"; |
| 319 break; | 307 break; |
| 320 } | 308 } |
| 321 visit_set.insert(visit_id); | 309 visit_set.insert(visit_id); |
| 322 } | 310 } |
| 323 return 0; | 311 return 0; |
| 324 } | 312 } |
| 325 | 313 |
| 326 SegmentID HistoryBackend::UpdateSegments(const GURL& url, | 314 SegmentID HistoryBackend::UpdateSegments(const GURL& url, |
| 327 VisitID from_visit, | 315 VisitID from_visit, |
| 328 VisitID visit_id, | 316 VisitID visit_id, |
| 329 ui::PageTransition transition_type, | 317 ui::PageTransition transition_type, |
| 330 const Time ts) { | 318 const Time ts) { |
| 331 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 332 | |
| 333 if (!db_) | 319 if (!db_) |
| 334 return 0; | 320 return 0; |
| 335 | 321 |
| 336 // We only consider main frames. | 322 // We only consider main frames. |
| 337 if (!ui::PageTransitionIsMainFrame(transition_type)) | 323 if (!ui::PageTransitionIsMainFrame(transition_type)) |
| 338 return 0; | 324 return 0; |
| 339 | 325 |
| 340 SegmentID segment_id = 0; | 326 SegmentID segment_id = 0; |
| 341 | 327 |
| 342 // Are we at the beginning of a new segment? | 328 // Are we at the beginning of a new segment? |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 NOTREACHED(); | 383 NOTREACHED(); |
| 398 return 0; | 384 return 0; |
| 399 } | 385 } |
| 400 return segment_id; | 386 return segment_id; |
| 401 } | 387 } |
| 402 | 388 |
| 403 void HistoryBackend::UpdateWithPageEndTime(ContextID context_id, | 389 void HistoryBackend::UpdateWithPageEndTime(ContextID context_id, |
| 404 int nav_entry_id, | 390 int nav_entry_id, |
| 405 const GURL& url, | 391 const GURL& url, |
| 406 Time end_ts) { | 392 Time end_ts) { |
| 407 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 408 | |
| 409 // Will be filled with the URL ID and the visit ID of the last addition. | 393 // Will be filled with the URL ID and the visit ID of the last addition. |
| 410 VisitID visit_id = tracker_.GetLastVisit(context_id, nav_entry_id, url); | 394 VisitID visit_id = tracker_.GetLastVisit(context_id, nav_entry_id, url); |
| 411 UpdateVisitDuration(visit_id, end_ts); | 395 UpdateVisitDuration(visit_id, end_ts); |
| 412 } | 396 } |
| 413 | 397 |
| 414 void HistoryBackend::UpdateVisitDuration(VisitID visit_id, const Time end_ts) { | 398 void HistoryBackend::UpdateVisitDuration(VisitID visit_id, const Time end_ts) { |
| 415 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 416 | |
| 417 if (!db_) | 399 if (!db_) |
| 418 return; | 400 return; |
| 419 | 401 |
| 420 // Get the starting visit_time for visit_id. | 402 // Get the starting visit_time for visit_id. |
| 421 VisitRow visit_row; | 403 VisitRow visit_row; |
| 422 if (db_->GetRowForVisit(visit_id, &visit_row)) { | 404 if (db_->GetRowForVisit(visit_id, &visit_row)) { |
| 423 // We should never have a negative duration time even when time is skewed. | 405 // We should never have a negative duration time even when time is skewed. |
| 424 visit_row.visit_duration = end_ts > visit_row.visit_time | 406 visit_row.visit_duration = end_ts > visit_row.visit_time |
| 425 ? end_ts - visit_row.visit_time | 407 ? end_ts - visit_row.visit_time |
| 426 : TimeDelta::FromMicroseconds(0); | 408 : TimeDelta::FromMicroseconds(0); |
| 427 db_->UpdateVisitRow(visit_row); | 409 db_->UpdateVisitRow(visit_row); |
| 428 } | 410 } |
| 429 } | 411 } |
| 430 | 412 |
| 431 TopHostsList HistoryBackend::TopHosts(size_t num_hosts) const { | 413 TopHostsList HistoryBackend::TopHosts(size_t num_hosts) const { |
| 432 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 433 | |
| 434 if (!db_) | 414 if (!db_) |
| 435 return TopHostsList(); | 415 return TopHostsList(); |
| 436 | 416 |
| 437 auto top_hosts = db_->TopHosts(num_hosts); | 417 auto top_hosts = db_->TopHosts(num_hosts); |
| 438 | 418 |
| 439 host_ranks_.clear(); | 419 host_ranks_.clear(); |
| 440 int i = 0; | 420 int i = 0; |
| 441 for (const auto& host_count : top_hosts) | 421 for (const auto& host_count : top_hosts) |
| 442 host_ranks_[host_count.first] = i++; | 422 host_ranks_[host_count.first] = i++; |
| 443 return top_hosts; | 423 return top_hosts; |
| 444 } | 424 } |
| 445 | 425 |
| 446 OriginCountAndLastVisitMap HistoryBackend::GetCountsAndLastVisitForOrigins( | 426 OriginCountAndLastVisitMap HistoryBackend::GetCountsAndLastVisitForOrigins( |
| 447 const std::set<GURL>& origins) const { | 427 const std::set<GURL>& origins) const { |
| 448 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 449 | |
| 450 if (!db_) | 428 if (!db_) |
| 451 return OriginCountAndLastVisitMap(); | 429 return OriginCountAndLastVisitMap(); |
| 452 | 430 |
| 453 URLDatabase::URLEnumerator it; | 431 URLDatabase::URLEnumerator it; |
| 454 if (!db_->InitURLEnumeratorForEverything(&it)) | 432 if (!db_->InitURLEnumeratorForEverything(&it)) |
| 455 return OriginCountAndLastVisitMap(); | 433 return OriginCountAndLastVisitMap(); |
| 456 | 434 |
| 457 OriginCountAndLastVisitMap origin_count_map; | 435 OriginCountAndLastVisitMap origin_count_map; |
| 458 for (const GURL& origin : origins) | 436 for (const GURL& origin : origins) |
| 459 origin_count_map[origin] = std::make_pair(0, base::Time()); | 437 origin_count_map[origin] = std::make_pair(0, base::Time()); |
| 460 | 438 |
| 461 URLRow row; | 439 URLRow row; |
| 462 while (it.GetNextURL(&row)) { | 440 while (it.GetNextURL(&row)) { |
| 463 GURL origin = row.url().GetOrigin(); | 441 GURL origin = row.url().GetOrigin(); |
| 464 auto iter = origin_count_map.find(origin); | 442 auto iter = origin_count_map.find(origin); |
| 465 if (iter != origin_count_map.end()) { | 443 if (iter != origin_count_map.end()) { |
| 466 std::pair<int, base::Time>& value = iter->second; | 444 std::pair<int, base::Time>& value = iter->second; |
| 467 ++(value.first); | 445 ++(value.first); |
| 468 if (value.second.is_null() || value.second < row.last_visit()) | 446 if (value.second.is_null() || value.second < row.last_visit()) |
| 469 value.second = row.last_visit(); | 447 value.second = row.last_visit(); |
| 470 } | 448 } |
| 471 } | 449 } |
| 472 | 450 |
| 473 return origin_count_map; | 451 return origin_count_map; |
| 474 } | 452 } |
| 475 | 453 |
| 476 int HistoryBackend::HostRankIfAvailable(const GURL& url) const { | 454 int HistoryBackend::HostRankIfAvailable(const GURL& url) const { |
| 477 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 478 | |
| 479 auto it = host_ranks_.find(HostForTopHosts(url)); | 455 auto it = host_ranks_.find(HostForTopHosts(url)); |
| 480 return it != host_ranks_.end() ? it->second : kMaxTopHosts; | 456 return it != host_ranks_.end() ? it->second : kMaxTopHosts; |
| 481 } | 457 } |
| 482 | 458 |
| 483 void HistoryBackend::AddPage(const HistoryAddPageArgs& request) { | 459 void HistoryBackend::AddPage(const HistoryAddPageArgs& request) { |
| 484 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 485 | |
| 486 if (!db_) | 460 if (!db_) |
| 487 return; | 461 return; |
| 488 | 462 |
| 489 // Will be filled with the URL ID and the visit ID of the last addition. | 463 // Will be filled with the URL ID and the visit ID of the last addition. |
| 490 std::pair<URLID, VisitID> last_ids( | 464 std::pair<URLID, VisitID> last_ids( |
| 491 0, tracker_.GetLastVisit(request.context_id, request.nav_entry_id, | 465 0, tracker_.GetLastVisit(request.context_id, request.nav_entry_id, |
| 492 request.referrer)); | 466 request.referrer)); |
| 493 | 467 |
| 494 VisitID from_visit_id = last_ids.second; | 468 VisitID from_visit_id = last_ids.second; |
| 495 | 469 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 !is_keyword_generated) { | 622 !is_keyword_generated) { |
| 649 tracker_.AddVisit(request.context_id, request.nav_entry_id, request.url, | 623 tracker_.AddVisit(request.context_id, request.nav_entry_id, request.url, |
| 650 last_ids.second); | 624 last_ids.second); |
| 651 } | 625 } |
| 652 | 626 |
| 653 ScheduleCommit(); | 627 ScheduleCommit(); |
| 654 } | 628 } |
| 655 | 629 |
| 656 void HistoryBackend::InitImpl( | 630 void HistoryBackend::InitImpl( |
| 657 const HistoryDatabaseParams& history_database_params) { | 631 const HistoryDatabaseParams& history_database_params) { |
| 658 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 659 | |
| 660 DCHECK(!db_) << "Initializing HistoryBackend twice"; | 632 DCHECK(!db_) << "Initializing HistoryBackend twice"; |
| 661 // In the rare case where the db fails to initialize a dialog may get shown | 633 // In the rare case where the db fails to initialize a dialog may get shown |
| 662 // the blocks the caller, yet allows other messages through. For this reason | 634 // the blocks the caller, yet allows other messages through. For this reason |
| 663 // we only set db_ to the created database if creation is successful. That | 635 // we only set db_ to the created database if creation is successful. That |
| 664 // way other methods won't do anything as db_ is still null. | 636 // way other methods won't do anything as db_ is still null. |
| 665 | 637 |
| 666 TimeTicks beginning_time = TimeTicks::Now(); | 638 TimeTicks beginning_time = TimeTicks::Now(); |
| 667 | 639 |
| 668 // Compute the file names. | 640 // Compute the file names. |
| 669 history_dir_ = history_database_params.history_dir; | 641 history_dir_ = history_database_params.history_dir; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 760 backend_client_->OnHistoryBackendInitialized( | 732 backend_client_->OnHistoryBackendInitialized( |
| 761 this, db_.get(), thumbnail_db_.get(), history_dir_); | 733 this, db_.get(), thumbnail_db_.get(), history_dir_); |
| 762 } | 734 } |
| 763 #endif | 735 #endif |
| 764 | 736 |
| 765 LOCAL_HISTOGRAM_TIMES("History.InitTime", TimeTicks::Now() - beginning_time); | 737 LOCAL_HISTOGRAM_TIMES("History.InitTime", TimeTicks::Now() - beginning_time); |
| 766 } | 738 } |
| 767 | 739 |
| 768 void HistoryBackend::OnMemoryPressure( | 740 void HistoryBackend::OnMemoryPressure( |
| 769 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { | 741 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { |
| 770 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 771 | |
| 772 bool trim_aggressively = | 742 bool trim_aggressively = |
| 773 memory_pressure_level == | 743 memory_pressure_level == |
| 774 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL; | 744 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL; |
| 775 if (db_) | 745 if (db_) |
| 776 db_->TrimMemory(trim_aggressively); | 746 db_->TrimMemory(trim_aggressively); |
| 777 if (thumbnail_db_) | 747 if (thumbnail_db_) |
| 778 thumbnail_db_->TrimMemory(trim_aggressively); | 748 thumbnail_db_->TrimMemory(trim_aggressively); |
| 779 } | 749 } |
| 780 | 750 |
| 781 void HistoryBackend::CloseAllDatabases() { | 751 void HistoryBackend::CloseAllDatabases() { |
| 782 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 783 | |
| 784 if (db_) { | 752 if (db_) { |
| 785 // Commit the long-running transaction. | 753 // Commit the long-running transaction. |
| 786 db_->CommitTransaction(); | 754 db_->CommitTransaction(); |
| 787 db_.reset(); | 755 db_.reset(); |
| 788 // Forget the first recorded time since the database is closed. | 756 // Forget the first recorded time since the database is closed. |
| 789 first_recorded_time_ = base::Time(); | 757 first_recorded_time_ = base::Time(); |
| 790 } | 758 } |
| 791 if (thumbnail_db_) { | 759 if (thumbnail_db_) { |
| 792 thumbnail_db_->CommitTransaction(); | 760 thumbnail_db_->CommitTransaction(); |
| 793 thumbnail_db_.reset(); | 761 thumbnail_db_.reset(); |
| 794 } | 762 } |
| 795 } | 763 } |
| 796 | 764 |
| 797 void HistoryBackend::RecordTopHostsMetrics(const GURL& url) { | 765 void HistoryBackend::RecordTopHostsMetrics(const GURL& url) { |
| 798 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 799 | |
| 800 // Convert index from 0-based to 1-based. | 766 // Convert index from 0-based to 1-based. |
| 801 UMA_HISTOGRAM_ENUMERATION("History.TopHostsVisitsByRank", | 767 UMA_HISTOGRAM_ENUMERATION("History.TopHostsVisitsByRank", |
| 802 HostRankIfAvailable(url) + 1, kMaxTopHosts + 2); | 768 HostRankIfAvailable(url) + 1, kMaxTopHosts + 2); |
| 803 } | 769 } |
| 804 | 770 |
| 805 std::pair<URLID, VisitID> HistoryBackend::AddPageVisit( | 771 std::pair<URLID, VisitID> HistoryBackend::AddPageVisit( |
| 806 const GURL& url, | 772 const GURL& url, |
| 807 Time time, | 773 Time time, |
| 808 VisitID referring_visit, | 774 VisitID referring_visit, |
| 809 ui::PageTransition transition, | 775 ui::PageTransition transition, |
| 810 VisitSource visit_source) { | 776 VisitSource visit_source) { |
| 811 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 812 | |
| 813 // Top-level frame navigations are visible, everything else is hidden | 777 // Top-level frame navigations are visible, everything else is hidden |
| 814 bool new_hidden = !ui::PageTransitionIsMainFrame(transition); | 778 bool new_hidden = !ui::PageTransitionIsMainFrame(transition); |
| 815 | 779 |
| 816 // NOTE: This code must stay in sync with | 780 // NOTE: This code must stay in sync with |
| 817 // ExpireHistoryBackend::ExpireURLsForVisits(). | 781 // ExpireHistoryBackend::ExpireURLsForVisits(). |
| 818 int typed_increment = 0; | 782 int typed_increment = 0; |
| 819 if (ui::PageTransitionIsNewNavigation(transition) && | 783 if (ui::PageTransitionIsNewNavigation(transition) && |
| 820 ((ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED) && | 784 ((ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED) && |
| 821 !ui::PageTransitionIsRedirect(transition)) || | 785 !ui::PageTransitionIsRedirect(transition)) || |
| 822 ui::PageTransitionCoreTypeIs(transition, | 786 ui::PageTransitionCoreTypeIs(transition, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 877 } else { | 841 } else { |
| 878 DVLOG(0) << "Failed to build visit insert statement: " | 842 DVLOG(0) << "Failed to build visit insert statement: " |
| 879 << "url_id = " << url_id; | 843 << "url_id = " << url_id; |
| 880 } | 844 } |
| 881 | 845 |
| 882 return std::make_pair(url_id, visit_id); | 846 return std::make_pair(url_id, visit_id); |
| 883 } | 847 } |
| 884 | 848 |
| 885 void HistoryBackend::AddPagesWithDetails(const URLRows& urls, | 849 void HistoryBackend::AddPagesWithDetails(const URLRows& urls, |
| 886 VisitSource visit_source) { | 850 VisitSource visit_source) { |
| 887 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 888 | |
| 889 if (!db_) | 851 if (!db_) |
| 890 return; | 852 return; |
| 891 | 853 |
| 892 URLRows changed_urls; | 854 URLRows changed_urls; |
| 893 for (URLRows::const_iterator i = urls.begin(); i != urls.end(); ++i) { | 855 for (URLRows::const_iterator i = urls.begin(); i != urls.end(); ++i) { |
| 894 DCHECK(!i->last_visit().is_null()); | 856 DCHECK(!i->last_visit().is_null()); |
| 895 | 857 |
| 896 // As of M37, we no longer maintain an archived database, ignore old visits. | 858 // As of M37, we no longer maintain an archived database, ignore old visits. |
| 897 if (IsExpiredVisitTime(i->last_visit())) | 859 if (IsExpiredVisitTime(i->last_visit())) |
| 898 continue; | 860 continue; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 // Broadcast a notification for typed URLs that have been modified. This | 895 // Broadcast a notification for typed URLs that have been modified. This |
| 934 // will be picked up by the in-memory URL database on the main thread. | 896 // will be picked up by the in-memory URL database on the main thread. |
| 935 // | 897 // |
| 936 // TODO(brettw) bug 1140015: Add an "add page" notification so the history | 898 // TODO(brettw) bug 1140015: Add an "add page" notification so the history |
| 937 // views can keep in sync. | 899 // views can keep in sync. |
| 938 NotifyURLsModified(changed_urls); | 900 NotifyURLsModified(changed_urls); |
| 939 ScheduleCommit(); | 901 ScheduleCommit(); |
| 940 } | 902 } |
| 941 | 903 |
| 942 bool HistoryBackend::IsExpiredVisitTime(const base::Time& time) { | 904 bool HistoryBackend::IsExpiredVisitTime(const base::Time& time) { |
| 943 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 944 return time < expirer_.GetCurrentExpirationTime(); | 905 return time < expirer_.GetCurrentExpirationTime(); |
| 945 } | 906 } |
| 946 | 907 |
| 947 void HistoryBackend::SetPageTitle(const GURL& url, | 908 void HistoryBackend::SetPageTitle(const GURL& url, |
| 948 const base::string16& title) { | 909 const base::string16& title) { |
| 949 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 950 | |
| 951 if (!db_) | 910 if (!db_) |
| 952 return; | 911 return; |
| 953 | 912 |
| 954 // Search for recent redirects which should get the same title. We make a | 913 // Search for recent redirects which should get the same title. We make a |
| 955 // dummy list containing the exact URL visited if there are no redirects so | 914 // dummy list containing the exact URL visited if there are no redirects so |
| 956 // the processing below can be the same. | 915 // the processing below can be the same. |
| 957 RedirectList dummy_list; | 916 RedirectList dummy_list; |
| 958 RedirectList* redirects; | 917 RedirectList* redirects; |
| 959 RedirectCache::iterator iter = recent_redirects_.Get(url); | 918 RedirectCache::iterator iter = recent_redirects_.Get(url); |
| 960 if (iter != recent_redirects_.end()) { | 919 if (iter != recent_redirects_.end()) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 984 // Broadcast notifications for any URLs that have changed. This will | 943 // Broadcast notifications for any URLs that have changed. This will |
| 985 // update the in-memory database and the InMemoryURLIndex. | 944 // update the in-memory database and the InMemoryURLIndex. |
| 986 if (!changed_urls.empty()) { | 945 if (!changed_urls.empty()) { |
| 987 NotifyURLsModified(changed_urls); | 946 NotifyURLsModified(changed_urls); |
| 988 ScheduleCommit(); | 947 ScheduleCommit(); |
| 989 } | 948 } |
| 990 } | 949 } |
| 991 | 950 |
| 992 void HistoryBackend::AddPageNoVisitForBookmark(const GURL& url, | 951 void HistoryBackend::AddPageNoVisitForBookmark(const GURL& url, |
| 993 const base::string16& title) { | 952 const base::string16& title) { |
| 994 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 995 | |
| 996 if (!db_) | 953 if (!db_) |
| 997 return; | 954 return; |
| 998 | 955 |
| 999 URLRow url_info(url); | 956 URLRow url_info(url); |
| 1000 URLID url_id = db_->GetRowForURL(url, &url_info); | 957 URLID url_id = db_->GetRowForURL(url, &url_info); |
| 1001 if (url_id) { | 958 if (url_id) { |
| 1002 // URL is already known, nothing to do. | 959 // URL is already known, nothing to do. |
| 1003 return; | 960 return; |
| 1004 } | 961 } |
| 1005 | 962 |
| 1006 if (!title.empty()) { | 963 if (!title.empty()) { |
| 1007 url_info.set_title(title); | 964 url_info.set_title(title); |
| 1008 } else { | 965 } else { |
| 1009 url_info.set_title(base::UTF8ToUTF16(url.spec())); | 966 url_info.set_title(base::UTF8ToUTF16(url.spec())); |
| 1010 } | 967 } |
| 1011 | 968 |
| 1012 url_info.set_last_visit(Time::Now()); | 969 url_info.set_last_visit(Time::Now()); |
| 1013 // Mark the page hidden. If the user types it in, it'll unhide. | 970 // Mark the page hidden. If the user types it in, it'll unhide. |
| 1014 url_info.set_hidden(true); | 971 url_info.set_hidden(true); |
| 1015 | 972 |
| 1016 db_->AddURL(url_info); | 973 db_->AddURL(url_info); |
| 1017 } | 974 } |
| 1018 | 975 |
| 1019 bool HistoryBackend::GetAllTypedURLs(URLRows* urls) { | 976 bool HistoryBackend::GetAllTypedURLs(URLRows* urls) { |
| 1020 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1021 | |
| 1022 if (db_) | 977 if (db_) |
| 1023 return db_->GetAllTypedUrls(urls); | 978 return db_->GetAllTypedUrls(urls); |
| 1024 return false; | 979 return false; |
| 1025 } | 980 } |
| 1026 | 981 |
| 1027 bool HistoryBackend::GetVisitsForURL(URLID id, VisitVector* visits) { | 982 bool HistoryBackend::GetVisitsForURL(URLID id, VisitVector* visits) { |
| 1028 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1029 | |
| 1030 if (db_) | 983 if (db_) |
| 1031 return db_->GetVisitsForURL(id, visits); | 984 return db_->GetVisitsForURL(id, visits); |
| 1032 return false; | 985 return false; |
| 1033 } | 986 } |
| 1034 | 987 |
| 1035 bool HistoryBackend::GetMostRecentVisitsForURL(URLID id, | 988 bool HistoryBackend::GetMostRecentVisitsForURL(URLID id, |
| 1036 int max_visits, | 989 int max_visits, |
| 1037 VisitVector* visits) { | 990 VisitVector* visits) { |
| 1038 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1039 | |
| 1040 if (db_) | 991 if (db_) |
| 1041 return db_->GetMostRecentVisitsForURL(id, max_visits, visits); | 992 return db_->GetMostRecentVisitsForURL(id, max_visits, visits); |
| 1042 return false; | 993 return false; |
| 1043 } | 994 } |
| 1044 | 995 |
| 1045 size_t HistoryBackend::UpdateURLs(const URLRows& urls) { | 996 size_t HistoryBackend::UpdateURLs(const URLRows& urls) { |
| 1046 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1047 | |
| 1048 if (!db_) | 997 if (!db_) |
| 1049 return 0; | 998 return 0; |
| 1050 | 999 |
| 1051 URLRows changed_urls; | 1000 URLRows changed_urls; |
| 1052 for (URLRows::const_iterator it = urls.begin(); it != urls.end(); ++it) { | 1001 for (URLRows::const_iterator it = urls.begin(); it != urls.end(); ++it) { |
| 1053 DCHECK(it->id()); | 1002 DCHECK(it->id()); |
| 1054 if (db_->UpdateURLRow(it->id(), *it)) | 1003 if (db_->UpdateURLRow(it->id(), *it)) |
| 1055 changed_urls.push_back(*it); | 1004 changed_urls.push_back(*it); |
| 1056 } | 1005 } |
| 1057 | 1006 |
| 1058 // Broadcast notifications for any URLs that have actually been changed. This | 1007 // Broadcast notifications for any URLs that have actually been changed. This |
| 1059 // will update the in-memory database and the InMemoryURLIndex. | 1008 // will update the in-memory database and the InMemoryURLIndex. |
| 1060 size_t num_updated_records = changed_urls.size(); | 1009 size_t num_updated_records = changed_urls.size(); |
| 1061 if (num_updated_records) { | 1010 if (num_updated_records) { |
| 1062 NotifyURLsModified(changed_urls); | 1011 NotifyURLsModified(changed_urls); |
| 1063 ScheduleCommit(); | 1012 ScheduleCommit(); |
| 1064 } | 1013 } |
| 1065 return num_updated_records; | 1014 return num_updated_records; |
| 1066 } | 1015 } |
| 1067 | 1016 |
| 1068 bool HistoryBackend::AddVisits(const GURL& url, | 1017 bool HistoryBackend::AddVisits(const GURL& url, |
| 1069 const std::vector<VisitInfo>& visits, | 1018 const std::vector<VisitInfo>& visits, |
| 1070 VisitSource visit_source) { | 1019 VisitSource visit_source) { |
| 1071 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1072 | |
| 1073 if (db_) { | 1020 if (db_) { |
| 1074 for (std::vector<VisitInfo>::const_iterator visit = visits.begin(); | 1021 for (std::vector<VisitInfo>::const_iterator visit = visits.begin(); |
| 1075 visit != visits.end(); ++visit) { | 1022 visit != visits.end(); ++visit) { |
| 1076 if (!AddPageVisit(url, visit->first, 0, visit->second, visit_source) | 1023 if (!AddPageVisit(url, visit->first, 0, visit->second, visit_source) |
| 1077 .first) { | 1024 .first) { |
| 1078 return false; | 1025 return false; |
| 1079 } | 1026 } |
| 1080 } | 1027 } |
| 1081 ScheduleCommit(); | 1028 ScheduleCommit(); |
| 1082 return true; | 1029 return true; |
| 1083 } | 1030 } |
| 1084 return false; | 1031 return false; |
| 1085 } | 1032 } |
| 1086 | 1033 |
| 1087 bool HistoryBackend::RemoveVisits(const VisitVector& visits) { | 1034 bool HistoryBackend::RemoveVisits(const VisitVector& visits) { |
| 1088 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1089 | |
| 1090 if (!db_) | 1035 if (!db_) |
| 1091 return false; | 1036 return false; |
| 1092 | 1037 |
| 1093 expirer_.ExpireVisits(visits); | 1038 expirer_.ExpireVisits(visits); |
| 1094 ScheduleCommit(); | 1039 ScheduleCommit(); |
| 1095 return true; | 1040 return true; |
| 1096 } | 1041 } |
| 1097 | 1042 |
| 1098 bool HistoryBackend::GetVisitsSource(const VisitVector& visits, | 1043 bool HistoryBackend::GetVisitsSource(const VisitVector& visits, |
| 1099 VisitSourceMap* sources) { | 1044 VisitSourceMap* sources) { |
| 1100 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1101 | |
| 1102 if (!db_) | 1045 if (!db_) |
| 1103 return false; | 1046 return false; |
| 1104 | 1047 |
| 1105 db_->GetVisitsSource(visits, sources); | 1048 db_->GetVisitsSource(visits, sources); |
| 1106 return true; | 1049 return true; |
| 1107 } | 1050 } |
| 1108 | 1051 |
| 1109 bool HistoryBackend::GetURL(const GURL& url, URLRow* url_row) { | 1052 bool HistoryBackend::GetURL(const GURL& url, URLRow* url_row) { |
| 1110 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1111 | |
| 1112 if (db_) | 1053 if (db_) |
| 1113 return db_->GetRowForURL(url, url_row) != 0; | 1054 return db_->GetRowForURL(url, url_row) != 0; |
| 1114 return false; | 1055 return false; |
| 1115 } | 1056 } |
| 1116 | 1057 |
| 1117 void HistoryBackend::QueryURL(const GURL& url, | 1058 void HistoryBackend::QueryURL(const GURL& url, |
| 1118 bool want_visits, | 1059 bool want_visits, |
| 1119 QueryURLResult* result) { | 1060 QueryURLResult* result) { |
| 1120 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1121 DCHECK(result); | 1061 DCHECK(result); |
| 1122 result->success = db_ && db_->GetRowForURL(url, &result->row); | 1062 result->success = db_ && db_->GetRowForURL(url, &result->row); |
| 1123 // Optionally query the visits. | 1063 // Optionally query the visits. |
| 1124 if (result->success && want_visits) | 1064 if (result->success && want_visits) |
| 1125 db_->GetVisitsForURL(result->row.id(), &result->visits); | 1065 db_->GetVisitsForURL(result->row.id(), &result->visits); |
| 1126 } | 1066 } |
| 1127 | 1067 |
| 1128 TypedUrlSyncableService* HistoryBackend::GetTypedUrlSyncableService() const { | 1068 TypedUrlSyncableService* HistoryBackend::GetTypedUrlSyncableService() const { |
| 1129 return typed_url_syncable_service_.get(); | 1069 return typed_url_syncable_service_.get(); |
| 1130 } | 1070 } |
| 1131 | 1071 |
| 1132 // Statistics ------------------------------------------------------------------ | 1072 // Statistics ------------------------------------------------------------------ |
| 1133 | 1073 |
| 1134 HistoryCountResult HistoryBackend::GetHistoryCount(const Time& begin_time, | 1074 HistoryCountResult HistoryBackend::GetHistoryCount(const Time& begin_time, |
| 1135 const Time& end_time) { | 1075 const Time& end_time) { |
| 1136 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1137 | |
| 1138 HistoryCountResult result; | 1076 HistoryCountResult result; |
| 1139 result.count = 0; | 1077 result.count = 0; |
| 1140 result.success = | 1078 result.success = |
| 1141 db_ && db_->GetHistoryCount(begin_time, end_time, &result.count); | 1079 db_ && db_->GetHistoryCount(begin_time, end_time, &result.count); |
| 1142 return result; | 1080 return result; |
| 1143 } | 1081 } |
| 1144 | 1082 |
| 1145 // Keyword visits -------------------------------------------------------------- | 1083 // Keyword visits -------------------------------------------------------------- |
| 1146 | 1084 |
| 1147 void HistoryBackend::SetKeywordSearchTermsForURL(const GURL& url, | 1085 void HistoryBackend::SetKeywordSearchTermsForURL(const GURL& url, |
| 1148 KeywordID keyword_id, | 1086 KeywordID keyword_id, |
| 1149 const base::string16& term) { | 1087 const base::string16& term) { |
| 1150 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1151 | |
| 1152 if (!db_) | 1088 if (!db_) |
| 1153 return; | 1089 return; |
| 1154 | 1090 |
| 1155 // Get the ID for this URL. | 1091 // Get the ID for this URL. |
| 1156 URLRow row; | 1092 URLRow row; |
| 1157 if (!db_->GetRowForURL(url, &row)) { | 1093 if (!db_->GetRowForURL(url, &row)) { |
| 1158 // There is a small possibility the url was deleted before the keyword | 1094 // There is a small possibility the url was deleted before the keyword |
| 1159 // was added. Ignore the request. | 1095 // was added. Ignore the request. |
| 1160 return; | 1096 return; |
| 1161 } | 1097 } |
| 1162 | 1098 |
| 1163 db_->SetKeywordSearchTermsForURL(row.id(), keyword_id, term); | 1099 db_->SetKeywordSearchTermsForURL(row.id(), keyword_id, term); |
| 1164 | 1100 |
| 1165 if (delegate_) | 1101 if (delegate_) |
| 1166 delegate_->NotifyKeywordSearchTermUpdated(row, keyword_id, term); | 1102 delegate_->NotifyKeywordSearchTermUpdated(row, keyword_id, term); |
| 1167 | 1103 |
| 1168 ScheduleCommit(); | 1104 ScheduleCommit(); |
| 1169 } | 1105 } |
| 1170 | 1106 |
| 1171 void HistoryBackend::DeleteAllSearchTermsForKeyword(KeywordID keyword_id) { | 1107 void HistoryBackend::DeleteAllSearchTermsForKeyword(KeywordID keyword_id) { |
| 1172 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1173 | |
| 1174 if (!db_) | 1108 if (!db_) |
| 1175 return; | 1109 return; |
| 1176 | 1110 |
| 1177 db_->DeleteAllSearchTermsForKeyword(keyword_id); | 1111 db_->DeleteAllSearchTermsForKeyword(keyword_id); |
| 1178 ScheduleCommit(); | 1112 ScheduleCommit(); |
| 1179 } | 1113 } |
| 1180 | 1114 |
| 1181 void HistoryBackend::DeleteKeywordSearchTermForURL(const GURL& url) { | 1115 void HistoryBackend::DeleteKeywordSearchTermForURL(const GURL& url) { |
| 1182 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1183 | |
| 1184 if (!db_) | 1116 if (!db_) |
| 1185 return; | 1117 return; |
| 1186 | 1118 |
| 1187 URLID url_id = db_->GetRowForURL(url, nullptr); | 1119 URLID url_id = db_->GetRowForURL(url, nullptr); |
| 1188 if (!url_id) | 1120 if (!url_id) |
| 1189 return; | 1121 return; |
| 1190 db_->DeleteKeywordSearchTermForURL(url_id); | 1122 db_->DeleteKeywordSearchTermForURL(url_id); |
| 1191 | 1123 |
| 1192 if (delegate_) | 1124 if (delegate_) |
| 1193 delegate_->NotifyKeywordSearchTermDeleted(url_id); | 1125 delegate_->NotifyKeywordSearchTermDeleted(url_id); |
| 1194 | 1126 |
| 1195 ScheduleCommit(); | 1127 ScheduleCommit(); |
| 1196 } | 1128 } |
| 1197 | 1129 |
| 1198 void HistoryBackend::DeleteMatchingURLsForKeyword(KeywordID keyword_id, | 1130 void HistoryBackend::DeleteMatchingURLsForKeyword(KeywordID keyword_id, |
| 1199 const base::string16& term) { | 1131 const base::string16& term) { |
| 1200 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1201 | |
| 1202 if (!db_) | 1132 if (!db_) |
| 1203 return; | 1133 return; |
| 1204 | 1134 |
| 1205 std::vector<KeywordSearchTermRow> rows; | 1135 std::vector<KeywordSearchTermRow> rows; |
| 1206 if (db_->GetKeywordSearchTermRows(term, &rows)) { | 1136 if (db_->GetKeywordSearchTermRows(term, &rows)) { |
| 1207 std::vector<GURL> items_to_delete; | 1137 std::vector<GURL> items_to_delete; |
| 1208 URLRow row; | 1138 URLRow row; |
| 1209 for (std::vector<KeywordSearchTermRow>::iterator it = rows.begin(); | 1139 for (std::vector<KeywordSearchTermRow>::iterator it = rows.begin(); |
| 1210 it != rows.end(); ++it) { | 1140 it != rows.end(); ++it) { |
| 1211 if ((it->keyword_id == keyword_id) && db_->GetURLRow(it->url_id, &row)) | 1141 if ((it->keyword_id == keyword_id) && db_->GetURLRow(it->url_id, &row)) |
| 1212 items_to_delete.push_back(row.url()); | 1142 items_to_delete.push_back(row.url()); |
| 1213 } | 1143 } |
| 1214 DeleteURLs(items_to_delete); | 1144 DeleteURLs(items_to_delete); |
| 1215 } | 1145 } |
| 1216 } | 1146 } |
| 1217 | 1147 |
| 1218 // Observers ------------------------------------------------------------------- | 1148 // Observers ------------------------------------------------------------------- |
| 1219 | 1149 |
| 1220 void HistoryBackend::AddObserver(HistoryBackendObserver* observer) { | 1150 void HistoryBackend::AddObserver(HistoryBackendObserver* observer) { |
| 1221 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1222 observers_.AddObserver(observer); | 1151 observers_.AddObserver(observer); |
| 1223 } | 1152 } |
| 1224 | 1153 |
| 1225 void HistoryBackend::RemoveObserver(HistoryBackendObserver* observer) { | 1154 void HistoryBackend::RemoveObserver(HistoryBackendObserver* observer) { |
| 1226 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1227 observers_.RemoveObserver(observer); | 1155 observers_.RemoveObserver(observer); |
| 1228 } | 1156 } |
| 1229 | 1157 |
| 1230 // Downloads ------------------------------------------------------------------- | 1158 // Downloads ------------------------------------------------------------------- |
| 1231 | 1159 |
| 1232 uint32_t HistoryBackend::GetNextDownloadId() { | 1160 uint32_t HistoryBackend::GetNextDownloadId() { |
| 1233 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1234 return db_ ? db_->GetNextDownloadId() : kInvalidDownloadId; | 1161 return db_ ? db_->GetNextDownloadId() : kInvalidDownloadId; |
| 1235 } | 1162 } |
| 1236 | 1163 |
| 1237 // Get all the download entries from the database. | 1164 // Get all the download entries from the database. |
| 1238 void HistoryBackend::QueryDownloads(std::vector<DownloadRow>* rows) { | 1165 void HistoryBackend::QueryDownloads(std::vector<DownloadRow>* rows) { |
| 1239 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1240 | |
| 1241 if (db_) | 1166 if (db_) |
| 1242 db_->QueryDownloads(rows); | 1167 db_->QueryDownloads(rows); |
| 1243 } | 1168 } |
| 1244 | 1169 |
| 1245 // Update a particular download entry. | 1170 // Update a particular download entry. |
| 1246 void HistoryBackend::UpdateDownload( | 1171 void HistoryBackend::UpdateDownload( |
| 1247 const DownloadRow& data, | 1172 const DownloadRow& data, |
| 1248 bool should_commit_immediately) { | 1173 bool should_commit_immediately) { |
| 1249 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1250 | |
| 1251 if (!db_) | 1174 if (!db_) |
| 1252 return; | 1175 return; |
| 1253 db_->UpdateDownload(data); | 1176 db_->UpdateDownload(data); |
| 1254 if (should_commit_immediately) | 1177 if (should_commit_immediately) |
| 1255 Commit(); | 1178 Commit(); |
| 1256 else | 1179 else |
| 1257 ScheduleCommit(); | 1180 ScheduleCommit(); |
| 1258 } | 1181 } |
| 1259 | 1182 |
| 1260 bool HistoryBackend::CreateDownload(const DownloadRow& history_info) { | 1183 bool HistoryBackend::CreateDownload(const DownloadRow& history_info) { |
| 1261 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1262 | |
| 1263 if (!db_) | 1184 if (!db_) |
| 1264 return false; | 1185 return false; |
| 1265 bool success = db_->CreateDownload(history_info); | 1186 bool success = db_->CreateDownload(history_info); |
| 1266 #if defined(OS_ANDROID) | 1187 #if defined(OS_ANDROID) |
| 1267 // On android, browser process can get easily killed. Download will no longer | 1188 // On android, browser process can get easily killed. Download will no longer |
| 1268 // be able to resume and the temporary file will linger forever if the | 1189 // be able to resume and the temporary file will linger forever if the |
| 1269 // download is not committed before that. Do the commit right away to avoid | 1190 // download is not committed before that. Do the commit right away to avoid |
| 1270 // uncommitted download entry if browser is killed. | 1191 // uncommitted download entry if browser is killed. |
| 1271 Commit(); | 1192 Commit(); |
| 1272 #else | 1193 #else |
| 1273 ScheduleCommit(); | 1194 ScheduleCommit(); |
| 1274 #endif | 1195 #endif |
| 1275 return success; | 1196 return success; |
| 1276 } | 1197 } |
| 1277 | 1198 |
| 1278 void HistoryBackend::RemoveDownloads(const std::set<uint32_t>& ids) { | 1199 void HistoryBackend::RemoveDownloads(const std::set<uint32_t>& ids) { |
| 1279 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1280 | |
| 1281 if (!db_) | 1200 if (!db_) |
| 1282 return; | 1201 return; |
| 1283 size_t downloads_count_before = db_->CountDownloads(); | 1202 size_t downloads_count_before = db_->CountDownloads(); |
| 1284 base::TimeTicks started_removing = base::TimeTicks::Now(); | 1203 base::TimeTicks started_removing = base::TimeTicks::Now(); |
| 1285 // HistoryBackend uses a long-running Transaction that is committed | 1204 // HistoryBackend uses a long-running Transaction that is committed |
| 1286 // periodically, so this loop doesn't actually hit the disk too hard. | 1205 // periodically, so this loop doesn't actually hit the disk too hard. |
| 1287 for (std::set<uint32_t>::const_iterator it = ids.begin(); it != ids.end(); | 1206 for (std::set<uint32_t>::const_iterator it = ids.begin(); it != ids.end(); |
| 1288 ++it) { | 1207 ++it) { |
| 1289 db_->RemoveDownload(*it); | 1208 db_->RemoveDownload(*it); |
| 1290 } | 1209 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1303 if (num_downloads_deleted > 0) { | 1222 if (num_downloads_deleted > 0) { |
| 1304 UMA_HISTOGRAM_TIMES("Download.DatabaseRemoveDownloadsTimePerRecord", | 1223 UMA_HISTOGRAM_TIMES("Download.DatabaseRemoveDownloadsTimePerRecord", |
| 1305 (1000 * micros) / num_downloads_deleted); | 1224 (1000 * micros) / num_downloads_deleted); |
| 1306 } | 1225 } |
| 1307 DCHECK_GE(ids.size(), num_downloads_deleted); | 1226 DCHECK_GE(ids.size(), num_downloads_deleted); |
| 1308 } | 1227 } |
| 1309 | 1228 |
| 1310 void HistoryBackend::QueryHistory(const base::string16& text_query, | 1229 void HistoryBackend::QueryHistory(const base::string16& text_query, |
| 1311 const QueryOptions& options, | 1230 const QueryOptions& options, |
| 1312 QueryResults* query_results) { | 1231 QueryResults* query_results) { |
| 1313 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1314 | |
| 1315 DCHECK(query_results); | 1232 DCHECK(query_results); |
| 1316 base::TimeTicks beginning_time = base::TimeTicks::Now(); | 1233 base::TimeTicks beginning_time = base::TimeTicks::Now(); |
| 1317 if (db_) { | 1234 if (db_) { |
| 1318 if (text_query.empty()) { | 1235 if (text_query.empty()) { |
| 1319 // Basic history query for the main database. | 1236 // Basic history query for the main database. |
| 1320 QueryHistoryBasic(options, query_results); | 1237 QueryHistoryBasic(options, query_results); |
| 1321 } else { | 1238 } else { |
| 1322 // Text history query. | 1239 // Text history query. |
| 1323 QueryHistoryText(text_query, options, query_results); | 1240 QueryHistoryText(text_query, options, query_results); |
| 1324 } | 1241 } |
| 1325 } | 1242 } |
| 1326 UMA_HISTOGRAM_TIMES("History.QueryHistory", | 1243 UMA_HISTOGRAM_TIMES("History.QueryHistory", |
| 1327 TimeTicks::Now() - beginning_time); | 1244 TimeTicks::Now() - beginning_time); |
| 1328 } | 1245 } |
| 1329 | 1246 |
| 1330 // Basic time-based querying of history. | 1247 // Basic time-based querying of history. |
| 1331 void HistoryBackend::QueryHistoryBasic(const QueryOptions& options, | 1248 void HistoryBackend::QueryHistoryBasic(const QueryOptions& options, |
| 1332 QueryResults* result) { | 1249 QueryResults* result) { |
| 1333 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1334 | |
| 1335 // First get all visits. | 1250 // First get all visits. |
| 1336 VisitVector visits; | 1251 VisitVector visits; |
| 1337 bool has_more_results = db_->GetVisibleVisitsInRange(options, &visits); | 1252 bool has_more_results = db_->GetVisibleVisitsInRange(options, &visits); |
| 1338 DCHECK_LE(static_cast<int>(visits.size()), options.EffectiveMaxCount()); | 1253 DCHECK_LE(static_cast<int>(visits.size()), options.EffectiveMaxCount()); |
| 1339 | 1254 |
| 1340 // Now add them and the URL rows to the results. | 1255 // Now add them and the URL rows to the results. |
| 1341 URLResult url_result; | 1256 URLResult url_result; |
| 1342 for (size_t i = 0; i < visits.size(); i++) { | 1257 for (size_t i = 0; i < visits.size(); i++) { |
| 1343 const VisitRow visit = visits[i]; | 1258 const VisitRow visit = visits[i]; |
| 1344 | 1259 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1367 } | 1282 } |
| 1368 | 1283 |
| 1369 if (!has_more_results && options.begin_time <= first_recorded_time_) | 1284 if (!has_more_results && options.begin_time <= first_recorded_time_) |
| 1370 result->set_reached_beginning(true); | 1285 result->set_reached_beginning(true); |
| 1371 } | 1286 } |
| 1372 | 1287 |
| 1373 // Text-based querying of history. | 1288 // Text-based querying of history. |
| 1374 void HistoryBackend::QueryHistoryText(const base::string16& text_query, | 1289 void HistoryBackend::QueryHistoryText(const base::string16& text_query, |
| 1375 const QueryOptions& options, | 1290 const QueryOptions& options, |
| 1376 QueryResults* result) { | 1291 QueryResults* result) { |
| 1377 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1378 | |
| 1379 URLRows text_matches; | 1292 URLRows text_matches; |
| 1380 db_->GetTextMatchesWithAlgorithm(text_query, options.matching_algorithm, | 1293 db_->GetTextMatchesWithAlgorithm(text_query, options.matching_algorithm, |
| 1381 &text_matches); | 1294 &text_matches); |
| 1382 | 1295 |
| 1383 std::vector<URLResult> matching_visits; | 1296 std::vector<URLResult> matching_visits; |
| 1384 VisitVector visits; // Declare outside loop to prevent re-construction. | 1297 VisitVector visits; // Declare outside loop to prevent re-construction. |
| 1385 for (size_t i = 0; i < text_matches.size(); i++) { | 1298 for (size_t i = 0; i < text_matches.size(); i++) { |
| 1386 const URLRow& text_match = text_matches[i]; | 1299 const URLRow& text_match = text_matches[i]; |
| 1387 // Get all visits for given URL match. | 1300 // Get all visits for given URL match. |
| 1388 db_->GetVisibleVisitsForURL(text_match.id(), options, &visits); | 1301 db_->GetVisibleVisitsForURL(text_match.id(), options, &visits); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1404 result->AppendURLBySwapping(&(*it)); | 1317 result->AppendURLBySwapping(&(*it)); |
| 1405 } | 1318 } |
| 1406 | 1319 |
| 1407 if (matching_visits.size() == result->size() && | 1320 if (matching_visits.size() == result->size() && |
| 1408 options.begin_time <= first_recorded_time_) | 1321 options.begin_time <= first_recorded_time_) |
| 1409 result->set_reached_beginning(true); | 1322 result->set_reached_beginning(true); |
| 1410 } | 1323 } |
| 1411 | 1324 |
| 1412 void HistoryBackend::QueryRedirectsFrom(const GURL& from_url, | 1325 void HistoryBackend::QueryRedirectsFrom(const GURL& from_url, |
| 1413 RedirectList* redirects) { | 1326 RedirectList* redirects) { |
| 1414 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1415 | |
| 1416 redirects->clear(); | 1327 redirects->clear(); |
| 1417 if (!db_) | 1328 if (!db_) |
| 1418 return; | 1329 return; |
| 1419 | 1330 |
| 1420 URLID from_url_id = db_->GetRowForURL(from_url, nullptr); | 1331 URLID from_url_id = db_->GetRowForURL(from_url, nullptr); |
| 1421 VisitID cur_visit = db_->GetMostRecentVisitForURL(from_url_id, nullptr); | 1332 VisitID cur_visit = db_->GetMostRecentVisitForURL(from_url_id, nullptr); |
| 1422 if (!cur_visit) | 1333 if (!cur_visit) |
| 1423 return; // No visits for URL. | 1334 return; // No visits for URL. |
| 1424 | 1335 |
| 1425 GetRedirectsFromSpecificVisit(cur_visit, redirects); | 1336 GetRedirectsFromSpecificVisit(cur_visit, redirects); |
| 1426 } | 1337 } |
| 1427 | 1338 |
| 1428 void HistoryBackend::QueryRedirectsTo(const GURL& to_url, | 1339 void HistoryBackend::QueryRedirectsTo(const GURL& to_url, |
| 1429 RedirectList* redirects) { | 1340 RedirectList* redirects) { |
| 1430 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1431 | |
| 1432 redirects->clear(); | 1341 redirects->clear(); |
| 1433 if (!db_) | 1342 if (!db_) |
| 1434 return; | 1343 return; |
| 1435 | 1344 |
| 1436 URLID to_url_id = db_->GetRowForURL(to_url, nullptr); | 1345 URLID to_url_id = db_->GetRowForURL(to_url, nullptr); |
| 1437 VisitID cur_visit = db_->GetMostRecentVisitForURL(to_url_id, nullptr); | 1346 VisitID cur_visit = db_->GetMostRecentVisitForURL(to_url_id, nullptr); |
| 1438 if (!cur_visit) | 1347 if (!cur_visit) |
| 1439 return; // No visits for URL. | 1348 return; // No visits for URL. |
| 1440 | 1349 |
| 1441 GetRedirectsToSpecificVisit(cur_visit, redirects); | 1350 GetRedirectsToSpecificVisit(cur_visit, redirects); |
| 1442 } | 1351 } |
| 1443 | 1352 |
| 1444 void HistoryBackend::GetVisibleVisitCountToHost( | 1353 void HistoryBackend::GetVisibleVisitCountToHost( |
| 1445 const GURL& url, | 1354 const GURL& url, |
| 1446 VisibleVisitCountToHostResult* result) { | 1355 VisibleVisitCountToHostResult* result) { |
| 1447 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1448 | |
| 1449 result->count = 0; | 1356 result->count = 0; |
| 1450 result->success = db_ && | 1357 result->success = db_ && |
| 1451 db_->GetVisibleVisitCountToHost(url, &result->count, | 1358 db_->GetVisibleVisitCountToHost(url, &result->count, |
| 1452 &result->first_visit); | 1359 &result->first_visit); |
| 1453 } | 1360 } |
| 1454 | 1361 |
| 1455 void HistoryBackend::QueryMostVisitedURLs(int result_count, | 1362 void HistoryBackend::QueryMostVisitedURLs(int result_count, |
| 1456 int days_back, | 1363 int days_back, |
| 1457 MostVisitedURLList* result) { | 1364 MostVisitedURLList* result) { |
| 1458 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1459 | |
| 1460 if (!db_) | 1365 if (!db_) |
| 1461 return; | 1366 return; |
| 1462 | 1367 |
| 1463 auto url_filter = backend_client_ | 1368 auto url_filter = backend_client_ |
| 1464 ? base::Bind(&HistoryBackendClient::IsWebSafe, | 1369 ? base::Bind(&HistoryBackendClient::IsWebSafe, |
| 1465 base::Unretained(backend_client_.get())) | 1370 base::Unretained(backend_client_.get())) |
| 1466 : base::Callback<bool(const GURL&)>(); | 1371 : base::Callback<bool(const GURL&)>(); |
| 1467 std::vector<std::unique_ptr<PageUsageData>> data = db_->QuerySegmentUsage( | 1372 std::vector<std::unique_ptr<PageUsageData>> data = db_->QuerySegmentUsage( |
| 1468 base::Time::Now() - base::TimeDelta::FromDays(days_back), result_count, | 1373 base::Time::Now() - base::TimeDelta::FromDays(days_back), result_count, |
| 1469 url_filter); | 1374 url_filter); |
| 1470 | 1375 |
| 1471 for (const std::unique_ptr<PageUsageData>& current_data : data) { | 1376 for (const std::unique_ptr<PageUsageData>& current_data : data) { |
| 1472 RedirectList redirects; | 1377 RedirectList redirects; |
| 1473 QueryRedirectsFrom(current_data->GetURL(), &redirects); | 1378 QueryRedirectsFrom(current_data->GetURL(), &redirects); |
| 1474 MostVisitedURL url = MakeMostVisitedURL(*current_data, redirects); | 1379 MostVisitedURL url = MakeMostVisitedURL(*current_data, redirects); |
| 1475 result->push_back(url); | 1380 result->push_back(url); |
| 1476 } | 1381 } |
| 1477 } | 1382 } |
| 1478 | 1383 |
| 1479 void HistoryBackend::GetRedirectsFromSpecificVisit(VisitID cur_visit, | 1384 void HistoryBackend::GetRedirectsFromSpecificVisit(VisitID cur_visit, |
| 1480 RedirectList* redirects) { | 1385 RedirectList* redirects) { |
| 1481 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1482 | |
| 1483 // Follow any redirects from the given visit and add them to the list. | 1386 // Follow any redirects from the given visit and add them to the list. |
| 1484 // It *should* be impossible to get a circular chain here, but we check | 1387 // It *should* be impossible to get a circular chain here, but we check |
| 1485 // just in case to avoid infinite loops. | 1388 // just in case to avoid infinite loops. |
| 1486 GURL cur_url; | 1389 GURL cur_url; |
| 1487 std::set<VisitID> visit_set; | 1390 std::set<VisitID> visit_set; |
| 1488 visit_set.insert(cur_visit); | 1391 visit_set.insert(cur_visit); |
| 1489 while (db_->GetRedirectFromVisit(cur_visit, &cur_visit, &cur_url)) { | 1392 while (db_->GetRedirectFromVisit(cur_visit, &cur_visit, &cur_url)) { |
| 1490 if (visit_set.find(cur_visit) != visit_set.end()) { | 1393 if (visit_set.find(cur_visit) != visit_set.end()) { |
| 1491 NOTREACHED() << "Loop in visit chain, giving up"; | 1394 NOTREACHED() << "Loop in visit chain, giving up"; |
| 1492 return; | 1395 return; |
| 1493 } | 1396 } |
| 1494 visit_set.insert(cur_visit); | 1397 visit_set.insert(cur_visit); |
| 1495 redirects->push_back(cur_url); | 1398 redirects->push_back(cur_url); |
| 1496 } | 1399 } |
| 1497 } | 1400 } |
| 1498 | 1401 |
| 1499 void HistoryBackend::GetRedirectsToSpecificVisit(VisitID cur_visit, | 1402 void HistoryBackend::GetRedirectsToSpecificVisit(VisitID cur_visit, |
| 1500 RedirectList* redirects) { | 1403 RedirectList* redirects) { |
| 1501 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1502 | |
| 1503 // Follow redirects going to cur_visit. These are added to |redirects| in | 1404 // Follow redirects going to cur_visit. These are added to |redirects| in |
| 1504 // the order they are found. If a redirect chain looks like A -> B -> C and | 1405 // the order they are found. If a redirect chain looks like A -> B -> C and |
| 1505 // |cur_visit| = C, redirects will be {B, A} in that order. | 1406 // |cur_visit| = C, redirects will be {B, A} in that order. |
| 1506 if (!db_) | 1407 if (!db_) |
| 1507 return; | 1408 return; |
| 1508 | 1409 |
| 1509 GURL cur_url; | 1410 GURL cur_url; |
| 1510 std::set<VisitID> visit_set; | 1411 std::set<VisitID> visit_set; |
| 1511 visit_set.insert(cur_visit); | 1412 visit_set.insert(cur_visit); |
| 1512 while (db_->GetRedirectToVisit(cur_visit, &cur_visit, &cur_url)) { | 1413 while (db_->GetRedirectToVisit(cur_visit, &cur_visit, &cur_url)) { |
| 1513 if (visit_set.find(cur_visit) != visit_set.end()) { | 1414 if (visit_set.find(cur_visit) != visit_set.end()) { |
| 1514 NOTREACHED() << "Loop in visit chain, giving up"; | 1415 NOTREACHED() << "Loop in visit chain, giving up"; |
| 1515 return; | 1416 return; |
| 1516 } | 1417 } |
| 1517 visit_set.insert(cur_visit); | 1418 visit_set.insert(cur_visit); |
| 1518 redirects->push_back(cur_url); | 1419 redirects->push_back(cur_url); |
| 1519 } | 1420 } |
| 1520 } | 1421 } |
| 1521 | 1422 |
| 1522 void HistoryBackend::ScheduleAutocomplete( | 1423 void HistoryBackend::ScheduleAutocomplete( |
| 1523 const base::Callback<void(HistoryBackend*, URLDatabase*)>& callback) { | 1424 const base::Callback<void(HistoryBackend*, URLDatabase*)>& callback) { |
| 1524 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1525 callback.Run(this, db_.get()); | 1425 callback.Run(this, db_.get()); |
| 1526 } | 1426 } |
| 1527 | 1427 |
| 1528 void HistoryBackend::DeleteFTSIndexDatabases() { | 1428 void HistoryBackend::DeleteFTSIndexDatabases() { |
| 1529 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1530 | |
| 1531 // Find files on disk matching the text databases file pattern so we can | 1429 // Find files on disk matching the text databases file pattern so we can |
| 1532 // quickly test for and delete them. | 1430 // quickly test for and delete them. |
| 1533 base::FilePath::StringType filepattern = FILE_PATH_LITERAL("History Index *"); | 1431 base::FilePath::StringType filepattern = FILE_PATH_LITERAL("History Index *"); |
| 1534 base::FileEnumerator enumerator(history_dir_, false, | 1432 base::FileEnumerator enumerator(history_dir_, false, |
| 1535 base::FileEnumerator::FILES, filepattern); | 1433 base::FileEnumerator::FILES, filepattern); |
| 1536 int num_databases_deleted = 0; | 1434 int num_databases_deleted = 0; |
| 1537 base::FilePath current_file; | 1435 base::FilePath current_file; |
| 1538 while (!(current_file = enumerator.Next()).empty()) { | 1436 while (!(current_file = enumerator.Next()).empty()) { |
| 1539 if (sql::Connection::Delete(current_file)) | 1437 if (sql::Connection::Delete(current_file)) |
| 1540 num_databases_deleted++; | 1438 num_databases_deleted++; |
| 1541 } | 1439 } |
| 1542 UMA_HISTOGRAM_COUNTS("History.DeleteFTSIndexDatabases", | 1440 UMA_HISTOGRAM_COUNTS("History.DeleteFTSIndexDatabases", |
| 1543 num_databases_deleted); | 1441 num_databases_deleted); |
| 1544 } | 1442 } |
| 1545 | 1443 |
| 1546 void HistoryBackend::GetFavicons( | 1444 void HistoryBackend::GetFavicons( |
| 1547 const std::vector<GURL>& icon_urls, | 1445 const std::vector<GURL>& icon_urls, |
| 1548 int icon_types, | 1446 int icon_types, |
| 1549 const std::vector<int>& desired_sizes, | 1447 const std::vector<int>& desired_sizes, |
| 1550 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { | 1448 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { |
| 1551 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1552 UpdateFaviconMappingsAndFetchImpl(nullptr, icon_urls, icon_types, | 1449 UpdateFaviconMappingsAndFetchImpl(nullptr, icon_urls, icon_types, |
| 1553 desired_sizes, bitmap_results); | 1450 desired_sizes, bitmap_results); |
| 1554 } | 1451 } |
| 1555 | 1452 |
| 1556 void HistoryBackend::GetLargestFaviconForURL( | 1453 void HistoryBackend::GetLargestFaviconForURL( |
| 1557 const GURL& page_url, | 1454 const GURL& page_url, |
| 1558 const std::vector<int>& icon_types, | 1455 const std::vector<int>& icon_types, |
| 1559 int minimum_size_in_pixels, | 1456 int minimum_size_in_pixels, |
| 1560 favicon_base::FaviconRawBitmapResult* favicon_bitmap_result) { | 1457 favicon_base::FaviconRawBitmapResult* favicon_bitmap_result) { |
| 1561 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1562 DCHECK(favicon_bitmap_result); | 1458 DCHECK(favicon_bitmap_result); |
| 1563 | 1459 |
| 1564 if (!db_ || !thumbnail_db_) | 1460 if (!db_ || !thumbnail_db_) |
| 1565 return; | 1461 return; |
| 1566 | 1462 |
| 1567 TimeTicks beginning_time = TimeTicks::Now(); | 1463 TimeTicks beginning_time = TimeTicks::Now(); |
| 1568 | 1464 |
| 1569 std::vector<IconMapping> icon_mappings; | 1465 std::vector<IconMapping> icon_mappings; |
| 1570 if (!thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings) || | 1466 if (!thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings) || |
| 1571 icon_mappings.empty()) | 1467 icon_mappings.empty()) |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1648 LOCAL_HISTOGRAM_TIMES("History.GetLargestFaviconForURL", | 1544 LOCAL_HISTOGRAM_TIMES("History.GetLargestFaviconForURL", |
| 1649 TimeTicks::Now() - beginning_time); | 1545 TimeTicks::Now() - beginning_time); |
| 1650 } | 1546 } |
| 1651 | 1547 |
| 1652 void HistoryBackend::GetFaviconsForURL( | 1548 void HistoryBackend::GetFaviconsForURL( |
| 1653 const GURL& page_url, | 1549 const GURL& page_url, |
| 1654 int icon_types, | 1550 int icon_types, |
| 1655 const std::vector<int>& desired_sizes, | 1551 const std::vector<int>& desired_sizes, |
| 1656 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { | 1552 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { |
| 1657 TRACE_EVENT0("browser", "HistoryBackend::GetFaviconsForURL"); | 1553 TRACE_EVENT0("browser", "HistoryBackend::GetFaviconsForURL"); |
| 1658 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1659 DCHECK(bitmap_results); | 1554 DCHECK(bitmap_results); |
| 1660 GetFaviconsFromDB(page_url, icon_types, desired_sizes, bitmap_results); | 1555 GetFaviconsFromDB(page_url, icon_types, desired_sizes, bitmap_results); |
| 1661 | 1556 |
| 1662 if (desired_sizes.size() == 1) | 1557 if (desired_sizes.size() == 1) |
| 1663 bitmap_results->assign(1, favicon_base::ResizeFaviconBitmapResult( | 1558 bitmap_results->assign(1, favicon_base::ResizeFaviconBitmapResult( |
| 1664 *bitmap_results, desired_sizes[0])); | 1559 *bitmap_results, desired_sizes[0])); |
| 1665 } | 1560 } |
| 1666 | 1561 |
| 1667 void HistoryBackend::GetFaviconForID( | 1562 void HistoryBackend::GetFaviconForID( |
| 1668 favicon_base::FaviconID favicon_id, | 1563 favicon_base::FaviconID favicon_id, |
| 1669 int desired_size, | 1564 int desired_size, |
| 1670 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { | 1565 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { |
| 1671 TRACE_EVENT0("browser", "HistoryBackend::GetFaviconForID"); | 1566 TRACE_EVENT0("browser", "HistoryBackend::GetFaviconForID"); |
| 1672 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1673 std::vector<favicon_base::FaviconID> favicon_ids; | 1567 std::vector<favicon_base::FaviconID> favicon_ids; |
| 1674 favicon_ids.push_back(favicon_id); | 1568 favicon_ids.push_back(favicon_id); |
| 1675 std::vector<int> desired_sizes; | 1569 std::vector<int> desired_sizes; |
| 1676 desired_sizes.push_back(desired_size); | 1570 desired_sizes.push_back(desired_size); |
| 1677 | 1571 |
| 1678 // Get results from DB. | 1572 // Get results from DB. |
| 1679 GetFaviconBitmapResultsForBestMatch(favicon_ids, desired_sizes, | 1573 GetFaviconBitmapResultsForBestMatch(favicon_ids, desired_sizes, |
| 1680 bitmap_results); | 1574 bitmap_results); |
| 1681 | 1575 |
| 1682 bitmap_results->assign(1, favicon_base::ResizeFaviconBitmapResult( | 1576 bitmap_results->assign(1, favicon_base::ResizeFaviconBitmapResult( |
| 1683 *bitmap_results, desired_size)); | 1577 *bitmap_results, desired_size)); |
| 1684 } | 1578 } |
| 1685 | 1579 |
| 1686 void HistoryBackend::UpdateFaviconMappingsAndFetch( | 1580 void HistoryBackend::UpdateFaviconMappingsAndFetch( |
| 1687 const GURL& page_url, | 1581 const GURL& page_url, |
| 1688 const std::vector<GURL>& icon_urls, | 1582 const std::vector<GURL>& icon_urls, |
| 1689 int icon_types, | 1583 int icon_types, |
| 1690 const std::vector<int>& desired_sizes, | 1584 const std::vector<int>& desired_sizes, |
| 1691 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { | 1585 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { |
| 1692 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1693 UpdateFaviconMappingsAndFetchImpl(&page_url, icon_urls, icon_types, | 1586 UpdateFaviconMappingsAndFetchImpl(&page_url, icon_urls, icon_types, |
| 1694 desired_sizes, bitmap_results); | 1587 desired_sizes, bitmap_results); |
| 1695 } | 1588 } |
| 1696 | 1589 |
| 1697 void HistoryBackend::MergeFavicon( | 1590 void HistoryBackend::MergeFavicon( |
| 1698 const GURL& page_url, | 1591 const GURL& page_url, |
| 1699 const GURL& icon_url, | 1592 const GURL& icon_url, |
| 1700 favicon_base::IconType icon_type, | 1593 favicon_base::IconType icon_type, |
| 1701 scoped_refptr<base::RefCountedMemory> bitmap_data, | 1594 scoped_refptr<base::RefCountedMemory> bitmap_data, |
| 1702 const gfx::Size& pixel_size) { | 1595 const gfx::Size& pixel_size) { |
| 1703 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1704 | |
| 1705 if (!thumbnail_db_ || !db_) | 1596 if (!thumbnail_db_ || !db_) |
| 1706 return; | 1597 return; |
| 1707 | 1598 |
| 1708 favicon_base::FaviconID favicon_id = | 1599 favicon_base::FaviconID favicon_id = |
| 1709 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); | 1600 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); |
| 1710 | 1601 |
| 1711 bool favicon_created = false; | 1602 bool favicon_created = false; |
| 1712 if (!favicon_id) { | 1603 if (!favicon_id) { |
| 1713 // There is no favicon at |icon_url|, create it. | 1604 // There is no favicon at |icon_url|, create it. |
| 1714 favicon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); | 1605 favicon_id = thumbnail_db_->AddFavicon(icon_url, icon_type); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1851 SendFaviconChangedNotificationForIconURL(icon_url); | 1742 SendFaviconChangedNotificationForIconURL(icon_url); |
| 1852 } | 1743 } |
| 1853 | 1744 |
| 1854 ScheduleCommit(); | 1745 ScheduleCommit(); |
| 1855 } | 1746 } |
| 1856 | 1747 |
| 1857 void HistoryBackend::SetFavicons(const GURL& page_url, | 1748 void HistoryBackend::SetFavicons(const GURL& page_url, |
| 1858 favicon_base::IconType icon_type, | 1749 favicon_base::IconType icon_type, |
| 1859 const GURL& icon_url, | 1750 const GURL& icon_url, |
| 1860 const std::vector<SkBitmap>& bitmaps) { | 1751 const std::vector<SkBitmap>& bitmaps) { |
| 1861 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1862 | |
| 1863 if (!thumbnail_db_ || !db_) | 1752 if (!thumbnail_db_ || !db_) |
| 1864 return; | 1753 return; |
| 1865 | 1754 |
| 1866 DCHECK_GE(kMaxFaviconBitmapsPerIconURL, bitmaps.size()); | 1755 DCHECK_GE(kMaxFaviconBitmapsPerIconURL, bitmaps.size()); |
| 1867 | 1756 |
| 1868 favicon_base::FaviconID icon_id = | 1757 favicon_base::FaviconID icon_id = |
| 1869 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); | 1758 thumbnail_db_->GetFaviconIDForFaviconURL(icon_url, icon_type, nullptr); |
| 1870 | 1759 |
| 1871 bool favicon_created = false; | 1760 bool favicon_created = false; |
| 1872 if (!icon_id) { | 1761 if (!icon_id) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1888 if (favicon_data_modified && !favicon_created) { | 1777 if (favicon_data_modified && !favicon_created) { |
| 1889 // If there was a favicon at |icon_url| prior to SetFavicons() being called, | 1778 // If there was a favicon at |icon_url| prior to SetFavicons() being called, |
| 1890 // there may be page URLs which also use the favicon at |icon_url|. Notify | 1779 // there may be page URLs which also use the favicon at |icon_url|. Notify |
| 1891 // the UI that the favicon has changed for |icon_url|. | 1780 // the UI that the favicon has changed for |icon_url|. |
| 1892 SendFaviconChangedNotificationForIconURL(icon_url); | 1781 SendFaviconChangedNotificationForIconURL(icon_url); |
| 1893 } | 1782 } |
| 1894 ScheduleCommit(); | 1783 ScheduleCommit(); |
| 1895 } | 1784 } |
| 1896 | 1785 |
| 1897 void HistoryBackend::SetFaviconsOutOfDateForPage(const GURL& page_url) { | 1786 void HistoryBackend::SetFaviconsOutOfDateForPage(const GURL& page_url) { |
| 1898 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1899 | |
| 1900 std::vector<IconMapping> icon_mappings; | 1787 std::vector<IconMapping> icon_mappings; |
| 1901 | 1788 |
| 1902 if (!thumbnail_db_ || | 1789 if (!thumbnail_db_ || |
| 1903 !thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) | 1790 !thumbnail_db_->GetIconMappingsForPageURL(page_url, &icon_mappings)) |
| 1904 return; | 1791 return; |
| 1905 | 1792 |
| 1906 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); | 1793 for (std::vector<IconMapping>::iterator m = icon_mappings.begin(); |
| 1907 m != icon_mappings.end(); ++m) { | 1794 m != icon_mappings.end(); ++m) { |
| 1908 thumbnail_db_->SetFaviconOutOfDate(m->icon_id); | 1795 thumbnail_db_->SetFaviconOutOfDate(m->icon_id); |
| 1909 } | 1796 } |
| 1910 ScheduleCommit(); | 1797 ScheduleCommit(); |
| 1911 } | 1798 } |
| 1912 | 1799 |
| 1913 void HistoryBackend::SetImportedFavicons( | 1800 void HistoryBackend::SetImportedFavicons( |
| 1914 const favicon_base::FaviconUsageDataList& favicon_usage) { | 1801 const favicon_base::FaviconUsageDataList& favicon_usage) { |
| 1915 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1916 | |
| 1917 if (!db_ || !thumbnail_db_) | 1802 if (!db_ || !thumbnail_db_) |
| 1918 return; | 1803 return; |
| 1919 | 1804 |
| 1920 Time now = Time::Now(); | 1805 Time now = Time::Now(); |
| 1921 | 1806 |
| 1922 // Track all URLs that had their favicons set or updated. | 1807 // Track all URLs that had their favicons set or updated. |
| 1923 std::set<GURL> favicons_changed; | 1808 std::set<GURL> favicons_changed; |
| 1924 | 1809 |
| 1925 for (size_t i = 0; i < favicon_usage.size(); i++) { | 1810 for (size_t i = 0; i < favicon_usage.size(); i++) { |
| 1926 favicon_base::FaviconID favicon_id = | 1811 favicon_base::FaviconID favicon_id = |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1972 NotifyFaviconsChanged(favicons_changed, GURL()); | 1857 NotifyFaviconsChanged(favicons_changed, GURL()); |
| 1973 } | 1858 } |
| 1974 } | 1859 } |
| 1975 | 1860 |
| 1976 void HistoryBackend::UpdateFaviconMappingsAndFetchImpl( | 1861 void HistoryBackend::UpdateFaviconMappingsAndFetchImpl( |
| 1977 const GURL* page_url, | 1862 const GURL* page_url, |
| 1978 const std::vector<GURL>& icon_urls, | 1863 const std::vector<GURL>& icon_urls, |
| 1979 int icon_types, | 1864 int icon_types, |
| 1980 const std::vector<int>& desired_sizes, | 1865 const std::vector<int>& desired_sizes, |
| 1981 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { | 1866 std::vector<favicon_base::FaviconRawBitmapResult>* bitmap_results) { |
| 1982 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 1983 | |
| 1984 // If |page_url| is specified, |icon_types| must be either a single icon | 1867 // If |page_url| is specified, |icon_types| must be either a single icon |
| 1985 // type or icon types which are equivalent. | 1868 // type or icon types which are equivalent. |
| 1986 DCHECK(!page_url || icon_types == favicon_base::FAVICON || | 1869 DCHECK(!page_url || icon_types == favicon_base::FAVICON || |
| 1987 icon_types == favicon_base::TOUCH_ICON || | 1870 icon_types == favicon_base::TOUCH_ICON || |
| 1988 icon_types == favicon_base::TOUCH_PRECOMPOSED_ICON || | 1871 icon_types == favicon_base::TOUCH_PRECOMPOSED_ICON || |
| 1989 icon_types == | 1872 icon_types == |
| 1990 (favicon_base::TOUCH_ICON | favicon_base::TOUCH_PRECOMPOSED_ICON)); | 1873 (favicon_base::TOUCH_ICON | favicon_base::TOUCH_PRECOMPOSED_ICON)); |
| 1991 bitmap_results->clear(); | 1874 bitmap_results->clear(); |
| 1992 | 1875 |
| 1993 if (!thumbnail_db_) { | 1876 if (!thumbnail_db_) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2028 ScheduleCommit(); | 1911 ScheduleCommit(); |
| 2029 } | 1912 } |
| 2030 } | 1913 } |
| 2031 | 1914 |
| 2032 GetFaviconBitmapResultsForBestMatch(favicon_ids, desired_sizes, | 1915 GetFaviconBitmapResultsForBestMatch(favicon_ids, desired_sizes, |
| 2033 bitmap_results); | 1916 bitmap_results); |
| 2034 } | 1917 } |
| 2035 | 1918 |
| 2036 bool HistoryBackend::SetFaviconBitmaps(favicon_base::FaviconID icon_id, | 1919 bool HistoryBackend::SetFaviconBitmaps(favicon_base::FaviconID icon_id, |
| 2037 const std::vector<SkBitmap>& bitmaps) { | 1920 const std::vector<SkBitmap>& bitmaps) { |
| 2038 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2039 | |
| 2040 std::vector<FaviconBitmapIDSize> bitmap_id_sizes; | 1921 std::vector<FaviconBitmapIDSize> bitmap_id_sizes; |
| 2041 thumbnail_db_->GetFaviconBitmapIDSizes(icon_id, &bitmap_id_sizes); | 1922 thumbnail_db_->GetFaviconBitmapIDSizes(icon_id, &bitmap_id_sizes); |
| 2042 | 1923 |
| 2043 typedef std::pair<scoped_refptr<base::RefCountedBytes>, gfx::Size> | 1924 typedef std::pair<scoped_refptr<base::RefCountedBytes>, gfx::Size> |
| 2044 PNGEncodedBitmap; | 1925 PNGEncodedBitmap; |
| 2045 std::vector<PNGEncodedBitmap> to_add; | 1926 std::vector<PNGEncodedBitmap> to_add; |
| 2046 for (size_t i = 0; i < bitmaps.size(); ++i) { | 1927 for (size_t i = 0; i < bitmaps.size(); ++i) { |
| 2047 scoped_refptr<base::RefCountedBytes> bitmap_data(new base::RefCountedBytes); | 1928 scoped_refptr<base::RefCountedBytes> bitmap_data(new base::RefCountedBytes); |
| 2048 if (!gfx::PNGCodec::EncodeBGRASkBitmap(bitmaps[i], false, | 1929 if (!gfx::PNGCodec::EncodeBGRASkBitmap(bitmaps[i], false, |
| 2049 &bitmap_data->data())) { | 1930 &bitmap_data->data())) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2089 to_add[i].second); | 1970 to_add[i].second); |
| 2090 | 1971 |
| 2091 favicon_bitmaps_changed = true; | 1972 favicon_bitmaps_changed = true; |
| 2092 } | 1973 } |
| 2093 return favicon_bitmaps_changed; | 1974 return favicon_bitmaps_changed; |
| 2094 } | 1975 } |
| 2095 | 1976 |
| 2096 bool HistoryBackend::IsFaviconBitmapDataEqual( | 1977 bool HistoryBackend::IsFaviconBitmapDataEqual( |
| 2097 FaviconBitmapID bitmap_id, | 1978 FaviconBitmapID bitmap_id, |
| 2098 const scoped_refptr<base::RefCountedMemory>& new_bitmap_data) { | 1979 const scoped_refptr<base::RefCountedMemory>& new_bitmap_data) { |
| 2099 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2100 | |
| 2101 if (!new_bitmap_data) | 1980 if (!new_bitmap_data) |
| 2102 return false; | 1981 return false; |
| 2103 | 1982 |
| 2104 scoped_refptr<base::RefCountedMemory> original_bitmap_data; | 1983 scoped_refptr<base::RefCountedMemory> original_bitmap_data; |
| 2105 thumbnail_db_->GetFaviconBitmap(bitmap_id, nullptr, nullptr, | 1984 thumbnail_db_->GetFaviconBitmap(bitmap_id, nullptr, nullptr, |
| 2106 &original_bitmap_data, nullptr); | 1985 &original_bitmap_data, nullptr); |
| 2107 return new_bitmap_data->Equals(original_bitmap_data); | 1986 return new_bitmap_data->Equals(original_bitmap_data); |
| 2108 } | 1987 } |
| 2109 | 1988 |
| 2110 bool HistoryBackend::GetFaviconsFromDB( | 1989 bool HistoryBackend::GetFaviconsFromDB( |
| 2111 const GURL& page_url, | 1990 const GURL& page_url, |
| 2112 int icon_types, | 1991 int icon_types, |
| 2113 const std::vector<int>& desired_sizes, | 1992 const std::vector<int>& desired_sizes, |
| 2114 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) { | 1993 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) { |
| 2115 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2116 DCHECK(favicon_bitmap_results); | 1994 DCHECK(favicon_bitmap_results); |
| 2117 favicon_bitmap_results->clear(); | 1995 favicon_bitmap_results->clear(); |
| 2118 | 1996 |
| 2119 if (!db_ || !thumbnail_db_) | 1997 if (!db_ || !thumbnail_db_) |
| 2120 return false; | 1998 return false; |
| 2121 | 1999 |
| 2122 // Time the query. | 2000 // Time the query. |
| 2123 TimeTicks beginning_time = TimeTicks::Now(); | 2001 TimeTicks beginning_time = TimeTicks::Now(); |
| 2124 | 2002 |
| 2125 // Get FaviconIDs for |page_url| and one of |icon_types|. | 2003 // Get FaviconIDs for |page_url| and one of |icon_types|. |
| 2126 std::vector<IconMapping> icon_mappings; | 2004 std::vector<IconMapping> icon_mappings; |
| 2127 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_types, | 2005 thumbnail_db_->GetIconMappingsForPageURL(page_url, icon_types, |
| 2128 &icon_mappings); | 2006 &icon_mappings); |
| 2129 std::vector<favicon_base::FaviconID> favicon_ids; | 2007 std::vector<favicon_base::FaviconID> favicon_ids; |
| 2130 for (size_t i = 0; i < icon_mappings.size(); ++i) | 2008 for (size_t i = 0; i < icon_mappings.size(); ++i) |
| 2131 favicon_ids.push_back(icon_mappings[i].icon_id); | 2009 favicon_ids.push_back(icon_mappings[i].icon_id); |
| 2132 | 2010 |
| 2133 // Populate |favicon_bitmap_results| and |icon_url_sizes|. | 2011 // Populate |favicon_bitmap_results| and |icon_url_sizes|. |
| 2134 bool success = GetFaviconBitmapResultsForBestMatch(favicon_ids, desired_sizes, | 2012 bool success = GetFaviconBitmapResultsForBestMatch(favicon_ids, desired_sizes, |
| 2135 favicon_bitmap_results); | 2013 favicon_bitmap_results); |
| 2136 UMA_HISTOGRAM_TIMES("History.GetFavIconFromDB", // historical name | 2014 UMA_HISTOGRAM_TIMES("History.GetFavIconFromDB", // historical name |
| 2137 TimeTicks::Now() - beginning_time); | 2015 TimeTicks::Now() - beginning_time); |
| 2138 return success && !favicon_bitmap_results->empty(); | 2016 return success && !favicon_bitmap_results->empty(); |
| 2139 } | 2017 } |
| 2140 | 2018 |
| 2141 bool HistoryBackend::GetFaviconBitmapResultsForBestMatch( | 2019 bool HistoryBackend::GetFaviconBitmapResultsForBestMatch( |
| 2142 const std::vector<favicon_base::FaviconID>& candidate_favicon_ids, | 2020 const std::vector<favicon_base::FaviconID>& candidate_favicon_ids, |
| 2143 const std::vector<int>& desired_sizes, | 2021 const std::vector<int>& desired_sizes, |
| 2144 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) { | 2022 std::vector<favicon_base::FaviconRawBitmapResult>* favicon_bitmap_results) { |
| 2145 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2146 | |
| 2147 favicon_bitmap_results->clear(); | 2023 favicon_bitmap_results->clear(); |
| 2148 | 2024 |
| 2149 if (candidate_favicon_ids.empty()) | 2025 if (candidate_favicon_ids.empty()) |
| 2150 return true; | 2026 return true; |
| 2151 | 2027 |
| 2152 // Find the FaviconID and the FaviconBitmapIDs which best match | 2028 // Find the FaviconID and the FaviconBitmapIDs which best match |
| 2153 // |desired_size_in_dip| and |desired_scale_factors|. | 2029 // |desired_size_in_dip| and |desired_scale_factors|. |
| 2154 // TODO(pkotwicz): Select bitmap results from multiple favicons once | 2030 // TODO(pkotwicz): Select bitmap results from multiple favicons once |
| 2155 // content::FaviconStatus supports multiple icon URLs. | 2031 // content::FaviconStatus supports multiple icon URLs. |
| 2156 favicon_base::FaviconID best_favicon_id = 0; | 2032 favicon_base::FaviconID best_favicon_id = 0; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2205 if (bitmap_result.is_valid()) | 2081 if (bitmap_result.is_valid()) |
| 2206 favicon_bitmap_results->push_back(bitmap_result); | 2082 favicon_bitmap_results->push_back(bitmap_result); |
| 2207 } | 2083 } |
| 2208 return true; | 2084 return true; |
| 2209 } | 2085 } |
| 2210 | 2086 |
| 2211 bool HistoryBackend::SetFaviconMappingsForPageAndRedirects( | 2087 bool HistoryBackend::SetFaviconMappingsForPageAndRedirects( |
| 2212 const GURL& page_url, | 2088 const GURL& page_url, |
| 2213 favicon_base::IconType icon_type, | 2089 favicon_base::IconType icon_type, |
| 2214 const std::vector<favicon_base::FaviconID>& icon_ids) { | 2090 const std::vector<favicon_base::FaviconID>& icon_ids) { |
| 2215 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2216 | |
| 2217 if (!thumbnail_db_) | 2091 if (!thumbnail_db_) |
| 2218 return false; | 2092 return false; |
| 2219 | 2093 |
| 2220 // Find all the pages whose favicons we should set, we want to set it for | 2094 // Find all the pages whose favicons we should set, we want to set it for |
| 2221 // all the pages in the redirect chain if it redirected. | 2095 // all the pages in the redirect chain if it redirected. |
| 2222 RedirectList redirects; | 2096 RedirectList redirects; |
| 2223 GetCachedRecentRedirects(page_url, &redirects); | 2097 GetCachedRecentRedirects(page_url, &redirects); |
| 2224 bool mappings_changed = SetFaviconMappingsForPages(redirects, icon_type, | 2098 bool mappings_changed = SetFaviconMappingsForPages(redirects, icon_type, |
| 2225 icon_ids); | 2099 icon_ids); |
| 2226 if (page_url.has_ref()) { | 2100 if (page_url.has_ref()) { |
| 2227 // Refs often gets added by Javascript, but the redirect chain is keyed to | 2101 // Refs often gets added by Javascript, but the redirect chain is keyed to |
| 2228 // the URL without a ref. | 2102 // the URL without a ref. |
| 2229 GURL::Replacements replacements; | 2103 GURL::Replacements replacements; |
| 2230 replacements.ClearRef(); | 2104 replacements.ClearRef(); |
| 2231 GURL page_url_without_ref = page_url.ReplaceComponents(replacements); | 2105 GURL page_url_without_ref = page_url.ReplaceComponents(replacements); |
| 2232 GetCachedRecentRedirects(page_url_without_ref, &redirects); | 2106 GetCachedRecentRedirects(page_url_without_ref, &redirects); |
| 2233 mappings_changed |= SetFaviconMappingsForPages(redirects, icon_type, | 2107 mappings_changed |= SetFaviconMappingsForPages(redirects, icon_type, |
| 2234 icon_ids); | 2108 icon_ids); |
| 2235 } | 2109 } |
| 2236 | 2110 |
| 2237 return mappings_changed; | 2111 return mappings_changed; |
| 2238 } | 2112 } |
| 2239 | 2113 |
| 2240 bool HistoryBackend::SetFaviconMappingsForPages( | 2114 bool HistoryBackend::SetFaviconMappingsForPages( |
| 2241 const std::vector<GURL>& page_urls, | 2115 const std::vector<GURL>& page_urls, |
| 2242 favicon_base::IconType icon_type, | 2116 favicon_base::IconType icon_type, |
| 2243 const std::vector<favicon_base::FaviconID>& icon_ids) { | 2117 const std::vector<favicon_base::FaviconID>& icon_ids) { |
| 2244 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2245 | |
| 2246 bool mappings_changed = false; | 2118 bool mappings_changed = false; |
| 2247 for (auto i(page_urls.begin()); i != page_urls.end(); ++i) { | 2119 for (auto i(page_urls.begin()); i != page_urls.end(); ++i) { |
| 2248 mappings_changed |= SetFaviconMappingsForPage(*i, icon_type, icon_ids); | 2120 mappings_changed |= SetFaviconMappingsForPage(*i, icon_type, icon_ids); |
| 2249 } | 2121 } |
| 2250 return mappings_changed; | 2122 return mappings_changed; |
| 2251 } | 2123 } |
| 2252 | 2124 |
| 2253 bool HistoryBackend::SetFaviconMappingsForPage( | 2125 bool HistoryBackend::SetFaviconMappingsForPage( |
| 2254 const GURL& page_url, | 2126 const GURL& page_url, |
| 2255 favicon_base::IconType icon_type, | 2127 favicon_base::IconType icon_type, |
| 2256 const std::vector<favicon_base::FaviconID>& icon_ids) { | 2128 const std::vector<favicon_base::FaviconID>& icon_ids) { |
| 2257 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2258 | |
| 2259 DCHECK_LE(icon_ids.size(), kMaxFaviconsPerPage); | 2129 DCHECK_LE(icon_ids.size(), kMaxFaviconsPerPage); |
| 2260 bool mappings_changed = false; | 2130 bool mappings_changed = false; |
| 2261 | 2131 |
| 2262 // Two icon types are considered 'equivalent' if one of the icon types is | 2132 // Two icon types are considered 'equivalent' if one of the icon types is |
| 2263 // TOUCH_ICON and the other is TOUCH_PRECOMPOSED_ICON. | 2133 // TOUCH_ICON and the other is TOUCH_PRECOMPOSED_ICON. |
| 2264 // | 2134 // |
| 2265 // Sets the icon mappings from |page_url| for |icon_type| to the favicons | 2135 // Sets the icon mappings from |page_url| for |icon_type| to the favicons |
| 2266 // with |icon_ids|. Mappings for |page_url| to favicons of type |icon_type| | 2136 // with |icon_ids|. Mappings for |page_url| to favicons of type |icon_type| |
| 2267 // whose FaviconID is not in |icon_ids| are removed. All icon mappings for | 2137 // whose FaviconID is not in |icon_ids| are removed. All icon mappings for |
| 2268 // |page_url| to favicons of a type equivalent to |icon_type| are removed. | 2138 // |page_url| to favicons of a type equivalent to |icon_type| are removed. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2304 | 2174 |
| 2305 for (size_t i = 0; i < unmapped_icon_ids.size(); ++i) { | 2175 for (size_t i = 0; i < unmapped_icon_ids.size(); ++i) { |
| 2306 thumbnail_db_->AddIconMapping(page_url, unmapped_icon_ids[i]); | 2176 thumbnail_db_->AddIconMapping(page_url, unmapped_icon_ids[i]); |
| 2307 mappings_changed = true; | 2177 mappings_changed = true; |
| 2308 } | 2178 } |
| 2309 return mappings_changed; | 2179 return mappings_changed; |
| 2310 } | 2180 } |
| 2311 | 2181 |
| 2312 void HistoryBackend::GetCachedRecentRedirects(const GURL& page_url, | 2182 void HistoryBackend::GetCachedRecentRedirects(const GURL& page_url, |
| 2313 RedirectList* redirect_list) { | 2183 RedirectList* redirect_list) { |
| 2314 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2315 | |
| 2316 RedirectCache::iterator iter = recent_redirects_.Get(page_url); | 2184 RedirectCache::iterator iter = recent_redirects_.Get(page_url); |
| 2317 if (iter != recent_redirects_.end()) { | 2185 if (iter != recent_redirects_.end()) { |
| 2318 *redirect_list = iter->second; | 2186 *redirect_list = iter->second; |
| 2319 | 2187 |
| 2320 // The redirect chain should have the destination URL as the last item. | 2188 // The redirect chain should have the destination URL as the last item. |
| 2321 DCHECK(!redirect_list->empty()); | 2189 DCHECK(!redirect_list->empty()); |
| 2322 DCHECK_EQ(redirect_list->back(), page_url); | 2190 DCHECK_EQ(redirect_list->back(), page_url); |
| 2323 } else { | 2191 } else { |
| 2324 // No known redirects, construct mock redirect chain containing |page_url|. | 2192 // No known redirects, construct mock redirect chain containing |page_url|. |
| 2325 redirect_list->push_back(page_url); | 2193 redirect_list->push_back(page_url); |
| 2326 } | 2194 } |
| 2327 } | 2195 } |
| 2328 | 2196 |
| 2329 void HistoryBackend::SendFaviconChangedNotificationForPageAndRedirects( | 2197 void HistoryBackend::SendFaviconChangedNotificationForPageAndRedirects( |
| 2330 const GURL& page_url) { | 2198 const GURL& page_url) { |
| 2331 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2332 | |
| 2333 RedirectList redirect_list; | 2199 RedirectList redirect_list; |
| 2334 GetCachedRecentRedirects(page_url, &redirect_list); | 2200 GetCachedRecentRedirects(page_url, &redirect_list); |
| 2335 if (!redirect_list.empty()) { | 2201 if (!redirect_list.empty()) { |
| 2336 std::set<GURL> favicons_changed(redirect_list.begin(), | 2202 std::set<GURL> favicons_changed(redirect_list.begin(), |
| 2337 redirect_list.end()); | 2203 redirect_list.end()); |
| 2338 NotifyFaviconsChanged(favicons_changed, GURL()); | 2204 NotifyFaviconsChanged(favicons_changed, GURL()); |
| 2339 } | 2205 } |
| 2340 } | 2206 } |
| 2341 | 2207 |
| 2342 void HistoryBackend::SendFaviconChangedNotificationForIconURL( | 2208 void HistoryBackend::SendFaviconChangedNotificationForIconURL( |
| 2343 const GURL& icon_url) { | 2209 const GURL& icon_url) { |
| 2344 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2345 NotifyFaviconsChanged(std::set<GURL>(), icon_url); | 2210 NotifyFaviconsChanged(std::set<GURL>(), icon_url); |
| 2346 } | 2211 } |
| 2347 | 2212 |
| 2348 void HistoryBackend::Commit() { | 2213 void HistoryBackend::Commit() { |
| 2349 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2350 | |
| 2351 if (!db_) | 2214 if (!db_) |
| 2352 return; | 2215 return; |
| 2353 | 2216 |
| 2354 #if defined(OS_IOS) | 2217 #if defined(OS_IOS) |
| 2355 // Attempts to get the application running long enough to commit the database | 2218 // Attempts to get the application running long enough to commit the database |
| 2356 // transaction if it is currently being backgrounded. | 2219 // transaction if it is currently being backgrounded. |
| 2357 base::ios::ScopedCriticalAction scoped_critical_action; | 2220 base::ios::ScopedCriticalAction scoped_critical_action; |
| 2358 #endif | 2221 #endif |
| 2359 | 2222 |
| 2360 // Note that a commit may not actually have been scheduled if a caller | 2223 // Note that a commit may not actually have been scheduled if a caller |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2372 | 2235 |
| 2373 if (thumbnail_db_) { | 2236 if (thumbnail_db_) { |
| 2374 thumbnail_db_->CommitTransaction(); | 2237 thumbnail_db_->CommitTransaction(); |
| 2375 DCHECK_EQ(thumbnail_db_->transaction_nesting(), 0) | 2238 DCHECK_EQ(thumbnail_db_->transaction_nesting(), 0) |
| 2376 << "Somebody left a transaction open"; | 2239 << "Somebody left a transaction open"; |
| 2377 thumbnail_db_->BeginTransaction(); | 2240 thumbnail_db_->BeginTransaction(); |
| 2378 } | 2241 } |
| 2379 } | 2242 } |
| 2380 | 2243 |
| 2381 void HistoryBackend::ScheduleCommit() { | 2244 void HistoryBackend::ScheduleCommit() { |
| 2382 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2383 | |
| 2384 if (scheduled_commit_) | 2245 if (scheduled_commit_) |
| 2385 return; | 2246 return; |
| 2386 scheduled_commit_ = new CommitLaterTask(this); | 2247 scheduled_commit_ = new CommitLaterTask(this); |
| 2387 task_runner_->PostDelayedTask( | 2248 task_runner_->PostDelayedTask( |
| 2388 FROM_HERE, | 2249 FROM_HERE, |
| 2389 base::Bind(&CommitLaterTask::RunCommit, scheduled_commit_), | 2250 base::Bind(&CommitLaterTask::RunCommit, scheduled_commit_), |
| 2390 base::TimeDelta::FromSeconds(kCommitIntervalSeconds)); | 2251 base::TimeDelta::FromSeconds(kCommitIntervalSeconds)); |
| 2391 } | 2252 } |
| 2392 | 2253 |
| 2393 void HistoryBackend::CancelScheduledCommit() { | 2254 void HistoryBackend::CancelScheduledCommit() { |
| 2394 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2395 | |
| 2396 if (scheduled_commit_) { | 2255 if (scheduled_commit_) { |
| 2397 scheduled_commit_->Cancel(); | 2256 scheduled_commit_->Cancel(); |
| 2398 scheduled_commit_ = nullptr; | 2257 scheduled_commit_ = nullptr; |
| 2399 } | 2258 } |
| 2400 } | 2259 } |
| 2401 | 2260 |
| 2402 void HistoryBackend::ProcessDBTaskImpl() { | 2261 void HistoryBackend::ProcessDBTaskImpl() { |
| 2403 if (!db_) { | 2262 if (!db_) { |
| 2404 // db went away, release all the refs. | 2263 // db went away, release all the refs. |
| 2405 queued_history_db_tasks_.clear(); | 2264 queued_history_db_tasks_.clear(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2433 } | 2292 } |
| 2434 } | 2293 } |
| 2435 | 2294 |
| 2436 //////////////////////////////////////////////////////////////////////////////// | 2295 //////////////////////////////////////////////////////////////////////////////// |
| 2437 // | 2296 // |
| 2438 // Generic operations | 2297 // Generic operations |
| 2439 // | 2298 // |
| 2440 //////////////////////////////////////////////////////////////////////////////// | 2299 //////////////////////////////////////////////////////////////////////////////// |
| 2441 | 2300 |
| 2442 void HistoryBackend::DeleteURLs(const std::vector<GURL>& urls) { | 2301 void HistoryBackend::DeleteURLs(const std::vector<GURL>& urls) { |
| 2443 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2444 | |
| 2445 expirer_.DeleteURLs(urls); | 2302 expirer_.DeleteURLs(urls); |
| 2446 | 2303 |
| 2447 db_->GetStartDate(&first_recorded_time_); | 2304 db_->GetStartDate(&first_recorded_time_); |
| 2448 // Force a commit, if the user is deleting something for privacy reasons, we | 2305 // Force a commit, if the user is deleting something for privacy reasons, we |
| 2449 // want to get it on disk ASAP. | 2306 // want to get it on disk ASAP. |
| 2450 Commit(); | 2307 Commit(); |
| 2451 } | 2308 } |
| 2452 | 2309 |
| 2453 void HistoryBackend::DeleteURL(const GURL& url) { | 2310 void HistoryBackend::DeleteURL(const GURL& url) { |
| 2454 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2455 | |
| 2456 expirer_.DeleteURL(url); | 2311 expirer_.DeleteURL(url); |
| 2457 | 2312 |
| 2458 db_->GetStartDate(&first_recorded_time_); | 2313 db_->GetStartDate(&first_recorded_time_); |
| 2459 // Force a commit, if the user is deleting something for privacy reasons, we | 2314 // Force a commit, if the user is deleting something for privacy reasons, we |
| 2460 // want to get it on disk ASAP. | 2315 // want to get it on disk ASAP. |
| 2461 Commit(); | 2316 Commit(); |
| 2462 } | 2317 } |
| 2463 | 2318 |
| 2464 void HistoryBackend::ExpireHistoryBetween(const std::set<GURL>& restrict_urls, | 2319 void HistoryBackend::ExpireHistoryBetween(const std::set<GURL>& restrict_urls, |
| 2465 Time begin_time, | 2320 Time begin_time, |
| 2466 Time end_time) { | 2321 Time end_time) { |
| 2467 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2468 | |
| 2469 if (!db_) | 2322 if (!db_) |
| 2470 return; | 2323 return; |
| 2471 | 2324 |
| 2472 if (begin_time.is_null() && (end_time.is_null() || end_time.is_max()) && | 2325 if (begin_time.is_null() && (end_time.is_null() || end_time.is_max()) && |
| 2473 restrict_urls.empty()) { | 2326 restrict_urls.empty()) { |
| 2474 // Special case deleting all history so it can be faster and to reduce the | 2327 // Special case deleting all history so it can be faster and to reduce the |
| 2475 // possibility of an information leak. | 2328 // possibility of an information leak. |
| 2476 DeleteAllHistory(); | 2329 DeleteAllHistory(); |
| 2477 } else { | 2330 } else { |
| 2478 // Clearing parts of history, have the expirer do the depend | 2331 // Clearing parts of history, have the expirer do the depend |
| 2479 expirer_.ExpireHistoryBetween(restrict_urls, begin_time, end_time); | 2332 expirer_.ExpireHistoryBetween(restrict_urls, begin_time, end_time); |
| 2480 | 2333 |
| 2481 // Force a commit, if the user is deleting something for privacy reasons, | 2334 // Force a commit, if the user is deleting something for privacy reasons, |
| 2482 // we want to get it on disk ASAP. | 2335 // we want to get it on disk ASAP. |
| 2483 Commit(); | 2336 Commit(); |
| 2484 } | 2337 } |
| 2485 | 2338 |
| 2486 if (begin_time <= first_recorded_time_) | 2339 if (begin_time <= first_recorded_time_) |
| 2487 db_->GetStartDate(&first_recorded_time_); | 2340 db_->GetStartDate(&first_recorded_time_); |
| 2488 } | 2341 } |
| 2489 | 2342 |
| 2490 void HistoryBackend::ExpireHistoryForTimes(const std::set<base::Time>& times, | 2343 void HistoryBackend::ExpireHistoryForTimes(const std::set<base::Time>& times, |
| 2491 base::Time begin_time, | 2344 base::Time begin_time, |
| 2492 base::Time end_time) { | 2345 base::Time end_time) { |
| 2493 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2494 | |
| 2495 if (times.empty() || !db_) | 2346 if (times.empty() || !db_) |
| 2496 return; | 2347 return; |
| 2497 | 2348 |
| 2498 QueryOptions options; | 2349 QueryOptions options; |
| 2499 options.begin_time = begin_time; | 2350 options.begin_time = begin_time; |
| 2500 options.end_time = end_time; | 2351 options.end_time = end_time; |
| 2501 options.duplicate_policy = QueryOptions::KEEP_ALL_DUPLICATES; | 2352 options.duplicate_policy = QueryOptions::KEEP_ALL_DUPLICATES; |
| 2502 QueryResults results; | 2353 QueryResults results; |
| 2503 QueryHistoryBasic(options, &results); | 2354 QueryHistoryBasic(options, &results); |
| 2504 | 2355 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2532 Commit(); | 2383 Commit(); |
| 2533 | 2384 |
| 2534 DCHECK_GE(times_to_expire.back(), first_recorded_time_); | 2385 DCHECK_GE(times_to_expire.back(), first_recorded_time_); |
| 2535 // Update |first_recorded_time_| if we expired it. | 2386 // Update |first_recorded_time_| if we expired it. |
| 2536 if (times_to_expire.back() == first_recorded_time_) | 2387 if (times_to_expire.back() == first_recorded_time_) |
| 2537 db_->GetStartDate(&first_recorded_time_); | 2388 db_->GetStartDate(&first_recorded_time_); |
| 2538 } | 2389 } |
| 2539 | 2390 |
| 2540 void HistoryBackend::ExpireHistory( | 2391 void HistoryBackend::ExpireHistory( |
| 2541 const std::vector<ExpireHistoryArgs>& expire_list) { | 2392 const std::vector<ExpireHistoryArgs>& expire_list) { |
| 2542 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2543 | |
| 2544 if (db_) { | 2393 if (db_) { |
| 2545 bool update_first_recorded_time = false; | 2394 bool update_first_recorded_time = false; |
| 2546 | 2395 |
| 2547 for (std::vector<ExpireHistoryArgs>::const_iterator it = | 2396 for (std::vector<ExpireHistoryArgs>::const_iterator it = |
| 2548 expire_list.begin(); | 2397 expire_list.begin(); |
| 2549 it != expire_list.end(); ++it) { | 2398 it != expire_list.end(); ++it) { |
| 2550 expirer_.ExpireHistoryBetween(it->urls, it->begin_time, it->end_time); | 2399 expirer_.ExpireHistoryBetween(it->urls, it->begin_time, it->end_time); |
| 2551 | 2400 |
| 2552 if (it->begin_time < first_recorded_time_) | 2401 if (it->begin_time < first_recorded_time_) |
| 2553 update_first_recorded_time = true; | 2402 update_first_recorded_time = true; |
| 2554 } | 2403 } |
| 2555 Commit(); | 2404 Commit(); |
| 2556 | 2405 |
| 2557 // Update |first_recorded_time_| if any deletion might have affected it. | 2406 // Update |first_recorded_time_| if any deletion might have affected it. |
| 2558 if (update_first_recorded_time) | 2407 if (update_first_recorded_time) |
| 2559 db_->GetStartDate(&first_recorded_time_); | 2408 db_->GetStartDate(&first_recorded_time_); |
| 2560 } | 2409 } |
| 2561 } | 2410 } |
| 2562 | 2411 |
| 2563 void HistoryBackend::URLsNoLongerBookmarked(const std::set<GURL>& urls) { | 2412 void HistoryBackend::URLsNoLongerBookmarked(const std::set<GURL>& urls) { |
| 2564 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2565 | |
| 2566 if (!db_) | 2413 if (!db_) |
| 2567 return; | 2414 return; |
| 2568 | 2415 |
| 2569 for (std::set<GURL>::const_iterator i = urls.begin(); i != urls.end(); ++i) { | 2416 for (std::set<GURL>::const_iterator i = urls.begin(); i != urls.end(); ++i) { |
| 2570 VisitVector visits; | 2417 VisitVector visits; |
| 2571 URLRow url_row; | 2418 URLRow url_row; |
| 2572 if (db_->GetRowForURL(*i, &url_row)) | 2419 if (db_->GetRowForURL(*i, &url_row)) |
| 2573 db_->GetVisitsForURL(url_row.id(), &visits); | 2420 db_->GetVisitsForURL(url_row.id(), &visits); |
| 2574 // We need to call DeleteURL() even if the DB didn't contain this URL, so | 2421 // We need to call DeleteURL() even if the DB didn't contain this URL, so |
| 2575 // that we can delete all associated icons in the case of deleting an | 2422 // that we can delete all associated icons in the case of deleting an |
| 2576 // unvisited bookmarked URL. | 2423 // unvisited bookmarked URL. |
| 2577 if (visits.empty()) | 2424 if (visits.empty()) |
| 2578 expirer_.DeleteURL(*i); // There are no more visits; nuke the URL. | 2425 expirer_.DeleteURL(*i); // There are no more visits; nuke the URL. |
| 2579 } | 2426 } |
| 2580 } | 2427 } |
| 2581 | 2428 |
| 2582 void HistoryBackend::DatabaseErrorCallback(int error, sql::Statement* stmt) { | 2429 void HistoryBackend::DatabaseErrorCallback(int error, sql::Statement* stmt) { |
| 2583 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2584 | |
| 2585 if (!scheduled_kill_db_ && sql::IsErrorCatastrophic(error)) { | 2430 if (!scheduled_kill_db_ && sql::IsErrorCatastrophic(error)) { |
| 2586 scheduled_kill_db_ = true; | 2431 scheduled_kill_db_ = true; |
| 2587 | 2432 |
| 2588 db_diagnostics_ = db_->GetDiagnosticInfo(error, stmt); | 2433 db_diagnostics_ = db_->GetDiagnosticInfo(error, stmt); |
| 2589 | 2434 |
| 2590 // Don't just do the close/delete here, as we are being called by |db| and | 2435 // Don't just do the close/delete here, as we are being called by |db| and |
| 2591 // that seems dangerous. | 2436 // that seems dangerous. |
| 2592 // TODO(shess): Consider changing KillHistoryDatabase() to use | 2437 // TODO(shess): Consider changing KillHistoryDatabase() to use |
| 2593 // RazeAndClose(). Then it can be cleared immediately. | 2438 // RazeAndClose(). Then it can be cleared immediately. |
| 2594 task_runner_->PostTask( | 2439 task_runner_->PostTask( |
| 2595 FROM_HERE, base::Bind(&HistoryBackend::KillHistoryDatabase, this)); | 2440 FROM_HERE, base::Bind(&HistoryBackend::KillHistoryDatabase, this)); |
| 2596 } | 2441 } |
| 2597 } | 2442 } |
| 2598 | 2443 |
| 2599 void HistoryBackend::KillHistoryDatabase() { | 2444 void HistoryBackend::KillHistoryDatabase() { |
| 2600 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2601 | |
| 2602 scheduled_kill_db_ = false; | 2445 scheduled_kill_db_ = false; |
| 2603 if (!db_) | 2446 if (!db_) |
| 2604 return; | 2447 return; |
| 2605 | 2448 |
| 2606 // Rollback transaction because Raze() cannot be called from within a | 2449 // Rollback transaction because Raze() cannot be called from within a |
| 2607 // transaction. | 2450 // transaction. |
| 2608 db_->RollbackTransaction(); | 2451 db_->RollbackTransaction(); |
| 2609 bool success = db_->Raze(); | 2452 bool success = db_->Raze(); |
| 2610 UMA_HISTOGRAM_BOOLEAN("History.KillHistoryDatabaseResult", success); | 2453 UMA_HISTOGRAM_BOOLEAN("History.KillHistoryDatabaseResult", success); |
| 2611 | 2454 |
| 2612 // Release stashed embedder object before cleaning up the databases. | 2455 // Release stashed embedder object before cleaning up the databases. |
| 2613 supports_user_data_helper_.reset(); | 2456 supports_user_data_helper_.reset(); |
| 2614 | 2457 |
| 2615 // The expirer keeps tabs on the active databases. Tell it about the | 2458 // The expirer keeps tabs on the active databases. Tell it about the |
| 2616 // databases which will be closed. | 2459 // databases which will be closed. |
| 2617 expirer_.SetDatabases(nullptr, nullptr); | 2460 expirer_.SetDatabases(nullptr, nullptr); |
| 2618 | 2461 |
| 2619 // Reopen a new transaction for |db_| for the sake of CloseAllDatabases(). | 2462 // Reopen a new transaction for |db_| for the sake of CloseAllDatabases(). |
| 2620 db_->BeginTransaction(); | 2463 db_->BeginTransaction(); |
| 2621 CloseAllDatabases(); | 2464 CloseAllDatabases(); |
| 2622 } | 2465 } |
| 2623 | 2466 |
| 2624 base::SupportsUserData::Data* HistoryBackend::GetUserData( | 2467 base::SupportsUserData::Data* HistoryBackend::GetUserData( |
| 2625 const void* key) const { | 2468 const void* key) const { |
| 2626 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2627 DCHECK(supports_user_data_helper_); | 2469 DCHECK(supports_user_data_helper_); |
| 2628 return supports_user_data_helper_->GetUserData(key); | 2470 return supports_user_data_helper_->GetUserData(key); |
| 2629 } | 2471 } |
| 2630 | 2472 |
| 2631 void HistoryBackend::SetUserData(const void* key, | 2473 void HistoryBackend::SetUserData(const void* key, |
| 2632 base::SupportsUserData::Data* data) { | 2474 base::SupportsUserData::Data* data) { |
| 2633 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2634 DCHECK(supports_user_data_helper_); | 2475 DCHECK(supports_user_data_helper_); |
| 2635 supports_user_data_helper_->SetUserData(key, data); | 2476 supports_user_data_helper_->SetUserData(key, data); |
| 2636 } | 2477 } |
| 2637 | 2478 |
| 2638 void HistoryBackend::ProcessDBTask( | 2479 void HistoryBackend::ProcessDBTask( |
| 2639 std::unique_ptr<HistoryDBTask> task, | 2480 std::unique_ptr<HistoryDBTask> task, |
| 2640 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, | 2481 scoped_refptr<base::SingleThreadTaskRunner> origin_loop, |
| 2641 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) { | 2482 const base::CancelableTaskTracker::IsCanceledCallback& is_canceled) { |
| 2642 bool scheduled = !queued_history_db_tasks_.empty(); | 2483 bool scheduled = !queued_history_db_tasks_.empty(); |
| 2643 queued_history_db_tasks_.push_back(base::MakeUnique<QueuedHistoryDBTask>( | 2484 queued_history_db_tasks_.push_back(base::MakeUnique<QueuedHistoryDBTask>( |
| 2644 std::move(task), origin_loop, is_canceled)); | 2485 std::move(task), origin_loop, is_canceled)); |
| 2645 if (!scheduled) | 2486 if (!scheduled) |
| 2646 ProcessDBTaskImpl(); | 2487 ProcessDBTaskImpl(); |
| 2647 } | 2488 } |
| 2648 | 2489 |
| 2649 void HistoryBackend::NotifyFaviconsChanged(const std::set<GURL>& page_urls, | 2490 void HistoryBackend::NotifyFaviconsChanged(const std::set<GURL>& page_urls, |
| 2650 const GURL& icon_url) { | 2491 const GURL& icon_url) { |
| 2651 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2652 | |
| 2653 if (delegate_) | 2492 if (delegate_) |
| 2654 delegate_->NotifyFaviconsChanged(page_urls, icon_url); | 2493 delegate_->NotifyFaviconsChanged(page_urls, icon_url); |
| 2655 } | 2494 } |
| 2656 | 2495 |
| 2657 void HistoryBackend::NotifyURLVisited(ui::PageTransition transition, | 2496 void HistoryBackend::NotifyURLVisited(ui::PageTransition transition, |
| 2658 const URLRow& row, | 2497 const URLRow& row, |
| 2659 const RedirectList& redirects, | 2498 const RedirectList& redirects, |
| 2660 base::Time visit_time) { | 2499 base::Time visit_time) { |
| 2661 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2662 | |
| 2663 for (HistoryBackendObserver& observer : observers_) | 2500 for (HistoryBackendObserver& observer : observers_) |
| 2664 observer.OnURLVisited(this, transition, row, redirects, visit_time); | 2501 observer.OnURLVisited(this, transition, row, redirects, visit_time); |
| 2665 | 2502 |
| 2666 if (delegate_) | 2503 if (delegate_) |
| 2667 delegate_->NotifyURLVisited(transition, row, redirects, visit_time); | 2504 delegate_->NotifyURLVisited(transition, row, redirects, visit_time); |
| 2668 } | 2505 } |
| 2669 | 2506 |
| 2670 void HistoryBackend::NotifyURLsModified(const URLRows& rows) { | 2507 void HistoryBackend::NotifyURLsModified(const URLRows& rows) { |
| 2671 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2672 | |
| 2673 for (HistoryBackendObserver& observer : observers_) | 2508 for (HistoryBackendObserver& observer : observers_) |
| 2674 observer.OnURLsModified(this, rows); | 2509 observer.OnURLsModified(this, rows); |
| 2675 | 2510 |
| 2676 if (delegate_) | 2511 if (delegate_) |
| 2677 delegate_->NotifyURLsModified(rows); | 2512 delegate_->NotifyURLsModified(rows); |
| 2678 } | 2513 } |
| 2679 | 2514 |
| 2680 void HistoryBackend::NotifyURLsDeleted(bool all_history, | 2515 void HistoryBackend::NotifyURLsDeleted(bool all_history, |
| 2681 bool expired, | 2516 bool expired, |
| 2682 const URLRows& rows, | 2517 const URLRows& rows, |
| 2683 const std::set<GURL>& favicon_urls) { | 2518 const std::set<GURL>& favicon_urls) { |
| 2684 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2685 | |
| 2686 URLRows copied_rows(rows); | 2519 URLRows copied_rows(rows); |
| 2687 for (HistoryBackendObserver& observer : observers_) { | 2520 for (HistoryBackendObserver& observer : observers_) { |
| 2688 observer.OnURLsDeleted(this, all_history, expired, copied_rows, | 2521 observer.OnURLsDeleted(this, all_history, expired, copied_rows, |
| 2689 favicon_urls); | 2522 favicon_urls); |
| 2690 } | 2523 } |
| 2691 | 2524 |
| 2692 if (delegate_) | 2525 if (delegate_) |
| 2693 delegate_->NotifyURLsDeleted(all_history, expired, copied_rows, | 2526 delegate_->NotifyURLsDeleted(all_history, expired, copied_rows, |
| 2694 favicon_urls); | 2527 favicon_urls); |
| 2695 } | 2528 } |
| 2696 | 2529 |
| 2697 // Deleting -------------------------------------------------------------------- | 2530 // Deleting -------------------------------------------------------------------- |
| 2698 | 2531 |
| 2699 void HistoryBackend::DeleteAllHistory() { | 2532 void HistoryBackend::DeleteAllHistory() { |
| 2700 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2701 | |
| 2702 // Our approach to deleting all history is: | 2533 // Our approach to deleting all history is: |
| 2703 // 1. Copy the bookmarks and their dependencies to new tables with temporary | 2534 // 1. Copy the bookmarks and their dependencies to new tables with temporary |
| 2704 // names. | 2535 // names. |
| 2705 // 2. Delete the original tables. Since tables can not share pages, we know | 2536 // 2. Delete the original tables. Since tables can not share pages, we know |
| 2706 // that any data we don't want to keep is now in an unused page. | 2537 // that any data we don't want to keep is now in an unused page. |
| 2707 // 3. Renaming the temporary tables to match the original. | 2538 // 3. Renaming the temporary tables to match the original. |
| 2708 // 4. Vacuuming the database to delete the unused pages. | 2539 // 4. Vacuuming the database to delete the unused pages. |
| 2709 // | 2540 // |
| 2710 // Since we are likely to have very few bookmarks and their dependencies | 2541 // Since we are likely to have very few bookmarks and their dependencies |
| 2711 // compared to all history, this is also much faster than just deleting from | 2542 // compared to all history, this is also much faster than just deleting from |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2748 | 2579 |
| 2749 db_->GetStartDate(&first_recorded_time_); | 2580 db_->GetStartDate(&first_recorded_time_); |
| 2750 | 2581 |
| 2751 // Send out the notification that history is cleared. The in-memory database | 2582 // Send out the notification that history is cleared. The in-memory database |
| 2752 // will pick this up and clear itself. | 2583 // will pick this up and clear itself. |
| 2753 NotifyURLsDeleted(true, false, URLRows(), std::set<GURL>()); | 2584 NotifyURLsDeleted(true, false, URLRows(), std::set<GURL>()); |
| 2754 } | 2585 } |
| 2755 | 2586 |
| 2756 bool HistoryBackend::ClearAllThumbnailHistory( | 2587 bool HistoryBackend::ClearAllThumbnailHistory( |
| 2757 const std::vector<GURL>& kept_urls) { | 2588 const std::vector<GURL>& kept_urls) { |
| 2758 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2759 | |
| 2760 if (!thumbnail_db_) { | 2589 if (!thumbnail_db_) { |
| 2761 // When we have no reference to the thumbnail database, maybe there was an | 2590 // When we have no reference to the thumbnail database, maybe there was an |
| 2762 // error opening it. In this case, we just try to blow it away to try to | 2591 // error opening it. In this case, we just try to blow it away to try to |
| 2763 // fix the error if it exists. This may fail, in which case either the | 2592 // fix the error if it exists. This may fail, in which case either the |
| 2764 // file doesn't exist or there's no more we can do. | 2593 // file doesn't exist or there's no more we can do. |
| 2765 sql::Connection::Delete(GetFaviconsFileName()); | 2594 sql::Connection::Delete(GetFaviconsFileName()); |
| 2766 return true; | 2595 return true; |
| 2767 } | 2596 } |
| 2768 | 2597 |
| 2769 // Isolate from any long-running transaction. | 2598 // Isolate from any long-running transaction. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2788 // must be no transaction open on the table when we do this. We assume that | 2617 // must be no transaction open on the table when we do this. We assume that |
| 2789 // our long-running transaction is open, so we complete it and start it again. | 2618 // our long-running transaction is open, so we complete it and start it again. |
| 2790 DCHECK_EQ(thumbnail_db_->transaction_nesting(), 1); | 2619 DCHECK_EQ(thumbnail_db_->transaction_nesting(), 1); |
| 2791 thumbnail_db_->CommitTransaction(); | 2620 thumbnail_db_->CommitTransaction(); |
| 2792 thumbnail_db_->Vacuum(); | 2621 thumbnail_db_->Vacuum(); |
| 2793 thumbnail_db_->BeginTransaction(); | 2622 thumbnail_db_->BeginTransaction(); |
| 2794 return true; | 2623 return true; |
| 2795 } | 2624 } |
| 2796 | 2625 |
| 2797 bool HistoryBackend::ClearAllMainHistory(const URLRows& kept_urls) { | 2626 bool HistoryBackend::ClearAllMainHistory(const URLRows& kept_urls) { |
| 2798 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | |
| 2799 | |
| 2800 // Create the duplicate URL table. We will copy the kept URLs into this. | 2627 // Create the duplicate URL table. We will copy the kept URLs into this. |
| 2801 if (!db_->CreateTemporaryURLTable()) | 2628 if (!db_->CreateTemporaryURLTable()) |
| 2802 return false; | 2629 return false; |
| 2803 | 2630 |
| 2804 // Insert the URLs into the temporary table. | 2631 // Insert the URLs into the temporary table. |
| 2805 for (URLRows::const_iterator i = kept_urls.begin(); i != kept_urls.end(); | 2632 for (URLRows::const_iterator i = kept_urls.begin(); i != kept_urls.end(); |
| 2806 ++i) { | 2633 ++i) { |
| 2807 db_->AddTemporaryURL(*i); | 2634 db_->AddTemporaryURL(*i); |
| 2808 } | 2635 } |
| 2809 | 2636 |
| 2810 // Replace the original URL table with the temporary one. | 2637 // Replace the original URL table with the temporary one. |
| 2811 if (!db_->CommitTemporaryURLTable()) | 2638 if (!db_->CommitTemporaryURLTable()) |
| 2812 return false; | 2639 return false; |
| 2813 | 2640 |
| 2814 // Delete the old tables and recreate them empty. | 2641 // Delete the old tables and recreate them empty. |
| 2815 db_->RecreateAllTablesButURL(); | 2642 db_->RecreateAllTablesButURL(); |
| 2816 | 2643 |
| 2817 // Vacuum to reclaim the space from the dropped tables. This must be done | 2644 // Vacuum to reclaim the space from the dropped tables. This must be done |
| 2818 // when there is no transaction open, and we assume that our long-running | 2645 // when there is no transaction open, and we assume that our long-running |
| 2819 // transaction is currently open. | 2646 // transaction is currently open. |
| 2820 db_->CommitTransaction(); | 2647 db_->CommitTransaction(); |
| 2821 db_->Vacuum(); | 2648 db_->Vacuum(); |
| 2822 db_->BeginTransaction(); | 2649 db_->BeginTransaction(); |
| 2823 db_->GetStartDate(&first_recorded_time_); | 2650 db_->GetStartDate(&first_recorded_time_); |
| 2824 | 2651 |
| 2825 return true; | 2652 return true; |
| 2826 } | 2653 } |
| 2827 | 2654 |
| 2828 } // namespace history | 2655 } // namespace history |
| OLD | NEW |