Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / android / history_report / data_provider.cc
blobe2892793b5bb297109789657993f1463dbff04bc
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.
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"
22 using bookmarks::BookmarkModel;
24 namespace {
25 typedef base::hash_map<std::string, BookmarkModel::URLAndTitle*> BookmarkMap;
27 struct Context {
28 history::HistoryService* history_service;
29 base::CancelableTaskTracker* history_task_tracker;
30 base::WaitableEvent finished;
32 Context(history::HistoryService* hservice,
33 base::CancelableTaskTracker* tracker)
34 : history_service(hservice),
35 history_task_tracker(tracker),
36 finished(false, false) {}
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();
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);
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),
75 base::Unretained(urls)),
76 context->history_task_tracker);
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);
91 } // namespace
93 namespace history_report {
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);
104 DataProvider::~DataProvider() {}
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]));
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));
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();
148 } while (!entries->empty() && valid_entries->empty());
149 return valid_entries.Pass();
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();
167 void DataProvider::RecreateLog() {
168 std::vector<std::string> urls;
170 base::WaitableEvent finished(false, false);
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();
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());
190 delta_file_service_->Recreate(urls);
193 } // namespace history_report