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"
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
;
25 typedef base::hash_map
<std::string
, BookmarkModel::URLAndTitle
*> BookmarkMap
;
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
,
41 std::vector
<history_report::DeltaFileEntryWithData
>* urls
,
43 const history::URLRow
& url
,
44 const history::VisitVector
& visits
) {
45 history_report::DeltaFileEntryWithData
* entry
= &((*urls
)[position
]);
49 LOG(WARNING
) << "No data for url " << entry
->Url();
51 if (position
+ 1 == urls
->size()) {
52 context
->finished
.Signal();
54 context
->history_service
->QueryURL(GURL((*urls
)[position
+ 1].Url()),
56 base::Bind(&UpdateUrl
,
57 base::Unretained(context
),
59 base::Unretained(urls
)),
60 context
->history_task_tracker
);
64 void QueryUrlsHistoryInUiThread(
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()),
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
,
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(
109 if (last_seq_no
== 0)
111 scoped_ptr
<std::vector
<DeltaFileEntryWithData
> > entries
;
112 scoped_ptr
<std::vector
<DeltaFileEntryWithData
> > valid_entries
;
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
,
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
) {
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
,
159 base::Bind(&StartVisitMigrationToUsageBufferUiThread
,
160 base::Unretained(history_service_
),
162 base::Unretained(&finished
),
163 base::Unretained(&history_task_tracker_
)));
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(
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_
)));
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