Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(521)

Side by Side Diff: chrome/browser/extensions/extension_history_api.cc

Issue 8372021: Move history extension API implementation to history dir. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/extensions/extension_history_api.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/json/json_writer.h"
11 #include "base/message_loop.h"
12 #include "base/string_number_conversions.h"
13 #include "base/task.h"
14 #include "base/values.h"
15 #include "chrome/browser/extensions/extension_event_router.h"
16 #include "chrome/browser/extensions/extension_history_api_constants.h"
17 #include "chrome/browser/history/history.h"
18 #include "chrome/browser/history/history_types.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/common/chrome_notification_types.h"
21 #include "content/public/browser/notification_details.h"
22 #include "content/public/browser/notification_source.h"
23
24 namespace keys = extension_history_api_constants;
25
26 namespace {
27
28 double MilliSecondsFromTime(const base::Time& time) {
29 return 1000 * time.ToDoubleT();
30 }
31
32 void GetHistoryItemDictionary(const history::URLRow& row,
33 DictionaryValue* value) {
34 value->SetString(keys::kIdKey, base::Int64ToString(row.id()));
35 value->SetString(keys::kUrlKey, row.url().spec());
36 value->SetString(keys::kTitleKey, row.title());
37 value->SetDouble(keys::kLastVisitdKey,
38 MilliSecondsFromTime(row.last_visit()));
39 value->SetInteger(keys::kTypedCountKey, row.typed_count());
40 value->SetInteger(keys::kVisitCountKey, row.visit_count());
41 }
42
43 void AddHistoryNode(const history::URLRow& row, ListValue* list) {
44 DictionaryValue* dict = new DictionaryValue();
45 GetHistoryItemDictionary(row, dict);
46 list->Append(dict);
47 }
48
49 void GetVisitInfoDictionary(const history::VisitRow& row,
50 DictionaryValue* value) {
51 value->SetString(keys::kIdKey, base::Int64ToString(row.url_id));
52 value->SetString(keys::kVisitId, base::Int64ToString(row.visit_id));
53 value->SetDouble(keys::kVisitTime, MilliSecondsFromTime(row.visit_time));
54 value->SetString(keys::kReferringVisitId,
55 base::Int64ToString(row.referring_visit));
56
57 const char* trans =
58 content::PageTransitionGetCoreTransitionString(row.transition);
59 DCHECK(trans) << "Invalid transition.";
60 value->SetString(keys::kTransition, trans);
61 }
62
63 void AddVisitNode(const history::VisitRow& row, ListValue* list) {
64 DictionaryValue* dict = new DictionaryValue();
65 GetVisitInfoDictionary(row, dict);
66 list->Append(dict);
67 }
68
69 } // namespace
70
71 ExtensionHistoryEventRouter::ExtensionHistoryEventRouter() {}
72
73 ExtensionHistoryEventRouter::~ExtensionHistoryEventRouter() {}
74
75 void ExtensionHistoryEventRouter::ObserveProfile(Profile* profile) {
76 CHECK(registrar_.IsEmpty());
77 const content::Source<Profile> source = content::Source<Profile>(profile);
78 registrar_.Add(this,
79 chrome::NOTIFICATION_HISTORY_URL_VISITED,
80 source);
81 registrar_.Add(this,
82 chrome::NOTIFICATION_HISTORY_URLS_DELETED,
83 source);
84 }
85
86 void ExtensionHistoryEventRouter::Observe(
87 int type,
88 const content::NotificationSource& source,
89 const content::NotificationDetails& details) {
90 switch (type) {
91 case chrome::NOTIFICATION_HISTORY_URL_VISITED:
92 HistoryUrlVisited(
93 content::Source<Profile>(source).ptr(),
94 content::Details<const history::URLVisitedDetails>(details).ptr());
95 break;
96 case chrome::NOTIFICATION_HISTORY_URLS_DELETED:
97 HistoryUrlsRemoved(
98 content::Source<Profile>(source).ptr(),
99 content::Details<const history::URLsDeletedDetails>(details).ptr());
100 break;
101 default:
102 NOTREACHED();
103 }
104 }
105
106 void ExtensionHistoryEventRouter::HistoryUrlVisited(
107 Profile* profile,
108 const history::URLVisitedDetails* details) {
109 ListValue args;
110 DictionaryValue* dict = new DictionaryValue();
111 GetHistoryItemDictionary(details->row, dict);
112 args.Append(dict);
113
114 std::string json_args;
115 base::JSONWriter::Write(&args, false, &json_args);
116 DispatchEvent(profile, keys::kOnVisited, json_args);
117 }
118
119 void ExtensionHistoryEventRouter::HistoryUrlsRemoved(
120 Profile* profile,
121 const history::URLsDeletedDetails* details) {
122 ListValue args;
123 DictionaryValue* dict = new DictionaryValue();
124 dict->SetBoolean(keys::kAllHistoryKey, details->all_history);
125 ListValue* urls = new ListValue();
126 for (std::set<GURL>::const_iterator iterator = details->urls.begin();
127 iterator != details->urls.end();
128 ++iterator) {
129 urls->Append(new StringValue(iterator->spec()));
130 }
131 dict->Set(keys::kUrlsKey, urls);
132 args.Append(dict);
133
134 std::string json_args;
135 base::JSONWriter::Write(&args, false, &json_args);
136 DispatchEvent(profile, keys::kOnVisitRemoved, json_args);
137 }
138
139 void ExtensionHistoryEventRouter::DispatchEvent(Profile* profile,
140 const char* event_name,
141 const std::string& json_args) {
142 if (profile && profile->GetExtensionEventRouter()) {
143 profile->GetExtensionEventRouter()->DispatchEventToRenderers(
144 event_name, json_args, profile, GURL());
145 }
146 }
147
148 void HistoryFunction::Run() {
149 if (!RunImpl()) {
150 SendResponse(false);
151 }
152 }
153
154 bool HistoryFunction::GetUrlFromValue(Value* value, GURL* url) {
155 std::string url_string;
156 if (!value->GetAsString(&url_string)) {
157 bad_message_ = true;
158 return false;
159 }
160
161 GURL temp_url(url_string);
162 if (!temp_url.is_valid()) {
163 error_ = keys::kInvalidUrlError;
164 return false;
165 }
166 url->Swap(&temp_url);
167 return true;
168 }
169
170 bool HistoryFunction::GetTimeFromValue(Value* value, base::Time* time) {
171 double ms_from_epoch = 0.0;
172 if (!value->GetAsDouble(&ms_from_epoch))
173 return false;
174 // The history service has seconds resolution, while javascript Date() has
175 // milliseconds resolution.
176 double seconds_from_epoch = ms_from_epoch / 1000.0;
177 // Time::FromDoubleT converts double time 0 to empty Time object. So we need
178 // to do special handling here.
179 *time = (seconds_from_epoch == 0) ?
180 base::Time::UnixEpoch() : base::Time::FromDoubleT(seconds_from_epoch);
181 return true;
182 }
183
184 HistoryFunctionWithCallback::HistoryFunctionWithCallback() {
185 }
186
187 HistoryFunctionWithCallback::~HistoryFunctionWithCallback() {
188 }
189
190 bool HistoryFunctionWithCallback::RunImpl() {
191 AddRef(); // Balanced in SendAysncRepose() and below.
192 bool retval = RunAsyncImpl();
193 if (false == retval)
194 Release();
195 return retval;
196 }
197
198 void HistoryFunctionWithCallback::SendAsyncResponse() {
199 MessageLoop::current()->PostTask(
200 FROM_HERE,
201 NewRunnableMethod(
202 this,
203 &HistoryFunctionWithCallback::SendResponseToCallback));
204 }
205
206 void HistoryFunctionWithCallback::SendResponseToCallback() {
207 SendResponse(true);
208 Release(); // Balanced in RunImpl().
209 }
210
211 bool GetVisitsHistoryFunction::RunAsyncImpl() {
212 DictionaryValue* json;
213 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &json));
214
215 Value* value;
216 EXTENSION_FUNCTION_VALIDATE(json->Get(keys::kUrlKey, &value));
217
218 GURL url;
219 if (!GetUrlFromValue(value, &url))
220 return false;
221
222 HistoryService* hs = profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
223 hs->QueryURL(url,
224 true, // Retrieve full history of a URL.
225 &cancelable_consumer_,
226 base::Bind(&GetVisitsHistoryFunction::QueryComplete,
227 base::Unretained(this)));
228
229 return true;
230 }
231
232 void GetVisitsHistoryFunction::QueryComplete(
233 HistoryService::Handle request_service,
234 bool success,
235 const history::URLRow* url_row,
236 history::VisitVector* visits) {
237 ListValue* list = new ListValue();
238 if (visits && !visits->empty()) {
239 for (history::VisitVector::iterator iterator = visits->begin();
240 iterator != visits->end();
241 ++iterator) {
242 AddVisitNode(*iterator, list);
243 }
244 }
245 result_.reset(list);
246 SendAsyncResponse();
247 }
248
249 bool SearchHistoryFunction::RunAsyncImpl() {
250 DictionaryValue* json;
251 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &json));
252
253 // Initialize the HistoryQuery
254 string16 search_text;
255 EXTENSION_FUNCTION_VALIDATE(json->GetString(keys::kTextKey, &search_text));
256
257 history::QueryOptions options;
258 options.SetRecentDayRange(1);
259 options.max_count = 100;
260
261 if (json->HasKey(keys::kStartTimeKey)) { // Optional.
262 Value* value;
263 EXTENSION_FUNCTION_VALIDATE(json->Get(keys::kStartTimeKey, &value));
264 EXTENSION_FUNCTION_VALIDATE(GetTimeFromValue(value, &options.begin_time));
265 }
266 if (json->HasKey(keys::kEndTimeKey)) { // Optional.
267 Value* value;
268 EXTENSION_FUNCTION_VALIDATE(json->Get(keys::kEndTimeKey, &value));
269 EXTENSION_FUNCTION_VALIDATE(GetTimeFromValue(value, &options.end_time));
270 }
271 if (json->HasKey(keys::kMaxResultsKey)) { // Optional.
272 EXTENSION_FUNCTION_VALIDATE(json->GetInteger(keys::kMaxResultsKey,
273 &options.max_count));
274 }
275
276 HistoryService* hs = profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
277 hs->QueryHistory(search_text, options, &cancelable_consumer_,
278 base::Bind(&SearchHistoryFunction::SearchComplete,
279 base::Unretained(this)));
280
281 return true;
282 }
283
284 void SearchHistoryFunction::SearchComplete(
285 HistoryService::Handle request_handle,
286 history::QueryResults* results) {
287 ListValue* list = new ListValue();
288 if (results && !results->empty()) {
289 for (history::QueryResults::URLResultVector::const_iterator iterator =
290 results->begin();
291 iterator != results->end();
292 ++iterator) {
293 AddHistoryNode(**iterator, list);
294 }
295 }
296 result_.reset(list);
297 SendAsyncResponse();
298 }
299
300 bool AddUrlHistoryFunction::RunImpl() {
301 DictionaryValue* json;
302 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &json));
303
304 Value* value;
305 EXTENSION_FUNCTION_VALIDATE(json->Get(keys::kUrlKey, &value));
306
307 GURL url;
308 if (!GetUrlFromValue(value, &url))
309 return false;
310
311 HistoryService* hs = profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
312 hs->AddPage(url, history::SOURCE_EXTENSION);
313
314 SendResponse(true);
315 return true;
316 }
317
318 bool DeleteUrlHistoryFunction::RunImpl() {
319 DictionaryValue* json;
320 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &json));
321
322 Value* value;
323 EXTENSION_FUNCTION_VALIDATE(json->Get(keys::kUrlKey, &value));
324
325 GURL url;
326 if (!GetUrlFromValue(value, &url))
327 return false;
328
329 HistoryService* hs = profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
330 hs->DeleteURL(url);
331
332 SendResponse(true);
333 return true;
334 }
335
336 bool DeleteRangeHistoryFunction::RunAsyncImpl() {
337 DictionaryValue* json;
338 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &json));
339
340 Value* value = NULL;
341 EXTENSION_FUNCTION_VALIDATE(json->Get(keys::kStartTimeKey, &value));
342 base::Time begin_time;
343 EXTENSION_FUNCTION_VALIDATE(GetTimeFromValue(value, &begin_time));
344
345 EXTENSION_FUNCTION_VALIDATE(json->Get(keys::kEndTimeKey, &value));
346 base::Time end_time;
347 EXTENSION_FUNCTION_VALIDATE(GetTimeFromValue(value, &end_time));
348
349 std::set<GURL> restrict_urls;
350 HistoryService* hs = profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
351 hs->ExpireHistoryBetween(
352 restrict_urls,
353 begin_time,
354 end_time,
355 &cancelable_consumer_,
356 base::Bind(&DeleteRangeHistoryFunction::DeleteComplete,
357 base::Unretained(this)));
358
359 return true;
360 }
361
362 void DeleteRangeHistoryFunction::DeleteComplete() {
363 SendAsyncResponse();
364 }
365
366 bool DeleteAllHistoryFunction::RunAsyncImpl() {
367 std::set<GURL> restrict_urls;
368 HistoryService* hs = profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
369 hs->ExpireHistoryBetween(
370 restrict_urls,
371 base::Time::UnixEpoch(), // From the beginning of the epoch.
372 base::Time::Now(), // To the current time.
373 &cancelable_consumer_,
374 base::Bind(&DeleteAllHistoryFunction::DeleteComplete,
375 base::Unretained(this)));
376
377 return true;
378 }
379
380 void DeleteAllHistoryFunction::DeleteComplete() {
381 SendAsyncResponse();
382 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_history_api.h ('k') | chrome/browser/extensions/extension_history_api_constants.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698