OLD | NEW |
| (Empty) |
1 // Copyright (c) 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/browsing_data/history_counter.h" | |
6 | |
7 #include <limits.h> | |
8 #include <stdint.h> | |
9 | |
10 #include "base/memory/ptr_util.h" | |
11 #include "base/timer/timer.h" | |
12 #include "chrome/browser/history/history_service_factory.h" | |
13 #include "chrome/browser/history/web_history_service_factory.h" | |
14 #include "chrome/browser/profiles/profile.h" | |
15 #include "chrome/browser/sync/profile_sync_service_factory.h" | |
16 #include "components/browser_sync/browser/profile_sync_service.h" | |
17 #include "components/browsing_data/core/pref_names.h" | |
18 #include "components/history/core/browser/history_service.h" | |
19 #include "components/history/core/browser/web_history_service.h" | |
20 #include "content/public/browser/browser_thread.h" | |
21 | |
22 namespace { | |
23 static const int64_t kWebHistoryTimeoutSeconds = 10; | |
24 } | |
25 | |
26 HistoryCounter::HistoryCounter(Profile* profile) | |
27 : BrowsingDataCounter(browsing_data::prefs::kDeleteBrowsingHistory), | |
28 profile_(profile), | |
29 has_synced_visits_(false), | |
30 local_counting_finished_(false), | |
31 web_counting_finished_(false), | |
32 testing_web_history_service_(nullptr), | |
33 sync_service_(nullptr), | |
34 history_sync_enabled_(false), | |
35 weak_ptr_factory_(this) {} | |
36 | |
37 HistoryCounter::~HistoryCounter() { | |
38 if (sync_service_) | |
39 sync_service_->RemoveObserver(this); | |
40 } | |
41 | |
42 void HistoryCounter::OnInitialized() { | |
43 sync_service_ = ProfileSyncServiceFactory::GetForProfile(profile_); | |
44 if (sync_service_) | |
45 sync_service_->AddObserver(this); | |
46 history_sync_enabled_ = !!WebHistoryServiceFactory::GetForProfile(profile_); | |
47 } | |
48 | |
49 bool HistoryCounter::HasTrackedTasks() { | |
50 return cancelable_task_tracker_.HasTrackedTasks(); | |
51 } | |
52 | |
53 void HistoryCounter::SetWebHistoryServiceForTesting( | |
54 history::WebHistoryService* service) { | |
55 testing_web_history_service_ = service; | |
56 } | |
57 | |
58 void HistoryCounter::Count() { | |
59 // Reset the state. | |
60 cancelable_task_tracker_.TryCancelAll(); | |
61 web_history_request_.reset(); | |
62 has_synced_visits_ = false; | |
63 | |
64 // Count the locally stored items. | |
65 local_counting_finished_ = false; | |
66 | |
67 history::HistoryService* service = HistoryServiceFactory::GetForProfile( | |
68 profile_, ServiceAccessType::EXPLICIT_ACCESS); | |
69 | |
70 service->GetHistoryCount( | |
71 GetPeriodStart(), | |
72 base::Time::Max(), | |
73 base::Bind(&HistoryCounter::OnGetLocalHistoryCount, | |
74 weak_ptr_factory_.GetWeakPtr()), | |
75 &cancelable_task_tracker_); | |
76 | |
77 // If the history sync is enabled, test if there is at least one synced item. | |
78 // If the testing web history service is present, use that one instead. | |
79 history::WebHistoryService* web_history = | |
80 testing_web_history_service_ | |
81 ? testing_web_history_service_ | |
82 : WebHistoryServiceFactory::GetForProfile(profile_); | |
83 | |
84 if (!web_history) { | |
85 web_counting_finished_ = true; | |
86 return; | |
87 } | |
88 | |
89 web_counting_finished_ = false; | |
90 | |
91 web_history_timeout_.Start( | |
92 FROM_HERE, | |
93 base::TimeDelta::FromSeconds(kWebHistoryTimeoutSeconds), | |
94 this, | |
95 &HistoryCounter::OnWebHistoryTimeout); | |
96 | |
97 history::QueryOptions options; | |
98 options.max_count = 1; | |
99 options.begin_time = GetPeriodStart(); | |
100 options.end_time = base::Time::Max(); | |
101 web_history_request_ = web_history->QueryHistory( | |
102 base::string16(), | |
103 options, | |
104 base::Bind(&HistoryCounter::OnGetWebHistoryCount, | |
105 weak_ptr_factory_.GetWeakPtr())); | |
106 | |
107 // TODO(msramek): Include web history count when there is an API for it. | |
108 } | |
109 | |
110 void HistoryCounter::OnGetLocalHistoryCount( | |
111 history::HistoryCountResult result) { | |
112 // Ensure that all callbacks are on the same thread, so that we do not need | |
113 // a mutex for |MergeResults|. | |
114 DCHECK(thread_checker_.CalledOnValidThread()); | |
115 | |
116 if (!result.success) { | |
117 LOG(ERROR) << "Failed to count the local history."; | |
118 return; | |
119 } | |
120 | |
121 local_result_ = result.count; | |
122 local_counting_finished_ = true; | |
123 MergeResults(); | |
124 } | |
125 | |
126 void HistoryCounter::OnGetWebHistoryCount( | |
127 history::WebHistoryService::Request* request, | |
128 const base::DictionaryValue* result) { | |
129 // Ensure that all callbacks are on the same thread, so that we do not need | |
130 // a mutex for |MergeResults|. | |
131 DCHECK(thread_checker_.CalledOnValidThread()); | |
132 | |
133 // If the timeout for this request already fired, ignore the result. | |
134 if (!web_history_timeout_.IsRunning()) | |
135 return; | |
136 | |
137 web_history_timeout_.Stop(); | |
138 | |
139 // If the query failed, err on the safe side and inform the user that they | |
140 // may have history items stored in Sync. Otherwise, we expect at least one | |
141 // entry in the "event" list. | |
142 const base::ListValue* events; | |
143 has_synced_visits_ = | |
144 !result || | |
145 (result->GetList("event", &events) && !events->empty()); | |
146 web_counting_finished_ = true; | |
147 MergeResults(); | |
148 } | |
149 | |
150 void HistoryCounter::OnWebHistoryTimeout() { | |
151 // Ensure that all callbacks are on the same thread, so that we do not need | |
152 // a mutex for |MergeResults|. | |
153 DCHECK(thread_checker_.CalledOnValidThread()); | |
154 | |
155 // If the query timed out, err on the safe side and inform the user that they | |
156 // may have history items stored in Sync. | |
157 web_history_request_.reset(); | |
158 has_synced_visits_ = true; | |
159 web_counting_finished_ = true; | |
160 MergeResults(); | |
161 } | |
162 | |
163 void HistoryCounter::MergeResults() { | |
164 if (!local_counting_finished_ || !web_counting_finished_) | |
165 return; | |
166 | |
167 ReportResult(base::WrapUnique( | |
168 new HistoryResult(this, local_result_, has_synced_visits_))); | |
169 } | |
170 | |
171 HistoryCounter::HistoryResult::HistoryResult( | |
172 const HistoryCounter* source, | |
173 ResultInt value, | |
174 bool has_synced_visits) | |
175 : FinishedResult(source, value), | |
176 has_synced_visits_(has_synced_visits) { | |
177 } | |
178 | |
179 HistoryCounter::HistoryResult::~HistoryResult() { | |
180 } | |
181 | |
182 void HistoryCounter::OnStateChanged() { | |
183 bool history_sync_enabled_new_state = | |
184 !!WebHistoryServiceFactory::GetForProfile(profile_); | |
185 | |
186 // If the history sync was just enabled or disabled, restart the counter | |
187 // so that we update the result accordingly. | |
188 if (history_sync_enabled_ != history_sync_enabled_new_state) { | |
189 history_sync_enabled_ = history_sync_enabled_new_state; | |
190 Restart(); | |
191 } | |
192 } | |
OLD | NEW |