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