| 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 |