Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / history / in_memory_url_index.cc
index 6a0299c..b761164 100644 (file)
@@ -5,19 +5,18 @@
 #include "chrome/browser/history/in_memory_url_index.h"
 
 #include "base/debug/trace_event.h"
-#include "base/file_util.h"
+#include "base/files/file_util.h"
 #include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
-#include "chrome/browser/bookmarks/bookmark_service.h"
 #include "chrome/browser/chrome_notification_types.h"
 #include "chrome/browser/history/history_notifications.h"
 #include "chrome/browser/history/history_service.h"
 #include "chrome/browser/history/history_service_factory.h"
-#include "chrome/browser/history/url_database.h"
 #include "chrome/browser/history/url_index_private_data.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/url_constants.h"
+#include "components/bookmarks/browser/bookmark_model.h"
+#include "components/history/core/browser/url_database.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_details.h"
 #include "content/public/browser/notification_service.h"
@@ -39,13 +38,13 @@ void InitializeSchemeWhitelist(std::set<std::string>* whitelist) {
   DCHECK(whitelist);
   if (!whitelist->empty())
     return;  // Nothing to do, already initialized.
-  whitelist->insert(std::string(chrome::kAboutScheme));
+  whitelist->insert(std::string(url::kAboutScheme));
   whitelist->insert(std::string(content::kChromeUIScheme));
-  whitelist->insert(std::string(content::kFileScheme));
-  whitelist->insert(std::string(content::kFtpScheme));
-  whitelist->insert(std::string(content::kHttpScheme));
-  whitelist->insert(std::string(content::kHttpsScheme));
-  whitelist->insert(std::string(content::kMailToScheme));
+  whitelist->insert(std::string(url::kFileScheme));
+  whitelist->insert(std::string(url::kFtpScheme));
+  whitelist->insert(std::string(url::kHttpScheme));
+  whitelist->insert(std::string(url::kHttpsScheme));
+  whitelist->insert(std::string(url::kMailToScheme));
 }
 
 // Restore/SaveCacheObserver ---------------------------------------------------
@@ -90,9 +89,13 @@ InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask::
 // InMemoryURLIndex ------------------------------------------------------------
 
 InMemoryURLIndex::InMemoryURLIndex(Profile* profile,
+                                   HistoryService* history_service,
                                    const base::FilePath& history_dir,
-                                   const std::string& languages)
+                                   const std::string& languages,
+                                   HistoryClient* history_client)
     : profile_(profile),
+      history_service_(history_service),
+      history_client_(history_client),
       history_dir_(history_dir),
       languages_(languages),
       private_data_(new URLIndexPrivateData),
@@ -105,16 +108,19 @@ InMemoryURLIndex::InMemoryURLIndex(Profile* profile,
   if (profile) {
     // TODO(mrossetti): Register for language change notifications.
     content::Source<Profile> source(profile);
-    registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED, source);
     registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_MODIFIED,
                    source);
     registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED, source);
   }
+  if (history_service_)
+    history_service_->AddObserver(this);
 }
 
 // Called only by unit tests.
 InMemoryURLIndex::InMemoryURLIndex()
     : profile_(NULL),
+      history_service_(nullptr),
+      history_client_(NULL),
       private_data_(new URLIndexPrivateData),
       restore_cache_observer_(NULL),
       save_cache_observer_(NULL),
@@ -135,13 +141,15 @@ void InMemoryURLIndex::Init() {
 }
 
 void InMemoryURLIndex::ShutDown() {
+  if (history_service_)
+    history_service_->RemoveObserver(this);
   registrar_.RemoveAll();
-  cache_reader_consumer_.CancelAllRequests();
+  cache_reader_tracker_.TryCancelAll();
   shutdown_ = true;
   base::FilePath path;
   if (!GetCacheFilePath(&path))
     return;
-  private_data_->CancelPendingUpdates();
+  private_data_tracker_.TryCancelAll();
   URLIndexPrivateData::WritePrivateDataToCacheFileTask(private_data_, path);
   needs_to_be_cached_ = false;
 }
@@ -161,12 +169,14 @@ bool InMemoryURLIndex::GetCacheFilePath(base::FilePath* file_path) {
 
 ScoredHistoryMatches InMemoryURLIndex::HistoryItemsForTerms(
     const base::string16& term_string,
-    size_t cursor_position) {
+    size_t cursor_position,
+    size_t max_matches) {
   return private_data_->HistoryItemsForTerms(
       term_string,
       cursor_position,
+      max_matches,
       languages_,
-      BookmarkModelFactory::GetForProfile(profile_));
+      history_client_);
 }
 
 // Updating --------------------------------------------------------------------
