Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: components/history/core/browser/history_backend.cc

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

Powered by Google App Engine
This is Rietveld 408576698