diff options
author | brettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-07 19:03:40 +0000 |
---|---|---|
committer | brettw@google.com <brettw@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-07 19:03:40 +0000 |
commit | 599874373cf5ae8b1ba75afda760534063012ccd (patch) | |
tree | a2fc39478768610c538e34c6fc98032dec630760 | |
parent | ded678ec915e3ca698c91d67611ba48f8a938511 (diff) | |
download | chromium_src-599874373cf5ae8b1ba75afda760534063012ccd.zip chromium_src-599874373cf5ae8b1ba75afda760534063012ccd.tar.gz chromium_src-599874373cf5ae8b1ba75afda760534063012ccd.tar.bz2 |
Added a new interface IChromeHistoryIndexer which needs to be implemented by
indexers which are interested in indexing Chrome's web history. These should
register their CLSID in HKCU\Software\Google\Google Chrome\IndexerPlugins and
this is be used by Chrome to publish its index.
Added code to publish the index too.
Checked in for Vijay Thadkal <veejay.t.s@gmail.com> (Google). Reitveld #9007.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5002 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/browser.vcproj | 12 | ||||
-rw-r--r-- | chrome/browser/browser.vsprops | 2 | ||||
-rw-r--r-- | chrome/browser/history/expire_history_backend_unittest.cc | 17 | ||||
-rw-r--r-- | chrome/browser/history/history_backend.cc | 28 | ||||
-rw-r--r-- | chrome/browser/history/history_backend.h | 5 | ||||
-rw-r--r-- | chrome/browser/history/history_backend_unittest.cc | 10 | ||||
-rw-r--r-- | chrome/browser/history/history_indexer.idl | 45 | ||||
-rw-r--r-- | chrome/browser/history/history_publisher.cc | 156 | ||||
-rw-r--r-- | chrome/browser/history/history_publisher.h | 81 | ||||
-rw-r--r-- | chrome/browser/history/text_database_manager.cc | 10 | ||||
-rw-r--r-- | chrome/browser/history/text_database_manager.h | 10 | ||||
-rw-r--r-- | chrome/browser/history/text_database_manager_unittest.cc | 22 | ||||
-rw-r--r-- | chrome/browser/history/thumbnail_database.cc | 18 | ||||
-rw-r--r-- | chrome/browser/history/thumbnail_database.h | 16 | ||||
-rw-r--r-- | chrome/browser/history/thumbnail_database_unittest.cc | 76 | ||||
-rw-r--r-- | chrome/browser/views/bookmark_bar_view.cc | 2 |
16 files changed, 447 insertions, 63 deletions
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj index f83558f..2b8bf3d 100644 --- a/chrome/browser/browser.vcproj +++ b/chrome/browser/browser.vcproj @@ -1326,6 +1326,10 @@ > </File> <File + RelativePath=".\history\history_indexer.idl" + > + </File> + <File RelativePath=".\history\history_marshaling.h" > </File> @@ -1334,6 +1338,14 @@ > </File> <File + RelativePath=".\history\history_publisher.cc" + > + </File> + <File + RelativePath=".\history\history_publisher.h" + > + </File> + <File RelativePath=".\history\history_types.cc" > </File> diff --git a/chrome/browser/browser.vsprops b/chrome/browser/browser.vsprops index a66aa02..b978e89 100644 --- a/chrome/browser/browser.vsprops +++ b/chrome/browser/browser.vsprops @@ -7,7 +7,7 @@ > <Tool Name="VCCLCompilerTool" - AdditionalIncludeDirectories=""$(OutDir)\webkit";..\third_party\webkit\out" + AdditionalIncludeDirectories=""$(IntDir)\..\browser";"$(OutDir)\webkit";..\third_party\webkit\out" PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE" /> <Tool diff --git a/chrome/browser/history/expire_history_backend_unittest.cc b/chrome/browser/history/expire_history_backend_unittest.cc index 7195cdb..f3e6a8b 100644 --- a/chrome/browser/history/expire_history_backend_unittest.cc +++ b/chrome/browser/history/expire_history_backend_unittest.cc @@ -115,12 +115,12 @@ class ExpireHistoryTest : public testing::Test, std::wstring thumb_name(dir_); file_util::AppendToPath(&thumb_name, L"Thumbnails"); thumb_db_.reset(new ThumbnailDatabase); - if (thumb_db_->Init(thumb_name) != INIT_OK) + if (thumb_db_->Init(thumb_name, NULL) != INIT_OK) thumb_db_.reset(); text_db_.reset(new TextDatabaseManager(dir_, main_db_.get(), main_db_.get())); - if (!text_db_->Init()) + if (!text_db_->Init(NULL)) text_db_.reset(); expirer_.SetDatabases(main_db_.get(), archived_db_.get(), thumb_db_.get(), @@ -199,9 +199,12 @@ void ExpireHistoryTest::AddExampleData(URLID url_ids[3], Time visit_times[4]) { scoped_ptr<SkBitmap> thumbnail( JPEGCodec::Decode(kGoogleThumbnail, sizeof(kGoogleThumbnail))); ThumbnailScore score(0.25, true, true, Time::Now()); - thumb_db_->SetPageThumbnail(url_ids[0], *thumbnail, score); - thumb_db_->SetPageThumbnail(url_ids[1], *thumbnail, score); - thumb_db_->SetPageThumbnail(url_ids[2], *thumbnail, score); + + Time time; + GURL gurl; + thumb_db_->SetPageThumbnail(gurl, url_ids[0], *thumbnail, score, time); + thumb_db_->SetPageThumbnail(gurl, url_ids[1], *thumbnail, score, time); + thumb_db_->SetPageThumbnail(gurl, url_ids[2], *thumbnail, score, time); // Four visits. VisitRow visit_row1; @@ -400,7 +403,7 @@ TEST_F(ExpireHistoryTest, DeleteURLAndFavicon) { text_db_.reset(); EXPECT_TRUE(IsStringInFile(fts_filename, "goats")); text_db_.reset(new TextDatabaseManager(dir_, main_db_.get(), main_db_.get())); - ASSERT_TRUE(text_db_->Init()); + ASSERT_TRUE(text_db_->Init(NULL)); expirer_.SetDatabases(main_db_.get(), archived_db_.get(), thumb_db_.get(), text_db_.get()); @@ -412,7 +415,7 @@ TEST_F(ExpireHistoryTest, DeleteURLAndFavicon) { text_db_.reset(); EXPECT_FALSE(IsStringInFile(fts_filename, "goats")); text_db_.reset(new TextDatabaseManager(dir_, main_db_.get(), main_db_.get())); - ASSERT_TRUE(text_db_->Init()); + ASSERT_TRUE(text_db_->Init(NULL)); expirer_.SetDatabases(main_db_.get(), archived_db_.get(), thumb_db_.get(), text_db_.get()); diff --git a/chrome/browser/history/history_backend.cc b/chrome/browser/history/history_backend.cc index c3bdd4a..d904148 100644 --- a/chrome/browser/history/history_backend.cc +++ b/chrome/browser/history/history_backend.cc @@ -15,6 +15,7 @@ #include "chrome/browser/autocomplete/history_url_provider.h" #include "chrome/browser/bookmarks/bookmark_service.h" #include "chrome/browser/history/download_types.h" +#include "chrome/browser/history/history_publisher.h" #include "chrome/browser/history/in_memory_history_backend.h" #include "chrome/browser/history/page_usage_data.h" #include "chrome/common/chrome_constants.h" @@ -531,18 +532,28 @@ void HistoryBackend::InitImpl() { delete mem_backend; // Error case, run without the in-memory DB. db_->BeginExclusiveMode(); // Must be after the mem backend read the data. + // Create the history publisher which needs to be passed on to the text and + // thumbnail databases for publishing history. + history_publisher_.reset(new HistoryPublisher()); + if (!history_publisher_->Init()) { + // The init may fail when there are no indexers wanting our history. + // Hence no need to log the failure. + history_publisher_.reset(); + } + // Full-text database. This has to be first so we can pass it to the // HistoryDatabase for migration. text_database_.reset(new TextDatabaseManager(history_dir_, db_.get(), db_.get())); - if (!text_database_->Init()) { + if (!text_database_->Init(history_publisher_.get())) { LOG(WARNING) << "Text database initialization failed, running without it."; text_database_.reset(); } // Thumbnail database. thumbnail_db_.reset(new ThumbnailDatabase()); - if (thumbnail_db_->Init(thumbnail_name) != INIT_OK) { + if (thumbnail_db_->Init(thumbnail_name, + history_publisher_.get()) != INIT_OK) { // Unlike the main database, we don't error out when the database is too // new because this error is much less severe. Generally, this shouldn't // happen since the thumbnail and main datbase versions should be in sync. @@ -1185,9 +1196,13 @@ void HistoryBackend::SetPageThumbnail( if (!db_.get() || !thumbnail_db_.get()) return; - URLID url_id = db_->GetRowForURL(url, NULL); - if (url_id) - thumbnail_db_->SetPageThumbnail(url_id, thumbnail, score); + URLRow url_row; + URLID url_id = db_->GetRowForURL(url, &url_row); + if (url_id) { + thumbnail_db_->SetPageThumbnail(url, url_id, thumbnail, score, + url_row.last_visit()); + } + ScheduleCommit(); } @@ -1617,6 +1632,9 @@ void HistoryBackend::ExpireHistoryBetween( } request->ForwardResult(ExpireHistoryRequest::TupleType()); + + if (history_publisher_.get()) + history_publisher_->DeleteUserHistoryBetween(begin_time, end_time); } void HistoryBackend::URLsNoLongerBookmarked(const std::set<GURL>& urls) { diff --git a/chrome/browser/history/history_backend.h b/chrome/browser/history/history_backend.h index b03a781..a7c9310 100644 --- a/chrome/browser/history/history_backend.h +++ b/chrome/browser/history/history_backend.h @@ -31,6 +31,7 @@ struct ThumbnailScore; namespace history { class CommitLaterTask; +class HistoryPublisher; // *See the .cc file for more information on the design.* // @@ -484,6 +485,10 @@ class HistoryBackend : public base::RefCountedThreadSafe<HistoryBackend>, // loaded. BookmarkService* bookmark_service_; + // Publishes the history to all indexers which are registered to receive + // history data from us. Can be NULL if there are no listeners. + scoped_ptr<HistoryPublisher> history_publisher_; + DISALLOW_EVIL_CONSTRUCTORS(HistoryBackend); }; diff --git a/chrome/browser/history/history_backend_unittest.cc b/chrome/browser/history/history_backend_unittest.cc index a762df4..2f9bcf4 100644 --- a/chrome/browser/history/history_backend_unittest.cc +++ b/chrome/browser/history/history_backend_unittest.cc @@ -12,6 +12,7 @@ #include "chrome/common/jpeg_codec.h" #include "chrome/common/thumbnail_score.h" #include "chrome/tools/profiles/thumbnail-inl.h" +#include "googleurl/src/gurl.h" #include "testing/gtest/include/gtest/gtest.h" using base::Time; @@ -195,10 +196,15 @@ TEST_F(HistoryBackendTest, DeleteAll) { ThumbnailScore score(0.25, true, true); scoped_ptr<SkBitmap> google_bitmap( JPEGCodec::Decode(kGoogleThumbnail, sizeof(kGoogleThumbnail))); - backend_->thumbnail_db_->SetPageThumbnail(row1_id, *google_bitmap, score); + + Time time; + GURL gurl; + backend_->thumbnail_db_->SetPageThumbnail(gurl, row1_id, *google_bitmap, + score, time); scoped_ptr<SkBitmap> weewar_bitmap( JPEGCodec::Decode(kWeewarThumbnail, sizeof(kWeewarThumbnail))); - backend_->thumbnail_db_->SetPageThumbnail(row2_id, *weewar_bitmap, score); + backend_->thumbnail_db_->SetPageThumbnail(gurl, row2_id, *weewar_bitmap, + score, time); // Star row1. bookmark_model_.AddURL( diff --git a/chrome/browser/history/history_indexer.idl b/chrome/browser/history/history_indexer.idl new file mode 100644 index 0000000..132c5f0 --- /dev/null +++ b/chrome/browser/history/history_indexer.idl @@ -0,0 +1,45 @@ +// Copyright (c) 2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import "oaidl.idl"; +import "ocidl.idl"; + +[ + object, + uuid(9C1100DD-51D4-4827-AE9F-3B8FAC4AED72), + oleautomation, + nonextensible, + pointer_default(unique) +] +interface IChromeHistoryIndexer : IUnknown { + // This is the method called by Chrome to send content and thumbnail of the + // page to be indexed. The html content and thumbnail for the same url + // are sent at different points in time. The thumbnail_format and + // thumbnail parameters will be NULL when sending only the content. + // |time| - The last time at which user visited the page. The time is in UTC. + // |url| - The url of the page being published for indexing. + // |html| - The html content of the page being published for indexing. + // |title| - The url of the page being published for indexing. + // |thumbnail_format| - The format of the thumbnail image. It is currently + // "image/jpeg", indicating that the thumbail is in jpeg + // format. + // |thumbnail| - This is an array of bytes that represents the thumbnail in + // the format specified by the "thumbnail_format" parameter. + HRESULT SendPageData([in] VARIANT time, + [in] BSTR url, + [in] BSTR html, + [in] BSTR title, + [in] BSTR thumbnail_format, + [in] VARIANT thumbnail); + + // This method is called by Chrome when the users delete their history. + // |begin_time| - Represents the start time from which the history needs to be + // deleted. It is given in UTC. + // |end_time| - Represents the end time until when the history needs to be + // deleted. It is given in UTC + // If both begin_time and end_time are '0', full user history needs to be + // deleted. + HRESULT DeleteUserHistoryBetween([in] VARIANT begin_time, + [in] VARIANT end_time); +}; diff --git a/chrome/browser/history/history_publisher.cc b/chrome/browser/history/history_publisher.cc new file mode 100644 index 0000000..5b4eead --- /dev/null +++ b/chrome/browser/history/history_publisher.cc @@ -0,0 +1,156 @@ +// Copyright (c) 008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/history/history_publisher.h" + +#if defined(OS_WIN) +#include <atlsafe.h> +#include <objbase.h> +#include <oleauto.h> +#include <wtypes.h> +#endif + +#include "base/registry.h" + +namespace history { + +const wchar_t* HistoryPublisher::kRegKeyRegisteredIndexersInfo = + L"Software\\Google\\Google Chrome\\IndexerPlugins"; +const char* HistoryPublisher::kThumbnailImageFormat = "image/jpeg"; + +// static +double HistoryPublisher::TimeToUTCVariantTime(const base::Time& time) { + double var_time = 0; +#if defined(OS_WIN) + if (!time.is_null()) { + base::Time::Exploded exploded; + time.UTCExplode(&exploded); + + // Create the system time struct representing our exploded time. + SYSTEMTIME system_time; + system_time.wYear = exploded.year; + system_time.wMonth = exploded.month; + system_time.wDayOfWeek = exploded.day_of_week; + system_time.wDay = exploded.day_of_month; + system_time.wHour = exploded.hour; + system_time.wMinute = exploded.minute; + system_time.wSecond = exploded.second; + system_time.wMilliseconds = exploded.millisecond; + SystemTimeToVariantTime(&system_time, &var_time); + } +#endif + + return var_time; +} + +HistoryPublisher::HistoryPublisher() { +#if defined(OS_WIN) + CoInitialize(NULL); +#endif +} + +HistoryPublisher::~HistoryPublisher() { +#if defined(OS_WIN) + CoUninitialize(); +#endif +} + +bool HistoryPublisher::Init() { + return ReadRegisteredIndexersFromRegistry(); +} + +bool HistoryPublisher::ReadRegisteredIndexersFromRegistry() { +#if defined(OS_WIN) + RegistryKeyIterator iter(HKEY_CURRENT_USER, kRegKeyRegisteredIndexersInfo); + while (iter.Valid()) { + // The subkey name is the GUID of the Indexer COM object which implements + // the IChromeHistoryIndexer interface. We shall store that and use it to + // send historical data to the indexer. + CLSID clsid; + CLSIDFromString(static_cast<LPOLESTR>( + const_cast<TCHAR*>(iter.Name())), &clsid); + CComPtr<IChromeHistoryIndexer> indexer; + HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC, + __uuidof(IChromeHistoryIndexer), + reinterpret_cast<void**>(&indexer)); + if (SUCCEEDED(hr) && indexer != NULL) + indexers_.push_back(indexer); + ++iter; + } + return indexers_.size() > 0; +#else + // The indexing plublisher is implemented only for Windows platform as of + // now. Hence returning false for other platforms. + return false; +#endif +} + +void HistoryPublisher::PublishPageThumbnail( + const std::vector<unsigned char>& thumbnail, const GURL& url, + const base::Time& time) const { + PageData page_data = { + time, + url, + NULL, + NULL, + kThumbnailImageFormat, + &thumbnail, + }; + + PublishDataToIndexers(page_data); +} + +void HistoryPublisher::PublishPageContent(const base::Time& time, + const GURL& url, + const std::wstring& title, + const std::wstring& contents) const { + PageData page_data = { + time, + url, + contents.c_str(), + title.c_str(), + NULL, + NULL, + }; + + PublishDataToIndexers(page_data); +} + +void HistoryPublisher::PublishDataToIndexers(const PageData& page_data) + const { +#if defined(OS_WIN) + double var_time = TimeToUTCVariantTime(page_data.time); + + CComSafeArray<unsigned char> thumbnail_arr; + if (page_data.thumbnail) { + for(size_t i = 0; i < page_data.thumbnail->size(); ++i) + thumbnail_arr.Add((*page_data.thumbnail)[i]); + } + + // Send data to registered indexers. + for(size_t i = 0; i < indexers_.size(); ++i) { + indexers_[i]->SendPageData( + CComVariant(var_time, VT_DATE), + CComBSTR(page_data.url.spec().c_str()), + CComBSTR(page_data.html), + CComBSTR(page_data.title), + CComBSTR(page_data.thumbnail_format), + CComVariant(thumbnail_arr.m_psa)); + } +#endif +} + +void HistoryPublisher::DeleteUserHistoryBetween(const base::Time& begin_time, + const base::Time& end_time) const { +#if defined(OS_WIN) + double var_begin_time = TimeToUTCVariantTime(begin_time); + double var_end_time = TimeToUTCVariantTime(end_time); + for(size_t i = 0; i < indexers_.size(); ++i) { + indexers_[i]->DeleteUserHistoryBetween(CComVariant(var_begin_time, VT_DATE), + CComVariant(var_end_time, VT_DATE)); + } +#endif +} + +} // namespace history diff --git a/chrome/browser/history/history_publisher.h b/chrome/browser/history/history_publisher.h new file mode 100644 index 0000000..7c199ac --- /dev/null +++ b/chrome/browser/history/history_publisher.h @@ -0,0 +1,81 @@ +// Copyright (c) 2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_HISTORY_HISTORY_PUBLISHER_H_ +#define CHROME_BROWSER_HISTORY_HISTORY_PUBLISHER_H_ + +#include <vector> +#include <string> + +#include "base/basictypes.h" +#include "base/time.h" +#include "chrome/browser/history/history_types.h" +#include "googleurl/src/gurl.h" + +#if defined(OS_WIN) +#include <atlbase.h> +#include <atlcomcli.h> +#include "history_indexer.h" +#endif + +namespace history { + +class HistoryPublisher { + public: + HistoryPublisher(); + ~HistoryPublisher(); + + // Must call this function to complete initialization. Returns true if we + // need to publish data to any indexers registered with us. Returns false if + // there are none registered. On false, no other function should be called. + bool Init(); + + void PublishPageThumbnail(const std::vector<unsigned char>& thumbnail, + const GURL& url, const base::Time& time) const; + void PublishPageContent(const base::Time& time, const GURL& url, + const std::wstring& title, + const std::wstring& contents) const; + void DeleteUserHistoryBetween(const base::Time& begin_time, + const base::Time& end_time) const; + + private: + struct PageData { + const base::Time& time; + const GURL& url; + const wchar_t* html; + const wchar_t* title; + const char* thumbnail_format; + const std::vector<unsigned char>* thumbnail; + }; + void PublishDataToIndexers(const PageData& page_data) const; + + // Converts time represented by the Time class object to variant time in UTC. + // Returns '0' if the time object is NULL. + static double TimeToUTCVariantTime(const base::Time& time); + + // Initializes the indexer_list_ with the list of indexers that registered + // with us to index history. Returns true if there are any registered. + bool ReadRegisteredIndexersFromRegistry(); + + private: +#if defined(OS_WIN) + typedef std::vector<CComPtr<IChromeHistoryIndexer> > IndexerList; + + // The list of indexers registered to receive history data from us. + IndexerList indexers_; +#endif + + // The Registry key under HKCU where the indexers need to register their + // CLSID. + static const wchar_t* kRegKeyRegisteredIndexersInfo; + + // The format of the thumbnail we pass to indexers. + static const char* kThumbnailImageFormat; + + DISALLOW_COPY_AND_ASSIGN(HistoryPublisher); +}; + +} // namespace history + +#endif // CHROME_BROWSER_HISTORY_HISTORY_PUBLISHER_H_ diff --git a/chrome/browser/history/text_database_manager.cc b/chrome/browser/history/text_database_manager.cc index 483befa..8fcb8fc 100644 --- a/chrome/browser/history/text_database_manager.cc +++ b/chrome/browser/history/text_database_manager.cc @@ -10,6 +10,7 @@ #include "base/logging.h" #include "base/message_loop.h" #include "base/string_util.h" +#include "chrome/browser/history/history_publisher.h" #include "chrome/common/mru_cache.h" using base::Time; @@ -77,6 +78,7 @@ TextDatabaseManager::TextDatabaseManager(const std::wstring& dir, transaction_nesting_(0), db_cache_(DBCache::NO_AUTO_EVICT), present_databases_loaded_(false), + history_publisher_(NULL), ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) { } @@ -104,7 +106,9 @@ Time TextDatabaseManager::IDToTime(TextDatabase::DBIdent id) { return Time::FromUTCExploded(exploded); } -bool TextDatabaseManager::Init() { +bool TextDatabaseManager::Init(const HistoryPublisher* history_publisher) { + history_publisher_ = history_publisher; + // Start checking recent changes and committing them. ScheduleFlushOldChanges(); return true; @@ -306,6 +310,10 @@ bool TextDatabaseManager::AddPageData(const GURL& url, HISTOGRAM_TIMES(L"History.AddFTSData", TimeTicks::Now() - beginning_time); + + if (history_publisher_) + history_publisher_->PublishPageContent(visit_time, url, title, body); + return success; } diff --git a/chrome/browser/history/text_database_manager.h b/chrome/browser/history/text_database_manager.h index f1195ef..fcf9d5f 100644 --- a/chrome/browser/history/text_database_manager.h +++ b/chrome/browser/history/text_database_manager.h @@ -22,6 +22,8 @@ struct sqlite3; namespace history { +class HistoryPublisher; + // Manages a set of text databases representing different time periods. This // will page them in and out as necessary, and will manage queries for times // spanning multiple databases. @@ -77,7 +79,7 @@ class TextDatabaseManager { // Must call before using other functions. If it returns false, no other // functions should be called. - bool Init(); + bool Init(const HistoryPublisher* history_publisher); // Allows scoping updates. This also allows things to go faster since every // page add doesn't need to be committed to disk (slow). Note that files will @@ -293,6 +295,12 @@ class TextDatabaseManager { // Generates tasks for our periodic checking of expired "recent changes". ScopedRunnableMethodFactory<TextDatabaseManager> factory_; + // This object is created and managed by the history backend. We maintain an + // opaque pointer to the object for our use. + // This can be NULL if there are no indexers registered to receive indexing + // data from us. + const HistoryPublisher* history_publisher_; + DISALLOW_EVIL_CONSTRUCTORS(TextDatabaseManager); }; diff --git a/chrome/browser/history/text_database_manager_unittest.cc b/chrome/browser/history/text_database_manager_unittest.cc index 6781a76..b080def 100644 --- a/chrome/browser/history/text_database_manager_unittest.cc +++ b/chrome/browser/history/text_database_manager_unittest.cc @@ -169,7 +169,7 @@ TEST_F(TextDatabaseManagerTest, InsertQuery) { ASSERT_TRUE(Init()); InMemDB visit_db; TextDatabaseManager manager(dir_, &visit_db, &visit_db); - ASSERT_TRUE(manager.Init()); + ASSERT_TRUE(manager.Init(NULL)); std::vector<Time> times; AddAllPages(manager, &visit_db, ×); @@ -201,7 +201,7 @@ TEST_F(TextDatabaseManagerTest, InsertCompleteNoVisit) { ASSERT_TRUE(Init()); InMemDB visit_db; TextDatabaseManager manager(dir_, &visit_db, &visit_db); - ASSERT_TRUE(manager.Init()); + ASSERT_TRUE(manager.Init(NULL)); // First add one without a visit. const GURL url(kURL1); @@ -225,7 +225,7 @@ TEST_F(TextDatabaseManagerTest, InsertCompleteVisit) { ASSERT_TRUE(Init()); InMemDB visit_db; TextDatabaseManager manager(dir_, &visit_db, &visit_db); - ASSERT_TRUE(manager.Init()); + ASSERT_TRUE(manager.Init(NULL)); // First add a visit to a page. We can just make up a URL ID since there is // not actually any URL database around. @@ -264,7 +264,7 @@ TEST_F(TextDatabaseManagerTest, InsertPartial) { ASSERT_TRUE(Init()); InMemDB visit_db; TextDatabaseManager manager(dir_, &visit_db, &visit_db); - ASSERT_TRUE(manager.Init()); + ASSERT_TRUE(manager.Init(NULL)); // Add the first one with just a URL. GURL url1(kURL1); @@ -312,7 +312,7 @@ TEST_F(TextDatabaseManagerTest, PartialComplete) { ASSERT_TRUE(Init()); InMemDB visit_db; TextDatabaseManager manager(dir_, &visit_db, &visit_db); - ASSERT_TRUE(manager.Init()); + ASSERT_TRUE(manager.Init(NULL)); Time added_time = Time::Now(); GURL url(kURL1); @@ -370,7 +370,7 @@ TEST_F(TextDatabaseManagerTest, Writing) { // Create the manager and write some stuff to it. { TextDatabaseManager manager(dir_, &visit_db, &visit_db); - ASSERT_TRUE(manager.Init()); + ASSERT_TRUE(manager.Init(NULL)); std::vector<Time> times; AddAllPages(manager, &visit_db, ×); @@ -384,7 +384,7 @@ TEST_F(TextDatabaseManagerTest, Writing) { // Recreate the manager and make sure it finds the written stuff. { TextDatabaseManager manager(dir_, &visit_db, &visit_db); - ASSERT_TRUE(manager.Init()); + ASSERT_TRUE(manager.Init(NULL)); // We should have matched every page again. manager.GetTextMatches(L"FOO", options, &results, &first_time_searched); @@ -406,7 +406,7 @@ TEST_F(TextDatabaseManagerTest, WritingTransaction) { // Create the manager and write some stuff to it. { TextDatabaseManager manager(dir_, &visit_db, &visit_db); - ASSERT_TRUE(manager.Init()); + ASSERT_TRUE(manager.Init(NULL)); std::vector<Time> times; manager.BeginTransaction(); @@ -422,7 +422,7 @@ TEST_F(TextDatabaseManagerTest, WritingTransaction) { // Recreate the manager and make sure it finds the written stuff. { TextDatabaseManager manager(dir_, &visit_db, &visit_db); - ASSERT_TRUE(manager.Init()); + ASSERT_TRUE(manager.Init(NULL)); // We should have matched every page again. manager.GetTextMatches(L"FOO", options, &results, &first_time_searched); @@ -435,7 +435,7 @@ TEST_F(TextDatabaseManagerTest, QueryMax) { ASSERT_TRUE(Init()); InMemDB visit_db; TextDatabaseManager manager(dir_, &visit_db, &visit_db); - ASSERT_TRUE(manager.Init()); + ASSERT_TRUE(manager.Init(NULL)); std::vector<Time> times; AddAllPages(manager, &visit_db, ×); @@ -472,7 +472,7 @@ TEST_F(TextDatabaseManagerTest, QueryBackwards) { ASSERT_TRUE(Init()); InMemDB visit_db; TextDatabaseManager manager(dir_, &visit_db, &visit_db); - ASSERT_TRUE(manager.Init()); + ASSERT_TRUE(manager.Init(NULL)); std::vector<Time> times; AddAllPages(manager, &visit_db, ×); diff --git a/chrome/browser/history/thumbnail_database.cc b/chrome/browser/history/thumbnail_database.cc index ca0a132..d493b56 100644 --- a/chrome/browser/history/thumbnail_database.cc +++ b/chrome/browser/history/thumbnail_database.cc @@ -7,6 +7,7 @@ #include "base/file_util.h" #include "base/time.h" #include "base/string_util.h" +#include "chrome/browser/history/history_publisher.h" #include "chrome/browser/history/url_database.h" #include "chrome/common/jpeg_codec.h" #include "chrome/common/sqlite_utils.h" @@ -24,14 +25,18 @@ static const int kCompatibleVersionNumber = 3; ThumbnailDatabase::ThumbnailDatabase() : db_(NULL), statement_cache_(NULL), - transaction_nesting_(0) { + transaction_nesting_(0), + history_publisher_(NULL) { } ThumbnailDatabase::~ThumbnailDatabase() { // The DBCloseScoper will delete the DB and the cache. } -InitStatus ThumbnailDatabase::Init(const std::wstring& db_name) { +InitStatus ThumbnailDatabase::Init(const std::wstring& db_name, + const HistoryPublisher* history_publisher) { + history_publisher_ = history_publisher; + // Open the thumbnail database, using the narrow version of open so that // the DB is in UTF-8. if (sqlite3_open(WideToUTF8(db_name).c_str(), &db_) != SQLITE_OK) @@ -222,9 +227,11 @@ void ThumbnailDatabase::Vacuum() { } void ThumbnailDatabase::SetPageThumbnail( + const GURL& url, URLID id, const SkBitmap& thumbnail, - const ThumbnailScore& score) { + const ThumbnailScore& score, + const Time& time) { if (!thumbnail.isNull()) { bool add_thumbnail = true; ThumbnailScore current_score; @@ -264,6 +271,11 @@ void ThumbnailDatabase::SetPageThumbnail( if (statement->step() != SQLITE_DONE) DLOG(WARNING) << "Unable to insert thumbnail"; } + + // Publish the thumbnail to any indexers listening to us. + // The tests may send an invalid url. Hence avoid publishing those. + if (url.is_valid() && history_publisher_ != NULL) + history_publisher_->PublishPageThumbnail(jpeg_data, url, time); } } else { if ( !DeleteThumbnail(id) ) diff --git a/chrome/browser/history/thumbnail_database.h b/chrome/browser/history/thumbnail_database.h index 0a15931..5452c77 100644 --- a/chrome/browser/history/thumbnail_database.h +++ b/chrome/browser/history/thumbnail_database.h @@ -22,6 +22,7 @@ namespace base { namespace history { class ExpireHistoryBackend; +class HistoryPublisher; // This database interface is owned by the history backend and runs on the // history thread. It is a totally separate component from history partially @@ -37,7 +38,8 @@ class ThumbnailDatabase { // Must be called after creation but before any other methods are called. // When not INIT_OK, no other functions should be called. - InitStatus Init(const std::wstring& db_name); + InitStatus Init(const std::wstring& db_name, + const HistoryPublisher* history_publisher); // Transactions on the database. void BeginTransaction(); @@ -55,9 +57,11 @@ class ThumbnailDatabase { // Sets the given data to be the thumbnail for the given URL, // overwriting any previous data. If the SkBitmap contains no pixel // data, the thumbnail will be deleted. - void SetPageThumbnail(URLID id, + void SetPageThumbnail(const GURL& url, + URLID id, const SkBitmap& thumbnail, - const ThumbnailScore& score); + const ThumbnailScore& score, + const base::Time& time); // Retrieves thumbnail data for the given URL, returning true on success, // false if there is no such thumbnail or there was some other error. @@ -160,6 +164,12 @@ class ThumbnailDatabase { int transaction_nesting_; MetaTableHelper meta_table_; + + // This object is created and managed by the history backend. We maintain an + // opaque pointer to the object for our use. + // This can be NULL if there are no indexers registered to receive indexing + // data from us. + const HistoryPublisher* history_publisher_; }; } // namespace history diff --git a/chrome/browser/history/thumbnail_database_unittest.cc b/chrome/browser/history/thumbnail_database_unittest.cc index 318d385..7507536 100644 --- a/chrome/browser/history/thumbnail_database_unittest.cc +++ b/chrome/browser/history/thumbnail_database_unittest.cc @@ -12,6 +12,7 @@ #include "chrome/common/jpeg_codec.h" #include "chrome/common/thumbnail_score.h" #include "chrome/tools/profiles/thumbnail-inl.h" +#include "googleurl/src/gurl.h" #include "testing/gtest/include/gtest/gtest.h" #include "SkBitmap.h" @@ -80,11 +81,13 @@ static std::vector<unsigned char> StringToVector(const unsigned char* str) { TEST_F(ThumbnailDatabaseTest, AddDelete) { ThumbnailDatabase db; - ASSERT_TRUE(db.Init(file_name_) == INIT_OK); + ASSERT_TRUE(db.Init(file_name_, NULL) == INIT_OK); // Add one page & verify it got added. ThumbnailScore boring(kBoringness, true, true); - db.SetPageThumbnail(kPage1, *google_bitmap_, boring); + Time time; + GURL gurl; + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, boring, time); ThumbnailScore score_output; ASSERT_TRUE(db.ThumbnailScoreForId(kPage1, &score_output)); ASSERT_TRUE(boring.Equals(score_output)); @@ -97,13 +100,14 @@ TEST_F(ThumbnailDatabaseTest, AddDelete) { // Add another page with a better boringness & verify it got added. ThumbnailScore better_boringness(kBetterBoringness, true, true); - db.SetPageThumbnail(page2, *google_bitmap_, better_boringness); + + db.SetPageThumbnail(gurl, page2, *google_bitmap_, better_boringness, time); ASSERT_TRUE(db.ThumbnailScoreForId(page2, &score_output)); ASSERT_TRUE(better_boringness.Equals(score_output)); // Delete the thumbnail for the second page. ThumbnailScore worse_boringness(kWorseBoringness, true, true); - db.SetPageThumbnail(page2, SkBitmap(), worse_boringness); + db.SetPageThumbnail(gurl, page2, SkBitmap(), worse_boringness, time); ASSERT_FALSE(db.GetPageThumbnail(page2, &jpeg_data)); ASSERT_FALSE(db.ThumbnailScoreForId(page2, &score_output)); @@ -120,11 +124,14 @@ TEST_F(ThumbnailDatabaseTest, AddDelete) { TEST_F(ThumbnailDatabaseTest, UseLessBoringThumbnails) { ThumbnailDatabase db; Time now = Time::Now(); - ASSERT_TRUE(db.Init(file_name_) == INIT_OK); + ASSERT_TRUE(db.Init(file_name_, NULL) == INIT_OK); // Add one page & verify it got added. ThumbnailScore boring(kBoringness, true, true); - db.SetPageThumbnail(kPage1, *google_bitmap_, boring); + + Time time; + GURL gurl; + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, boring, time); std::vector<unsigned char> jpeg_data; ThumbnailScore score_out; ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); @@ -134,7 +141,7 @@ TEST_F(ThumbnailDatabaseTest, UseLessBoringThumbnails) { // Attempt to update the first page entry with a thumbnail that // is more boring and verify that it doesn't change. ThumbnailScore more_boring(kWorseBoringness, true, true); - db.SetPageThumbnail(kPage1, *google_bitmap_, more_boring); + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, more_boring, time); ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); ASSERT_TRUE(db.ThumbnailScoreForId(kPage1, &score_out)); ASSERT_TRUE(boring.Equals(score_out)); @@ -142,7 +149,7 @@ TEST_F(ThumbnailDatabaseTest, UseLessBoringThumbnails) { // Attempt to update the first page entry with a thumbnail that // is less boring and verify that we update it. ThumbnailScore less_boring(kBetterBoringness, true, true); - db.SetPageThumbnail(kPage1, *google_bitmap_, less_boring); + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, less_boring, time); ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); ASSERT_TRUE(db.ThumbnailScoreForId(kPage1, &score_out)); ASSERT_TRUE(less_boring.Equals(score_out)); @@ -151,12 +158,15 @@ TEST_F(ThumbnailDatabaseTest, UseLessBoringThumbnails) { TEST_F(ThumbnailDatabaseTest, UseAtTopThumbnails) { ThumbnailDatabase db; Time now = Time::Now(); - ASSERT_TRUE(db.Init(file_name_) == INIT_OK); + ASSERT_TRUE(db.Init(file_name_, NULL) == INIT_OK); // Add one page & verify it got added. Note that it doesn't have // |good_clipping| and isn't |at_top|. ThumbnailScore boring_and_bad(kBoringness, false, false); - db.SetPageThumbnail(kPage1, *google_bitmap_, boring_and_bad); + + Time time; + GURL gurl; + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, boring_and_bad, time); std::vector<unsigned char> jpeg_data; ThumbnailScore score_out; ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); @@ -166,7 +176,7 @@ TEST_F(ThumbnailDatabaseTest, UseAtTopThumbnails) { // A thumbnail that's at the top of the page should replace // thumbnails that are in the middle, for the same boringness. ThumbnailScore boring_but_better(kBoringness, false, true); - db.SetPageThumbnail(kPage1, *google_bitmap_, boring_but_better); + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, boring_but_better, time); ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); ASSERT_TRUE(db.ThumbnailScoreForId(kPage1, &score_out)); ASSERT_TRUE(boring_but_better.Equals(score_out)); @@ -175,13 +185,15 @@ TEST_F(ThumbnailDatabaseTest, UseAtTopThumbnails) { // a thumbnail in the middle/bottom is when the current thumbnail is // weirdly stretched and the incoming thumbnail isn't. ThumbnailScore better_boring_bad_framing(kBetterBoringness, false, false); - db.SetPageThumbnail(kPage1, *google_bitmap_, better_boring_bad_framing); + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, better_boring_bad_framing, + time); ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); ASSERT_TRUE(db.ThumbnailScoreForId(kPage1, &score_out)); ASSERT_TRUE(boring_but_better.Equals(score_out)); ThumbnailScore boring_good_clipping(kBoringness, true, false); - db.SetPageThumbnail(kPage1, *google_bitmap_, boring_good_clipping); + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, boring_good_clipping, + time); ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); ASSERT_TRUE(db.ThumbnailScoreForId(kPage1, &score_out)); ASSERT_TRUE(boring_good_clipping.Equals(score_out)); @@ -190,15 +202,17 @@ TEST_F(ThumbnailDatabaseTest, UseAtTopThumbnails) { // we shouldn't be able to replace it with: // 1) A stretched thumbnail in the middle of the page - db.SetPageThumbnail(kPage1, *google_bitmap_, - ThumbnailScore(kBetterBoringness, false, false, now)); + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, + ThumbnailScore(kBetterBoringness, false, false, now), + time); ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); ASSERT_TRUE(db.ThumbnailScoreForId(kPage1, &score_out)); ASSERT_TRUE(boring_good_clipping.Equals(score_out)); // 2) A stretched thumbnail at the top of the page - db.SetPageThumbnail(kPage1, *google_bitmap_, - ThumbnailScore(kBetterBoringness, false, true, now)); + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, + ThumbnailScore(kBetterBoringness, false, true, now), + time); ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); ASSERT_TRUE(db.ThumbnailScoreForId(kPage1, &score_out)); ASSERT_TRUE(boring_good_clipping.Equals(score_out)); @@ -206,7 +220,7 @@ TEST_F(ThumbnailDatabaseTest, UseAtTopThumbnails) { // But it should be replaced by a thumbnail that's clipped properly // and is at the top ThumbnailScore best_score(kBetterBoringness, true, true); - db.SetPageThumbnail(kPage1, *google_bitmap_, best_score); + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, best_score, time); ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); ASSERT_TRUE(db.ThumbnailScoreForId(kPage1, &score_out)); ASSERT_TRUE(best_score.Equals(score_out)); @@ -220,11 +234,14 @@ TEST_F(ThumbnailDatabaseTest, ThumbnailTimeDegradation) { const double kBaseBoringness = 0.305; const double kWorseBoringness = 0.345; - ASSERT_TRUE(db.Init(file_name_) == INIT_OK); + ASSERT_TRUE(db.Init(file_name_, NULL) == INIT_OK); // add one page & verify it got added. ThumbnailScore base_boringness(kBaseBoringness, true, true, kFiveHoursAgo); - db.SetPageThumbnail(kPage1, *google_bitmap_, base_boringness); + + Time time; + GURL gurl; + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, base_boringness, time); std::vector<unsigned char> jpeg_data; ThumbnailScore score_out; ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); @@ -234,7 +251,7 @@ TEST_F(ThumbnailDatabaseTest, ThumbnailTimeDegradation) { // Try to add a different thumbnail with a worse score an hour later // (but not enough to trip the boringness degradation threshold). ThumbnailScore hour_later(kWorseBoringness, true, true, kThreeHoursAgo); - db.SetPageThumbnail(kPage1, *google_bitmap_, hour_later); + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, hour_later, time); ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); ASSERT_TRUE(db.ThumbnailScoreForId(kPage1, &score_out)); ASSERT_TRUE(base_boringness.Equals(score_out)); @@ -243,7 +260,7 @@ TEST_F(ThumbnailDatabaseTest, ThumbnailTimeDegradation) { // that we'll allow the same thumbnail with the same (worse) // boringness that we previous rejected. ThumbnailScore five_hours_later(kWorseBoringness, true, true, kNow); - db.SetPageThumbnail(kPage1, *google_bitmap_, five_hours_later); + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, five_hours_later, time); ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); ASSERT_TRUE(db.ThumbnailScoreForId(kPage1, &score_out)); ASSERT_TRUE(five_hours_later.Equals(score_out)); @@ -256,7 +273,7 @@ TEST_F(ThumbnailDatabaseTest, NeverAcceptTotallyBoringThumbnail) { // thumbnail is totally boring. ThumbnailDatabase db; Time now = Time::Now(); - ASSERT_TRUE(db.Init(file_name_) == INIT_OK); + ASSERT_TRUE(db.Init(file_name_, NULL) == INIT_OK); std::vector<unsigned char> jpeg_data; ThumbnailScore score_out; @@ -273,6 +290,9 @@ TEST_F(ThumbnailDatabaseTest, NeverAcceptTotallyBoringThumbnail) { {true, true} }; + Time time; + GURL gurl; + // Test that for each entry type, all entry types that are better // than it still will reject thumbnails which are totally boring. for (int i = 0; i < kSizeOfTable; ++i) { @@ -281,7 +301,7 @@ TEST_F(ThumbnailDatabaseTest, NeverAcceptTotallyBoringThumbnail) { heiarchy_table[i].at_top, kNow); - db.SetPageThumbnail(kPage1, *google_bitmap_, base); + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, base, time); ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); ASSERT_TRUE(db.ThumbnailScoreForId(kPage1, &score_out)); ASSERT_TRUE(base.Equals(score_out)); @@ -291,7 +311,8 @@ TEST_F(ThumbnailDatabaseTest, NeverAcceptTotallyBoringThumbnail) { kTotallyBoring, heiarchy_table[j].good_scaling, heiarchy_table[j].at_top, kNow); - db.SetPageThumbnail(kPage1, *google_bitmap_, shouldnt_replace); + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, shouldnt_replace, + time); ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); ASSERT_TRUE(db.ThumbnailScoreForId(kPage1, &score_out)); ASSERT_TRUE(base.Equals(score_out)); @@ -306,14 +327,15 @@ TEST_F(ThumbnailDatabaseTest, NeverAcceptTotallyBoringThumbnail) { // We should never accept a totally boring thumbnail no matter how // much old the current thumbnail is. ThumbnailScore base_boring(kBaseBoringness, true, true, kNow); - db.SetPageThumbnail(kPage1, *google_bitmap_, base_boring); + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, base_boring, time); ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); ASSERT_TRUE(db.ThumbnailScoreForId(kPage1, &score_out)); ASSERT_TRUE(base_boring.Equals(score_out)); ThumbnailScore totally_boring_in_the_future( kTotallyBoring, true, true, kNow + TimeDelta::FromDays(365)); - db.SetPageThumbnail(kPage1, *google_bitmap_, totally_boring_in_the_future); + db.SetPageThumbnail(gurl, kPage1, *google_bitmap_, + totally_boring_in_the_future, time); ASSERT_TRUE(db.GetPageThumbnail(kPage1, &jpeg_data)); ASSERT_TRUE(db.ThumbnailScoreForId(kPage1, &score_out)); ASSERT_TRUE(base_boring.Equals(score_out)); diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc index 66d1ccd..a5f6fdf 100644 --- a/chrome/browser/views/bookmark_bar_view.cc +++ b/chrome/browser/views/bookmark_bar_view.cc @@ -17,8 +17,6 @@ #include "chrome/browser/browser_window.h" #include "chrome/browser/drag_utils.h" #include "chrome/browser/download/download_util.h" -#include "chrome/browser/history/history_backend.h" -#include "chrome/browser/history/history_database.h" #include "chrome/browser/history/history.h" #include "chrome/browser/page_navigator.h" #include "chrome/browser/profile.h" |