OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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/android/history_report/data_provider.h" |
| 6 #include "base/bind.h" |
| 7 #include "base/containers/hash_tables.h" |
| 8 #include "base/logging.h" |
| 9 #include "base/synchronization/waitable_event.h" |
| 10 #include "chrome/browser/android/history_report/delta_file_commons.h" |
| 11 #include "chrome/browser/android/history_report/delta_file_service.h" |
| 12 #include "chrome/browser/android/history_report/get_all_urls_from_history_task.h
" |
| 13 #include "chrome/browser/android/history_report/historic_visits_migration_task.h
" |
| 14 #include "chrome/browser/android/history_report/usage_reports_buffer_service.h" |
| 15 #include "chrome/browser/history/history_service_factory.h" |
| 16 #include "chrome/browser/profiles/profile.h" |
| 17 #include "components/bookmarks/browser/bookmark_model.h" |
| 18 #include "components/history/core/browser/history_db_task.h" |
| 19 #include "components/history/core/browser/history_service.h" |
| 20 #include "content/public/browser/browser_thread.h" |
| 21 |
| 22 using bookmarks::BookmarkModel; |
| 23 |
| 24 namespace { |
| 25 typedef base::hash_map<std::string, BookmarkModel::URLAndTitle*> BookmarkMap; |
| 26 |
| 27 struct Context { |
| 28 history::HistoryService* history_service; |
| 29 base::CancelableTaskTracker* history_task_tracker; |
| 30 base::WaitableEvent finished; |
| 31 |
| 32 Context(history::HistoryService* hservice, |
| 33 base::CancelableTaskTracker* tracker) |
| 34 : history_service(hservice), |
| 35 history_task_tracker(tracker), |
| 36 finished(false, false) {} |
| 37 }; |
| 38 |
| 39 void UpdateUrl(Context* context, |
| 40 size_t position, |
| 41 std::vector<history_report::DeltaFileEntryWithData>* urls, |
| 42 bool success, |
| 43 const history::URLRow& url, |
| 44 const history::VisitVector& visits) { |
| 45 history_report::DeltaFileEntryWithData* entry = &((*urls)[position]); |
| 46 if (success) { |
| 47 entry->SetData(url); |
| 48 } else { |
| 49 LOG(WARNING) << "No data for url " << entry->Url(); |
| 50 } |
| 51 if (position + 1 == urls->size()) { |
| 52 context->finished.Signal(); |
| 53 } else { |
| 54 context->history_service->QueryURL(GURL((*urls)[position + 1].Url()), |
| 55 false, |
| 56 base::Bind(&UpdateUrl, |
| 57 base::Unretained(context), |
| 58 position + 1, |
| 59 base::Unretained(urls)), |
| 60 context->history_task_tracker); |
| 61 } |
| 62 } |
| 63 |
| 64 void QueryUrlsHistoryInUiThread( |
| 65 Context* context, |
| 66 std::vector<history_report::DeltaFileEntryWithData>* urls) { |
| 67 context->history_task_tracker->TryCancelAll(); |
| 68 // TODO(haaawk): change history service so that all this data can be |
| 69 // obtained with a single call to history service. |
| 70 context->history_service->QueryURL(GURL((*urls)[0].Url()), |
| 71 false, |
| 72 base::Bind(&UpdateUrl, |
| 73 base::Unretained(context), |
| 74 0, |
| 75 base::Unretained(urls)), |
| 76 context->history_task_tracker); |
| 77 } |
| 78 |
| 79 void StartVisitMigrationToUsageBufferUiThread( |
| 80 history::HistoryService* history_service, |
| 81 history_report::UsageReportsBufferService* buffer_service, |
| 82 base::WaitableEvent* finished, |
| 83 base::CancelableTaskTracker* task_tracker) { |
| 84 history_service->ScheduleDBTask( |
| 85 scoped_ptr<history::HistoryDBTask>( |
| 86 new history_report::HistoricVisitsMigrationTask(finished, |
| 87 buffer_service)), |
| 88 task_tracker); |
| 89 } |
| 90 |
| 91 } // namespace |
| 92 |
| 93 namespace history_report { |
| 94 |
| 95 DataProvider::DataProvider(Profile* profile, |
| 96 DeltaFileService* delta_file_service, |
| 97 BookmarkModel* bookmark_model) |
| 98 : bookmark_model_(bookmark_model), |
| 99 delta_file_service_(delta_file_service) { |
| 100 history_service_ = HistoryServiceFactory::GetForProfile( |
| 101 profile, ServiceAccessType::EXPLICIT_ACCESS); |
| 102 } |
| 103 |
| 104 DataProvider::~DataProvider() {} |
| 105 |
| 106 scoped_ptr<std::vector<DeltaFileEntryWithData> > DataProvider::Query( |
| 107 int64 last_seq_no, |
| 108 int32 limit) { |
| 109 if (last_seq_no == 0) |
| 110 RecreateLog(); |
| 111 scoped_ptr<std::vector<DeltaFileEntryWithData> > entries; |
| 112 scoped_ptr<std::vector<DeltaFileEntryWithData> > valid_entries; |
| 113 do { |
| 114 entries = delta_file_service_->Query(last_seq_no, limit); |
| 115 if (!entries->empty()) { |
| 116 Context context(history_service_, |
| 117 &history_task_tracker_); |
| 118 content::BrowserThread::PostTask( |
| 119 content::BrowserThread::UI, |
| 120 FROM_HERE, |
| 121 base::Bind(&QueryUrlsHistoryInUiThread, |
| 122 base::Unretained(&context), |
| 123 base::Unretained(entries.get()))); |
| 124 std::vector<BookmarkModel::URLAndTitle> bookmarks; |
| 125 bookmark_model_->BlockTillLoaded(); |
| 126 bookmark_model_->GetBookmarks(&bookmarks); |
| 127 BookmarkMap bookmark_map; |
| 128 for (size_t i = 0; i < bookmarks.size(); ++i) { |
| 129 bookmark_map.insert( |
| 130 make_pair(bookmarks[i].url.spec(), &bookmarks[i])); |
| 131 } |
| 132 context.finished.Wait(); |
| 133 for (size_t i = 0; i < entries->size(); ++i) { |
| 134 BookmarkMap::iterator bookmark = |
| 135 bookmark_map.find((*entries)[i].Url()); |
| 136 if (bookmark != bookmark_map.end()) |
| 137 (*entries)[i].MarkAsBookmark(*(bookmark->second)); |
| 138 } |
| 139 } |
| 140 |
| 141 valid_entries.reset(new std::vector<DeltaFileEntryWithData>()); |
| 142 valid_entries->reserve(entries->size()); |
| 143 for (size_t i = 0; i < entries->size(); ++i) { |
| 144 const DeltaFileEntryWithData& entry = (*entries)[i]; |
| 145 if (entry.Valid()) valid_entries->push_back(entry); |
| 146 if (entry.SeqNo() > last_seq_no) last_seq_no = entry.SeqNo(); |
| 147 } |
| 148 } while (!entries->empty() && valid_entries->empty()); |
| 149 return valid_entries.Pass(); |
| 150 } |
| 151 |
| 152 void DataProvider::StartVisitMigrationToUsageBuffer( |
| 153 UsageReportsBufferService* buffer_service) { |
| 154 base::WaitableEvent finished(false, false); |
| 155 buffer_service->Clear(); |
| 156 content::BrowserThread::PostTask( |
| 157 content::BrowserThread::UI, |
| 158 FROM_HERE, |
| 159 base::Bind(&StartVisitMigrationToUsageBufferUiThread, |
| 160 base::Unretained(history_service_), |
| 161 buffer_service, |
| 162 base::Unretained(&finished), |
| 163 base::Unretained(&history_task_tracker_))); |
| 164 finished.Wait(); |
| 165 } |
| 166 |
| 167 void DataProvider::RecreateLog() { |
| 168 std::vector<std::string> urls; |
| 169 { |
| 170 base::WaitableEvent finished(false, false); |
| 171 |
| 172 scoped_ptr<history::HistoryDBTask> task = |
| 173 scoped_ptr<history::HistoryDBTask>(new GetAllUrlsFromHistoryTask( |
| 174 &finished, &urls)); |
| 175 content::BrowserThread::PostTask( |
| 176 content::BrowserThread::UI, FROM_HERE, |
| 177 base::Bind(base::IgnoreResult(&history::HistoryService::ScheduleDBTask), |
| 178 base::Unretained(history_service_), base::Passed(&task), |
| 179 base::Unretained(&history_task_tracker_))); |
| 180 finished.Wait(); |
| 181 } |
| 182 |
| 183 std::vector<BookmarkModel::URLAndTitle> bookmarks; |
| 184 bookmark_model_->BlockTillLoaded(); |
| 185 bookmark_model_->GetBookmarks(&bookmarks); |
| 186 urls.reserve(urls.size() + bookmarks.size()); |
| 187 for (size_t i = 0; i < bookmarks.size(); i++) { |
| 188 urls.push_back(bookmarks[i].url.spec()); |
| 189 } |
| 190 delta_file_service_->Recreate(urls); |
| 191 } |
| 192 |
| 193 } // namespace history_report |
OLD | NEW |