Home | History | Annotate | Download | only in history
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/history/history_publisher.h"
      6 
      7 #include <atlsafe.h>
      8 #include <oleauto.h>
      9 #include <wtypes.h>
     10 
     11 #include "base/strings/string_util.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "base/time/time.h"
     14 #include "base/win/registry.h"
     15 #include "base/win/scoped_bstr.h"
     16 #include "base/win/scoped_comptr.h"
     17 #include "base/win/scoped_variant.h"
     18 #include "url/gurl.h"
     19 
     20 namespace {
     21 
     22 // Instantiates the registered indexers from the registry |root| + |path| key
     23 // and adds them to the |indexers| list.
     24 void AddRegisteredIndexers(
     25     HKEY root,
     26     const wchar_t* path,
     27     std::vector< base::win::ScopedComPtr<IChromeHistoryIndexer> >* indexers) {
     28   for (base::win::RegistryKeyIterator r_iter(root, path); r_iter.Valid();
     29        ++r_iter) {
     30     CLSID clsid;
     31     if (FAILED(CLSIDFromString(const_cast<wchar_t*>(r_iter.Name()), &clsid)))
     32       continue;
     33     base::win::ScopedComPtr<IChromeHistoryIndexer> indexer;
     34     if (SUCCEEDED(indexer.CreateInstance(clsid, NULL, CLSCTX_INPROC))) {
     35       indexers->push_back(indexer);
     36       indexer.Release();
     37     }
     38   }
     39 }
     40 
     41 }  // namespace
     42 
     43 namespace history {
     44 
     45 const wchar_t* const HistoryPublisher::kRegKeyRegisteredIndexersInfo =
     46     L"Software\\Google\\Google Chrome\\IndexerPlugins";
     47 
     48 // static
     49 double HistoryPublisher::TimeToUTCVariantTime(const base::Time& time) {
     50   double var_time = 0;
     51   if (!time.is_null()) {
     52     base::Time::Exploded exploded;
     53     time.UTCExplode(&exploded);
     54 
     55     // Create the system time struct representing our exploded time.
     56     SYSTEMTIME system_time;
     57     system_time.wYear = exploded.year;
     58     system_time.wMonth = exploded.month;
     59     system_time.wDayOfWeek = exploded.day_of_week;
     60     system_time.wDay = exploded.day_of_month;
     61     system_time.wHour = exploded.hour;
     62     system_time.wMinute = exploded.minute;
     63     system_time.wSecond = exploded.second;
     64     system_time.wMilliseconds = exploded.millisecond;
     65     SystemTimeToVariantTime(&system_time, &var_time);
     66   }
     67 
     68   return var_time;
     69 }
     70 
     71 HistoryPublisher::HistoryPublisher() {
     72 }
     73 
     74 HistoryPublisher::~HistoryPublisher() {
     75 }
     76 
     77 bool HistoryPublisher::Init() {
     78   return ReadRegisteredIndexersFromRegistry();
     79 }
     80 
     81 // Peruse the registry for Indexer to instantiate and store in |indexers_|.
     82 // Return true if we found at least one indexer object. We look both in HKCU
     83 // and HKLM.
     84 bool HistoryPublisher::ReadRegisteredIndexersFromRegistry() {
     85   AddRegisteredIndexers(HKEY_CURRENT_USER,
     86                         kRegKeyRegisteredIndexersInfo, &indexers_);
     87   AddRegisteredIndexers(HKEY_LOCAL_MACHINE,
     88                         kRegKeyRegisteredIndexersInfo, &indexers_);
     89   return !indexers_.empty();
     90 }
     91 
     92 void HistoryPublisher::PublishDataToIndexers(const PageData& page_data)
     93     const {
     94   double var_time = TimeToUTCVariantTime(page_data.time);
     95 
     96   CComSafeArray<unsigned char> thumbnail_arr;
     97   if (page_data.thumbnail) {
     98     for (size_t i = 0; i < page_data.thumbnail->size(); ++i)
     99       thumbnail_arr.Add((*page_data.thumbnail)[i]);
    100   }
    101 
    102   // Send data to registered indexers.
    103   base::win::ScopedVariant time(var_time, VT_DATE);
    104   base::win::ScopedBstr url(ASCIIToWide(page_data.url.spec()).c_str());
    105   base::win::ScopedBstr html(page_data.html);
    106   base::win::ScopedBstr title(page_data.title);
    107   // Don't send a NULL string through ASCIIToWide.
    108   base::win::ScopedBstr format(page_data.thumbnail_format ?
    109       ASCIIToWide(page_data.thumbnail_format).c_str() :
    110       NULL);
    111   base::win::ScopedVariant psa(thumbnail_arr.m_psa);
    112   for (size_t i = 0; i < indexers_.size(); ++i) {
    113     indexers_[i]->SendPageData(time, url, html, title, format, psa);
    114   }
    115 }
    116 
    117 }  // namespace history
    118