OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/api/history/history_api.h" | 5 #include "chrome/browser/extensions/api/history/history_api.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 } | 212 } |
213 | 213 |
214 void HistoryAPI::OnListenerAdded(const EventListenerInfo& details) { | 214 void HistoryAPI::OnListenerAdded(const EventListenerInfo& details) { |
215 Profile* profile = Profile::FromBrowserContext(browser_context_); | 215 Profile* profile = Profile::FromBrowserContext(browser_context_); |
216 history_event_router_.reset(new HistoryEventRouter( | 216 history_event_router_.reset(new HistoryEventRouter( |
217 profile, HistoryServiceFactory::GetForProfile( | 217 profile, HistoryServiceFactory::GetForProfile( |
218 profile, ServiceAccessType::EXPLICIT_ACCESS))); | 218 profile, ServiceAccessType::EXPLICIT_ACCESS))); |
219 EventRouter::Get(browser_context_)->UnregisterObserver(this); | 219 EventRouter::Get(browser_context_)->UnregisterObserver(this); |
220 } | 220 } |
221 | 221 |
222 bool HistoryFunction::ValidateUrl(const std::string& url_string, GURL* url) { | 222 bool HistoryFunction::ValidateUrl(const std::string& url_string, |
| 223 GURL* url, |
| 224 std::string* error) { |
223 GURL temp_url(url_string); | 225 GURL temp_url(url_string); |
224 if (!temp_url.is_valid()) { | 226 if (!temp_url.is_valid()) { |
225 error_ = kInvalidUrlError; | 227 *error = kInvalidUrlError; |
226 return false; | 228 return false; |
227 } | 229 } |
228 url->Swap(&temp_url); | 230 url->Swap(&temp_url); |
229 return true; | 231 return true; |
230 } | 232 } |
231 | 233 |
232 bool HistoryFunction::VerifyDeleteAllowed() { | 234 bool HistoryFunction::VerifyDeleteAllowed(std::string* error) { |
233 PrefService* prefs = GetProfile()->GetPrefs(); | 235 PrefService* prefs = GetProfile()->GetPrefs(); |
234 if (!prefs->GetBoolean(prefs::kAllowDeletingBrowserHistory)) { | 236 if (!prefs->GetBoolean(prefs::kAllowDeletingBrowserHistory)) { |
235 error_ = kDeleteProhibitedError; | 237 *error = kDeleteProhibitedError; |
236 return false; | 238 return false; |
237 } | 239 } |
238 return true; | 240 return true; |
239 } | 241 } |
240 | 242 |
241 base::Time HistoryFunction::GetTime(double ms_from_epoch) { | 243 base::Time HistoryFunction::GetTime(double ms_from_epoch) { |
242 // The history service has seconds resolution, while javascript Date() has | 244 // The history service has seconds resolution, while javascript Date() has |
243 // milliseconds resolution. | 245 // milliseconds resolution. |
244 double seconds_from_epoch = ms_from_epoch / 1000.0; | 246 double seconds_from_epoch = ms_from_epoch / 1000.0; |
245 // Time::FromDoubleT converts double time 0 to empty Time object. So we need | 247 // Time::FromDoubleT converts double time 0 to empty Time object. So we need |
246 // to do special handling here. | 248 // to do special handling here. |
247 return (seconds_from_epoch == 0) ? | 249 return (seconds_from_epoch == 0) ? |
248 base::Time::UnixEpoch() : base::Time::FromDoubleT(seconds_from_epoch); | 250 base::Time::UnixEpoch() : base::Time::FromDoubleT(seconds_from_epoch); |
249 } | 251 } |
250 | 252 |
251 HistoryFunctionWithCallback::HistoryFunctionWithCallback() { | 253 Profile* HistoryFunction::GetProfile() const { |
| 254 return Profile::FromBrowserContext(browser_context()); |
252 } | 255 } |
253 | 256 |
254 HistoryFunctionWithCallback::~HistoryFunctionWithCallback() { | 257 HistoryFunctionWithCallback::HistoryFunctionWithCallback() {} |
255 } | |
256 | 258 |
257 bool HistoryFunctionWithCallback::RunAsync() { | 259 HistoryFunctionWithCallback::~HistoryFunctionWithCallback() {} |
258 AddRef(); // Balanced in SendAysncRepose() and below. | |
259 bool retval = RunAsyncImpl(); | |
260 if (false == retval) | |
261 Release(); | |
262 return retval; | |
263 } | |
264 | 260 |
265 void HistoryFunctionWithCallback::SendAsyncResponse() { | 261 ExtensionFunction::ResponseAction HistoryGetVisitsFunction::Run() { |
266 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
267 FROM_HERE, | |
268 base::Bind(&HistoryFunctionWithCallback::SendResponseToCallback, this)); | |
269 } | |
270 | |
271 void HistoryFunctionWithCallback::SendResponseToCallback() { | |
272 SendResponse(true); | |
273 Release(); // Balanced in RunAsync(). | |
274 } | |
275 | |
276 bool HistoryGetVisitsFunction::RunAsyncImpl() { | |
277 std::unique_ptr<GetVisits::Params> params(GetVisits::Params::Create(*args_)); | 262 std::unique_ptr<GetVisits::Params> params(GetVisits::Params::Create(*args_)); |
278 EXTENSION_FUNCTION_VALIDATE(params.get()); | 263 EXTENSION_FUNCTION_VALIDATE(params.get()); |
279 | 264 |
280 GURL url; | 265 GURL url; |
281 if (!ValidateUrl(params->details.url, &url)) | 266 std::string error; |
282 return false; | 267 if (!ValidateUrl(params->details.url, &url, &error)) |
| 268 return RespondNow(Error(error)); |
283 | 269 |
284 history::HistoryService* hs = HistoryServiceFactory::GetForProfile( | 270 history::HistoryService* hs = HistoryServiceFactory::GetForProfile( |
285 GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); | 271 GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); |
286 hs->QueryURL(url, | 272 hs->QueryURL(url, |
287 true, // Retrieve full history of a URL. | 273 true, // Retrieve full history of a URL. |
288 base::Bind(&HistoryGetVisitsFunction::QueryComplete, | 274 base::Bind(&HistoryGetVisitsFunction::QueryComplete, |
289 base::Unretained(this)), | 275 base::Unretained(this)), |
290 &task_tracker_); | 276 &task_tracker_); |
291 return true; | 277 AddRef(); // Balanced in QueryComplete(). |
| 278 return RespondLater(); // QueryComplete() will be called asynchronously. |
292 } | 279 } |
293 | 280 |
294 void HistoryGetVisitsFunction::QueryComplete( | 281 void HistoryGetVisitsFunction::QueryComplete( |
295 bool success, | 282 bool success, |
296 const history::URLRow& url_row, | 283 const history::URLRow& url_row, |
297 const history::VisitVector& visits) { | 284 const history::VisitVector& visits) { |
298 VisitItemList visit_item_vec; | 285 VisitItemList visit_item_vec; |
299 if (success && !visits.empty()) { | 286 if (success && !visits.empty()) { |
300 for (const history::VisitRow& visit : visits) | 287 for (const history::VisitRow& visit : visits) |
301 visit_item_vec.push_back(GetVisitItem(visit)); | 288 visit_item_vec.push_back(GetVisitItem(visit)); |
302 } | 289 } |
303 | 290 |
304 results_ = GetVisits::Results::Create(visit_item_vec); | 291 Respond(ArgumentList(GetVisits::Results::Create(visit_item_vec))); |
305 SendAsyncResponse(); | 292 Release(); // Balanced in Run(). |
306 } | 293 } |
307 | 294 |
308 bool HistorySearchFunction::RunAsyncImpl() { | 295 ExtensionFunction::ResponseAction HistorySearchFunction::Run() { |
309 std::unique_ptr<Search::Params> params(Search::Params::Create(*args_)); | 296 std::unique_ptr<Search::Params> params(Search::Params::Create(*args_)); |
310 EXTENSION_FUNCTION_VALIDATE(params.get()); | 297 EXTENSION_FUNCTION_VALIDATE(params.get()); |
311 | 298 |
312 base::string16 search_text = base::UTF8ToUTF16(params->query.text); | 299 base::string16 search_text = base::UTF8ToUTF16(params->query.text); |
313 | 300 |
314 history::QueryOptions options; | 301 history::QueryOptions options; |
315 options.SetRecentDayRange(1); | 302 options.SetRecentDayRange(1); |
316 options.max_count = 100; | 303 options.max_count = 100; |
317 | 304 |
318 if (params->query.start_time.get()) | 305 if (params->query.start_time.get()) |
319 options.begin_time = GetTime(*params->query.start_time); | 306 options.begin_time = GetTime(*params->query.start_time); |
320 if (params->query.end_time.get()) | 307 if (params->query.end_time.get()) |
321 options.end_time = GetTime(*params->query.end_time); | 308 options.end_time = GetTime(*params->query.end_time); |
322 if (params->query.max_results.get()) | 309 if (params->query.max_results.get()) |
323 options.max_count = *params->query.max_results; | 310 options.max_count = *params->query.max_results; |
324 | 311 |
325 history::HistoryService* hs = HistoryServiceFactory::GetForProfile( | 312 history::HistoryService* hs = HistoryServiceFactory::GetForProfile( |
326 GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); | 313 GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); |
327 hs->QueryHistory(search_text, | 314 hs->QueryHistory(search_text, |
328 options, | 315 options, |
329 base::Bind(&HistorySearchFunction::SearchComplete, | 316 base::Bind(&HistorySearchFunction::SearchComplete, |
330 base::Unretained(this)), | 317 base::Unretained(this)), |
331 &task_tracker_); | 318 &task_tracker_); |
332 | 319 |
333 return true; | 320 AddRef(); // Balanced in SearchComplete(). |
| 321 return RespondLater(); // SearchComplete() will be called asynchronously. |
334 } | 322 } |
335 | 323 |
336 void HistorySearchFunction::SearchComplete(history::QueryResults* results) { | 324 void HistorySearchFunction::SearchComplete(history::QueryResults* results) { |
337 HistoryItemList history_item_vec; | 325 HistoryItemList history_item_vec; |
338 if (results && !results->empty()) { | 326 if (results && !results->empty()) { |
339 for (const history::URLResult* item : *results) | 327 for (const history::URLResult* item : *results) |
340 history_item_vec.push_back(GetHistoryItem(*item)); | 328 history_item_vec.push_back(GetHistoryItem(*item)); |
341 } | 329 } |
342 results_ = Search::Results::Create(history_item_vec); | 330 Respond(ArgumentList(Search::Results::Create(history_item_vec))); |
343 SendAsyncResponse(); | 331 Release(); // Balanced in Run(). |
344 } | 332 } |
345 | 333 |
346 bool HistoryAddUrlFunction::RunAsync() { | 334 ExtensionFunction::ResponseAction HistoryAddUrlFunction::Run() { |
347 std::unique_ptr<AddUrl::Params> params(AddUrl::Params::Create(*args_)); | 335 std::unique_ptr<AddUrl::Params> params(AddUrl::Params::Create(*args_)); |
348 EXTENSION_FUNCTION_VALIDATE(params.get()); | 336 EXTENSION_FUNCTION_VALIDATE(params.get()); |
349 | 337 |
350 GURL url; | 338 GURL url; |
351 if (!ValidateUrl(params->details.url, &url)) | 339 std::string error; |
352 return false; | 340 if (!ValidateUrl(params->details.url, &url, &error)) |
| 341 return RespondNow(Error(error)); |
353 | 342 |
354 history::HistoryService* hs = HistoryServiceFactory::GetForProfile( | 343 history::HistoryService* hs = HistoryServiceFactory::GetForProfile( |
355 GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); | 344 GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); |
356 hs->AddPage(url, base::Time::Now(), history::SOURCE_EXTENSION); | 345 hs->AddPage(url, base::Time::Now(), history::SOURCE_EXTENSION); |
357 | 346 |
358 SendResponse(true); | 347 return RespondNow(NoArguments()); |
359 return true; | |
360 } | 348 } |
361 | 349 |
362 bool HistoryDeleteUrlFunction::RunAsync() { | 350 ExtensionFunction::ResponseAction HistoryDeleteUrlFunction::Run() { |
363 std::unique_ptr<DeleteUrl::Params> params(DeleteUrl::Params::Create(*args_)); | 351 std::unique_ptr<DeleteUrl::Params> params(DeleteUrl::Params::Create(*args_)); |
364 EXTENSION_FUNCTION_VALIDATE(params.get()); | 352 EXTENSION_FUNCTION_VALIDATE(params.get()); |
365 | 353 |
366 if (!VerifyDeleteAllowed()) | 354 std::string error; |
367 return false; | 355 if (!VerifyDeleteAllowed(&error)) |
| 356 return RespondNow(Error(error)); |
368 | 357 |
369 GURL url; | 358 GURL url; |
370 if (!ValidateUrl(params->details.url, &url)) | 359 if (!ValidateUrl(params->details.url, &url, &error)) |
371 return false; | 360 return RespondNow(Error(error)); |
372 | 361 |
373 history::HistoryService* hs = HistoryServiceFactory::GetForProfile( | 362 history::HistoryService* hs = HistoryServiceFactory::GetForProfile( |
374 GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); | 363 GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); |
375 hs->DeleteURL(url); | 364 hs->DeleteURL(url); |
376 | 365 |
377 // Also clean out from the activity log. If the activity log testing flag is | 366 // Also clean out from the activity log. If the activity log testing flag is |
378 // set then don't clean so testers can see what potentially malicious | 367 // set then don't clean so testers can see what potentially malicious |
379 // extensions have been trying to clean from their logs. | 368 // extensions have been trying to clean from their logs. |
380 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | 369 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
381 switches::kEnableExtensionActivityLogTesting)) { | 370 switches::kEnableExtensionActivityLogTesting)) { |
382 ActivityLog* activity_log = ActivityLog::GetInstance(GetProfile()); | 371 ActivityLog* activity_log = ActivityLog::GetInstance(GetProfile()); |
383 DCHECK(activity_log); | 372 DCHECK(activity_log); |
384 activity_log->RemoveURL(url); | 373 activity_log->RemoveURL(url); |
385 } | 374 } |
386 | 375 |
387 SendResponse(true); | 376 return RespondNow(NoArguments()); |
388 return true; | |
389 } | 377 } |
390 | 378 |
391 bool HistoryDeleteRangeFunction::RunAsyncImpl() { | 379 ExtensionFunction::ResponseAction HistoryDeleteRangeFunction::Run() { |
392 std::unique_ptr<DeleteRange::Params> params( | 380 std::unique_ptr<DeleteRange::Params> params( |
393 DeleteRange::Params::Create(*args_)); | 381 DeleteRange::Params::Create(*args_)); |
394 EXTENSION_FUNCTION_VALIDATE(params.get()); | 382 EXTENSION_FUNCTION_VALIDATE(params.get()); |
395 | 383 |
396 if (!VerifyDeleteAllowed()) | 384 std::string error; |
397 return false; | 385 if (!VerifyDeleteAllowed(&error)) |
| 386 return RespondNow(Error(error)); |
398 | 387 |
399 base::Time start_time = GetTime(params->range.start_time); | 388 base::Time start_time = GetTime(params->range.start_time); |
400 base::Time end_time = GetTime(params->range.end_time); | 389 base::Time end_time = GetTime(params->range.end_time); |
401 | 390 |
402 std::set<GURL> restrict_urls; | 391 std::set<GURL> restrict_urls; |
403 history::HistoryService* hs = HistoryServiceFactory::GetForProfile( | 392 history::HistoryService* hs = HistoryServiceFactory::GetForProfile( |
404 GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); | 393 GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); |
405 hs->ExpireHistoryBetween( | 394 hs->ExpireHistoryBetween( |
406 restrict_urls, | 395 restrict_urls, |
407 start_time, | 396 start_time, |
408 end_time, | 397 end_time, |
409 base::Bind(&HistoryDeleteRangeFunction::DeleteComplete, | 398 base::Bind(&HistoryDeleteRangeFunction::DeleteComplete, |
410 base::Unretained(this)), | 399 base::Unretained(this)), |
411 &task_tracker_); | 400 &task_tracker_); |
412 | 401 |
413 // Also clean from the activity log unless in testing mode. | 402 // Also clean from the activity log unless in testing mode. |
414 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | 403 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
415 switches::kEnableExtensionActivityLogTesting)) { | 404 switches::kEnableExtensionActivityLogTesting)) { |
416 ActivityLog* activity_log = ActivityLog::GetInstance(GetProfile()); | 405 ActivityLog* activity_log = ActivityLog::GetInstance(GetProfile()); |
417 DCHECK(activity_log); | 406 DCHECK(activity_log); |
418 activity_log->RemoveURLs(restrict_urls); | 407 activity_log->RemoveURLs(restrict_urls); |
419 } | 408 } |
420 | 409 |
421 return true; | 410 AddRef(); // Balanced in DeleteComplete(). |
| 411 return RespondLater(); // DeleteComplete() will be called asynchronously. |
422 } | 412 } |
423 | 413 |
424 void HistoryDeleteRangeFunction::DeleteComplete() { | 414 void HistoryDeleteRangeFunction::DeleteComplete() { |
425 SendAsyncResponse(); | 415 Respond(NoArguments()); |
| 416 Release(); // Balanced in Run(). |
426 } | 417 } |
427 | 418 |
428 bool HistoryDeleteAllFunction::RunAsyncImpl() { | 419 ExtensionFunction::ResponseAction HistoryDeleteAllFunction::Run() { |
429 if (!VerifyDeleteAllowed()) | 420 std::string error; |
430 return false; | 421 if (!VerifyDeleteAllowed(&error)) |
| 422 return RespondNow(Error(error)); |
431 | 423 |
432 std::set<GURL> restrict_urls; | 424 std::set<GURL> restrict_urls; |
433 history::HistoryService* hs = HistoryServiceFactory::GetForProfile( | 425 history::HistoryService* hs = HistoryServiceFactory::GetForProfile( |
434 GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); | 426 GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); |
435 hs->ExpireHistoryBetween( | 427 hs->ExpireHistoryBetween( |
436 restrict_urls, | 428 restrict_urls, |
437 base::Time(), // Unbounded beginning... | 429 base::Time(), // Unbounded beginning... |
438 base::Time(), // ...and the end. | 430 base::Time(), // ...and the end. |
439 base::Bind(&HistoryDeleteAllFunction::DeleteComplete, | 431 base::Bind(&HistoryDeleteAllFunction::DeleteComplete, |
440 base::Unretained(this)), | 432 base::Unretained(this)), |
441 &task_tracker_); | 433 &task_tracker_); |
442 | 434 |
443 // Also clean from the activity log unless in testing mode. | 435 // Also clean from the activity log unless in testing mode. |
444 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( | 436 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( |
445 switches::kEnableExtensionActivityLogTesting)) { | 437 switches::kEnableExtensionActivityLogTesting)) { |
446 ActivityLog* activity_log = ActivityLog::GetInstance(GetProfile()); | 438 ActivityLog* activity_log = ActivityLog::GetInstance(GetProfile()); |
447 DCHECK(activity_log); | 439 DCHECK(activity_log); |
448 activity_log->RemoveURLs(restrict_urls); | 440 activity_log->RemoveURLs(restrict_urls); |
449 } | 441 } |
450 | 442 |
451 return true; | 443 AddRef(); // Balanced in DeleteComplete(). |
| 444 return RespondLater(); // DeleteComplete() will be called asynchronously. |
452 } | 445 } |
453 | 446 |
454 void HistoryDeleteAllFunction::DeleteComplete() { | 447 void HistoryDeleteAllFunction::DeleteComplete() { |
455 SendAsyncResponse(); | 448 Respond(NoArguments()); |
| 449 Release(); // Balanced in Run(). |
456 } | 450 } |
457 | 451 |
458 } // namespace extensions | 452 } // namespace extensions |
OLD | NEW |