@@ -179,9 +189,6 @@ void InMemoryURLIndex::Observe(int notification_type,
                                const content::NotificationSource& source,
                                const content::NotificationDetails& details) {
   switch (notification_type) {
-    case chrome::NOTIFICATION_HISTORY_URL_VISITED:
-      OnURLVisited(content::Details<URLVisitedDetails>(details).ptr());
-      break;
     case chrome::NOTIFICATION_HISTORY_URLS_MODIFIED:
       OnURLsModified(
           content::Details<history::URLsModifiedDetails>(details).ptr());
@@ -202,12 +209,17 @@ void InMemoryURLIndex::Observe(int notification_type,
   }
 }
 
-void InMemoryURLIndex::OnURLVisited(const URLVisitedDetails* details) {
-  HistoryService* service =
-      HistoryServiceFactory::GetForProfile(profile_,
-                                           Profile::EXPLICIT_ACCESS);
-  needs_to_be_cached_ |= private_data_->UpdateURL(
-      service, details->row, languages_, scheme_whitelist_);
+void InMemoryURLIndex::OnURLVisited(HistoryService* history_service,
+                                    ui::PageTransition transition,
+                                    const URLRow& row,
+                                    const RedirectList& redirects,
+                                    base::Time visit_time) {
+  DCHECK_EQ(history_service_, history_service);
+  needs_to_be_cached_ |= private_data_->UpdateURL(history_service_,
+                                                  row,
+                                                  languages_,
+                                                  scheme_whitelist_,
+                                                  &private_data_tracker_);
 }
 
 void InMemoryURLIndex::OnURLsModified(const URLsModifiedDetails* details) {
@@ -215,9 +227,11 @@ void InMemoryURLIndex::OnURLsModified(const URLsModifiedDetails* details) {
       HistoryServiceFactory::GetForProfile(profile_,
                                            Profile::EXPLICIT_ACCESS);
   for (URLRows::const_iterator row = details->changed_urls.begin();
-       row != details->changed_urls.end(); ++row)
-    needs_to_be_cached_ |=
-        private_data_->UpdateURL(service, *row, languages_, scheme_whitelist_);
+       row != details->changed_urls.end();
+       ++row) {
+    needs_to_be_cached_ |= private_data_->UpdateURL(
+        service, *row, languages_, scheme_whitelist_, &private_data_tracker_);
+  }
 }
 
 void InMemoryURLIndex::OnURLsDeleted(const URLsDeletedDetails* details) {
@@ -229,6 +243,25 @@ void InMemoryURLIndex::OnURLsDeleted(const URLsDeletedDetails* details) {
          row != details->rows.end(); ++row)
       needs_to_be_cached_ |= private_data_->DeleteURL(row->url());
   }
+  // If we made changes, destroy the previous cache.  Otherwise, if we go
+  // through an unclean shutdown (and therefore fail to write a new cache file),
+  // when Chrome restarts and we restore from the previous cache, we'll end up
+  // searching over URLs that may be deleted.  This would be wrong, and
+  // surprising to the user who bothered to delete some URLs from his/her
+  // history.  In this situation, deleting the cache is a better solution than
+  // writing a new cache (after deleting the URLs from the in-memory structure)
+  // because deleting the cache forces it to be rebuilt from history upon
+  // startup.  If we instead write a new, updated cache then at the time of next
+  // startup (after an unclean shutdown) we will not rebuild the in-memory data
+  // structures from history but rather use the cache.  This solution is
+  // mediocre because this cache may not have the most-recently-visited URLs
+  // in it (URLs visited after user deleted some URLs from history), which
+  // would be odd and confusing.  It's better to force a rebuild.
+  base::FilePath path;
+  if (needs_to_be_cached_ && GetCacheFilePath(&path)) {
+    content::BrowserThread::PostBlockingPoolTask(
+        FROM_HERE, base::Bind(DeleteCacheFile, path));
+  }
 }
 
 // Restoring from Cache --------------------------------------------------------
@@ -255,6 +288,7 @@ void InMemoryURLIndex::PostRestoreFromCacheFileTask() {
 void InMemoryURLIndex::OnCacheLoadDone(
     scoped_refptr<URLIndexPrivateData> private_data) {
   if (private_data.get() && !private_data->Empty()) {
+    private_data_tracker_.TryCancelAll();
     private_data_ = private_data;
     restored_ = true;
     if (restore_cache_observer_)
@@ -286,9 +320,10 @@ void InMemoryURLIndex::ScheduleRebuildFromHistory() {
       HistoryServiceFactory::GetForProfile(profile_,
                                            Profile::EXPLICIT_ACCESS);
   service->ScheduleDBTask(
-      new InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask(
-          this, languages_, scheme_whitelist_),
-      &cache_reader_consumer_);
+      scoped_ptr<history::HistoryDBTask>(
+          new InMemoryURLIndex::RebuildPrivateDataFromHistoryDBTask(
+              this, languages_, scheme_whitelist_)),
+      &cache_reader_tracker_);
 }
 
 void InMemoryURLIndex::DoneRebuidingPrivateDataFromHistoryDB(
@@ -296,6 +331,7 @@ void InMemoryURLIndex::DoneRebuidingPrivateDataFromHistoryDB(
     scoped_refptr<URLIndexPrivateData> private_data) {
   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
   if (succeeded) {
+    private_data_tracker_.TryCancelAll();
     private_data_ = private_data;
     PostSaveToCacheFileTask();  // Cache the newly rebuilt index.
   } else {
@@ -309,6 +345,7 @@ void InMemoryURLIndex::DoneRebuidingPrivateDataFromHistoryDB(
 }
 
 void InMemoryURLIndex::RebuildFromHistory(HistoryDatabase* history_db) {
+  private_data_tracker_.TryCancelAll();
   private_data_ = URLIndexPrivateData::RebuildFromHistory(history_db,
                                                           languages_,
                                                           scheme_whitelist_);