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

Side by Side Diff: chrome/browser/extensions/api/downloads/downloads_api.cc

Issue 10639020: Switch the downloads API over to IDL/json_schema_compiler (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 5 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
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/downloads/downloads_api.h" 5 #include "chrome/browser/extensions/api/downloads/downloads_api.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cctype> 8 #include <cctype>
9 #include <iterator> 9 #include <iterator>
10 #include <set> 10 #include <set>
(...skipping 20 matching lines...) Expand all
31 #include "chrome/browser/download/download_service_factory.h" 31 #include "chrome/browser/download/download_service_factory.h"
32 #include "chrome/browser/download/download_util.h" 32 #include "chrome/browser/download/download_util.h"
33 #include "chrome/browser/extensions/extension_event_names.h" 33 #include "chrome/browser/extensions/extension_event_names.h"
34 #include "chrome/browser/extensions/extension_event_router.h" 34 #include "chrome/browser/extensions/extension_event_router.h"
35 #include "chrome/browser/icon_loader.h" 35 #include "chrome/browser/icon_loader.h"
36 #include "chrome/browser/icon_manager.h" 36 #include "chrome/browser/icon_manager.h"
37 #include "chrome/browser/renderer_host/chrome_render_message_filter.h" 37 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
38 #include "chrome/browser/ui/browser.h" 38 #include "chrome/browser/ui/browser.h"
39 #include "chrome/browser/ui/webui/web_ui_util.h" 39 #include "chrome/browser/ui/webui/web_ui_util.h"
40 #include "chrome/common/chrome_notification_types.h" 40 #include "chrome/common/chrome_notification_types.h"
41 #include "chrome/common/extensions/api/downloads.h"
41 #include "content/public/browser/download_interrupt_reasons.h" 42 #include "content/public/browser/download_interrupt_reasons.h"
42 #include "content/public/browser/download_item.h" 43 #include "content/public/browser/download_item.h"
43 #include "content/public/browser/download_save_info.h" 44 #include "content/public/browser/download_save_info.h"
45 #include "content/public/browser/download_url_parameters.h"
44 #include "content/public/browser/notification_service.h" 46 #include "content/public/browser/notification_service.h"
45 #include "content/public/browser/render_process_host.h" 47 #include "content/public/browser/render_process_host.h"
46 #include "content/public/browser/render_view_host.h" 48 #include "content/public/browser/render_view_host.h"
47 #include "content/public/browser/resource_context.h" 49 #include "content/public/browser/resource_context.h"
48 #include "content/public/browser/resource_dispatcher_host.h" 50 #include "content/public/browser/resource_dispatcher_host.h"
49 #include "net/base/load_flags.h" 51 #include "net/base/load_flags.h"
50 #include "net/http/http_util.h" 52 #include "net/http/http_util.h"
51 #include "net/url_request/url_request.h" 53 #include "net/url_request/url_request.h"
52 54
53 using content::BrowserContext; 55 using content::BrowserContext;
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 bool include_incognito, 319 bool include_incognito,
318 DownloadManager** manager, DownloadManager** incognito_manager) { 320 DownloadManager** manager, DownloadManager** incognito_manager) {
319 *manager = BrowserContext::GetDownloadManager(profile); 321 *manager = BrowserContext::GetDownloadManager(profile);
320 *incognito_manager = NULL; 322 *incognito_manager = NULL;
321 if (include_incognito && profile->HasOffTheRecordProfile()) { 323 if (include_incognito && profile->HasOffTheRecordProfile()) {
322 *incognito_manager = BrowserContext::GetDownloadManager( 324 *incognito_manager = BrowserContext::GetDownloadManager(
323 profile->GetOffTheRecordProfile()); 325 profile->GetOffTheRecordProfile());
324 } 326 }
325 } 327 }
326 328
327 DownloadItem* GetActiveItemInternal( 329 DownloadItem* GetActiveItem(Profile* profile, bool include_incognito, int id) {
328 Profile* profile,
329 bool include_incognito,
330 int id) {
331 DownloadManager* manager = NULL; 330 DownloadManager* manager = NULL;
332 DownloadManager* incognito_manager = NULL; 331 DownloadManager* incognito_manager = NULL;
333 GetManagers(profile, include_incognito, &manager, &incognito_manager); 332 GetManagers(profile, include_incognito, &manager, &incognito_manager);
334 DownloadItem* download_item = manager->GetActiveDownloadItem(id); 333 DownloadItem* download_item = manager->GetActiveDownloadItem(id);
335 if (!download_item && incognito_manager) 334 if (!download_item && incognito_manager)
336 download_item = incognito_manager->GetActiveDownloadItem(id); 335 download_item = incognito_manager->GetActiveDownloadItem(id);
337 return download_item; 336 return download_item;
338 } 337 }
339 338
339 enum DownloadsFunctionName {
340 DOWNLOADS_FUNCTION_DOWNLOAD = 0,
341 DOWNLOADS_FUNCTION_SEARCH = 1,
342 DOWNLOADS_FUNCTION_PAUSE = 2,
343 DOWNLOADS_FUNCTION_RESUME = 3,
344 DOWNLOADS_FUNCTION_CANCEL = 4,
345 DOWNLOADS_FUNCTION_ERASE = 5,
346 DOWNLOADS_FUNCTION_SET_DESTINATION = 6,
347 DOWNLOADS_FUNCTION_ACCEPT_DANGER = 7,
348 DOWNLOADS_FUNCTION_SHOW = 8,
349 DOWNLOADS_FUNCTION_DRAG = 9,
350 DOWNLOADS_FUNCTION_GET_FILE_ICON = 10,
351 DOWNLOADS_FUNCTION_OPEN = 11,
352 // Insert new values here, not at the beginning.
353 DOWNLOADS_FUNCTION_LAST
354 };
355
356 void RecordApiFunctions(DownloadsFunctionName function) {
357 UMA_HISTOGRAM_ENUMERATION("Download.ApiFunctions",
358 function,
359 DOWNLOADS_FUNCTION_LAST);
360 }
361
362 void CompileDownloadQueryOrderBy(
363 const std::string& order_by_str, std::string* error, DownloadQuery* query) {
364 static base::LazyInstance<SortTypeMap> sorter_types =
asargent_no_longer_on_chrome 2012/07/02 23:43:48 nit: Why have this as a lazy instance static data
benjhayden 2012/07/09 20:18:09 I'd love to use a switch statement, but C++ doesn'
asargent_no_longer_on_chrome 2012/07/09 22:09:43 It's probably not a huge deal either way. But that
benjhayden 2012/07/10 18:32:04 Added a TODO to switch to string comparisons. I'll
365 LAZY_INSTANCE_INITIALIZER;
366 if (sorter_types.Get().size() == 0)
367 InitSortTypeMap(sorter_types.Get());
368
369 std::vector<std::string> order_by_strs;
370 base::SplitString(order_by_str, ' ', &order_by_strs);
371 for (std::vector<std::string>::const_iterator iter = order_by_strs.begin();
372 iter != order_by_strs.end(); ++iter) {
373 std::string term_str = *iter;
374 if (term_str.empty())
375 continue;
376 DownloadQuery::SortDirection direction = DownloadQuery::ASCENDING;
377 if (term_str[0] == '-') {
378 direction = DownloadQuery::DESCENDING;
379 term_str = term_str.substr(1);
380 }
381 SortTypeMap::const_iterator sorter_type =
382 sorter_types.Get().find(term_str);
383 if (sorter_type == sorter_types.Get().end()) {
384 *error = download_extension_errors::kInvalidOrderByError;
385 return;
386 }
387 query->AddSorter(sorter_type->second, direction);
388 }
389 }
390
391 void RunDownloadQuery(
392 const extensions::api::downloads::DownloadQuery& query_in,
393 Profile* profile,
394 bool include_incognito,
395 std::string* error,
396 DownloadQuery::DownloadVector* results) {
397 static base::LazyInstance<FilterTypeMap> filter_types =
asargent_no_longer_on_chrome 2012/07/02 23:43:48 same nit here - no need for a static lazy instance
benjhayden 2012/07/09 20:18:09 Same response.
398 LAZY_INSTANCE_INITIALIZER;
399 if (filter_types.Get().size() == 0)
400 InitFilterTypeMap(filter_types.Get());
401
402 DownloadQuery query_out;
403
404 if (query_in.limit.get()) {
405 if (*query_in.limit.get() < 0) {
406 *error = download_extension_errors::kInvalidQueryLimit;
407 return;
408 }
409 query_out.Limit(*query_in.limit.get());
410 }
411 if (query_in.state.get()) {
412 DownloadItem::DownloadState state = StateEnumFromString(
413 *query_in.state.get());
414 if (state == DownloadItem::MAX_DOWNLOAD_STATE) {
415 *error = download_extension_errors::kInvalidStateError;
416 return;
417 }
418 query_out.AddFilter(state);
419 }
420 if (query_in.danger.get()) {
421 content::DownloadDangerType danger_type =
422 DangerEnumFromString(*query_in.danger.get());
423 if (danger_type == content::DOWNLOAD_DANGER_TYPE_MAX) {
424 *error = download_extension_errors::kInvalidDangerTypeError;
425 return;
426 }
427 query_out.AddFilter(danger_type);
428 }
429 if (query_in.order_by.get()) {
430 CompileDownloadQueryOrderBy(*query_in.order_by.get(), error, &query_out);
431 if (!error->empty())
432 return;
433 }
434
435 scoped_ptr<base::DictionaryValue> query_in_value(query_in.ToValue().Pass());
436 for (base::DictionaryValue::Iterator query_json_field(*query_in_value.get());
437 query_json_field.HasNext(); query_json_field.Advance()) {
438 FilterTypeMap::const_iterator filter_type =
439 filter_types.Get().find(query_json_field.key());
440 if (filter_type != filter_types.Get().end()) {
441 if (!query_out.AddFilter(filter_type->second, query_json_field.value())) {
442 *error = download_extension_errors::kInvalidFilterError;
443 return;
444 }
445 }
446 }
447
448 DownloadManager* manager = NULL;
449 DownloadManager* incognito_manager = NULL;
450 GetManagers(profile, include_incognito, &manager, &incognito_manager);
451 DownloadQuery::DownloadVector all_items;
452 if (query_in.id.get()) {
453 DownloadItem* item = manager->GetDownloadItem(*query_in.id.get());
454 if (!item && incognito_manager)
455 item = incognito_manager->GetDownloadItem(*query_in.id.get());
456 if (item)
457 all_items.push_back(item);
458 } else {
459 manager->GetAllDownloads(FilePath(FILE_PATH_LITERAL("")), &all_items);
460 if (incognito_manager)
461 incognito_manager->GetAllDownloads(
462 FilePath(FILE_PATH_LITERAL("")), &all_items);
463 }
464 query_out.Search(all_items.begin(), all_items.end(), results);
465 }
466
340 } // namespace 467 } // namespace
341 468
342 bool DownloadsFunctionInterface::RunImplImpl( 469 DownloadsDownloadFunction::DownloadsDownloadFunction() {}
343 DownloadsFunctionInterface* pimpl) {
344 CHECK(pimpl);
345 if (!pimpl->ParseArgs()) return false;
346 UMA_HISTOGRAM_ENUMERATION(
347 "Download.ApiFunctions", pimpl->function(), DOWNLOADS_FUNCTION_LAST);
348 return pimpl->RunInternal();
349 }
350
351 SyncDownloadsFunction::SyncDownloadsFunction(
352 DownloadsFunctionInterface::DownloadsFunctionName function)
353 : function_(function) {
354 }
355
356 SyncDownloadsFunction::~SyncDownloadsFunction() {}
357
358 bool SyncDownloadsFunction::RunImpl() {
359 return DownloadsFunctionInterface::RunImplImpl(this);
360 }
361
362 DownloadsFunctionInterface::DownloadsFunctionName
363 SyncDownloadsFunction::function() const {
364 return function_;
365 }
366
367 DownloadItem* SyncDownloadsFunction::GetActiveItem(int download_id) {
368 return GetActiveItemInternal(profile(), include_incognito(), download_id);
369 }
370
371 AsyncDownloadsFunction::AsyncDownloadsFunction(
372 DownloadsFunctionInterface::DownloadsFunctionName function)
373 : function_(function) {
374 }
375
376 AsyncDownloadsFunction::~AsyncDownloadsFunction() {}
377
378 bool AsyncDownloadsFunction::RunImpl() {
379 return DownloadsFunctionInterface::RunImplImpl(this);
380 }
381
382 DownloadsFunctionInterface::DownloadsFunctionName
383 AsyncDownloadsFunction::function() const {
384 return function_;
385 }
386
387 DownloadItem* AsyncDownloadsFunction::GetActiveItem(int download_id) {
388 return GetActiveItemInternal(profile(), include_incognito(), download_id);
389 }
390
391 DownloadsDownloadFunction::DownloadsDownloadFunction()
392 : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_DOWNLOAD) {
393 }
394
395 DownloadsDownloadFunction::~DownloadsDownloadFunction() {} 470 DownloadsDownloadFunction::~DownloadsDownloadFunction() {}
396 471
397 DownloadsDownloadFunction::IOData::IOData() 472 bool DownloadsDownloadFunction::RunImpl() {
398 : save_as(false), 473 scoped_ptr<extensions::api::downloads::Download::Params> params(
399 extra_headers(NULL), 474 extensions::api::downloads::Download::Params::Create(*args_));
400 method("GET"), 475 EXTENSION_FUNCTION_VALIDATE(params.get());
401 rdh(NULL), 476 const extensions::api::downloads::DownloadOptions& options = params->options;
402 resource_context(NULL), 477 GURL download_url(options.url);
403 render_process_host_id(0), 478 if (!download_url.is_valid() ||
404 render_view_host_routing_id(0) { 479 (!download_url.SchemeIs("data") &&
405 } 480 download_url.GetOrigin() != GetExtension()->url().GetOrigin() &&
406 481 !GetExtension()->HasHostPermission(download_url))) {
407 DownloadsDownloadFunction::IOData::~IOData() {}
408
409 bool DownloadsDownloadFunction::ParseArgs() {
410 base::DictionaryValue* options = NULL;
411 std::string url;
412 iodata_.reset(new IOData());
413 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &options));
414 EXTENSION_FUNCTION_VALIDATE(options->GetString(kUrlKey, &url));
415 iodata_->url = GURL(url);
416 if (!iodata_->url.is_valid()) {
417 error_ = download_extension_errors::kInvalidURLError; 482 error_ = download_extension_errors::kInvalidURLError;
418 return false; 483 return false;
419 } 484 }
420 485
421 if (!iodata_->url.SchemeIs("data") && 486 content::DownloadSaveInfo save_info;
422 iodata_->url.GetOrigin() != GetExtension()->url().GetOrigin() && 487 if (options.filename.get()) {
423 !GetExtension()->HasHostPermission(iodata_->url)) { 488 // TODO(benjhayden): Make json_schema_compiler generate string16s instead of
424 error_ = download_extension_errors::kInvalidURLError; 489 // std::strings. Can't get filename16 from options.ToValue() because that
425 return false; 490 // converts it from std::string.
426 } 491 base::DictionaryValue* options_value = NULL;
427 492 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &options_value));
428 if (options->HasKey(kFilenameKey)) { 493 string16 filename16;
429 EXTENSION_FUNCTION_VALIDATE(options->GetString( 494 EXTENSION_FUNCTION_VALIDATE(options_value->GetString(
430 kFilenameKey, &iodata_->filename)); 495 kFilenameKey, &filename16));
431 if (!ValidateFilename(iodata_->filename)) { 496 if (!ValidateFilename(filename16)) {
432 error_ = download_extension_errors::kGenericError; 497 error_ = download_extension_errors::kGenericError;
433 return false; 498 return false;
434 } 499 }
435 } 500 // TODO(benjhayden) Ensure that this filename is interpreted as a path
436 501 // relative to the default downloads directory without allowing '..'.
437 if (options->HasKey(kSaveAsKey)) { 502 save_info.suggested_name = filename16;
438 EXTENSION_FUNCTION_VALIDATE(options->GetBoolean( 503 }
439 kSaveAsKey, &iodata_->save_as)); 504
440 } 505 if (options.save_as.get())
441 506 save_info.prompt_for_save_location = *options.save_as.get();
442 if (options->HasKey(kMethodKey)) { 507
443 EXTENSION_FUNCTION_VALIDATE(options->GetString( 508 Profile* current_profile = profile();
444 kMethodKey, &iodata_->method)); 509 if (include_incognito() && profile()->HasOffTheRecordProfile())
445 } 510 current_profile = profile()->GetOffTheRecordProfile();
446 511
447 // It's ok to use a pointer to extra_headers without DeepCopy()ing because 512 scoped_ptr<content::DownloadUrlParameters> download_params(
448 // |args_| (which owns *extra_headers) is guaranteed to live as long as 513 new content::DownloadUrlParameters(
449 // |this|. 514 download_url,
450 if (options->HasKey(kHeadersKey)) { 515 render_view_host()->GetProcess()->GetID(),
451 EXTENSION_FUNCTION_VALIDATE(options->GetList( 516 render_view_host()->GetRoutingID(),
452 kHeadersKey, &iodata_->extra_headers)); 517 current_profile->GetResourceContext(),
453 } 518 save_info));
454 519
455 if (options->HasKey(kBodyKey)) { 520 if (options.headers.get()) {
456 EXTENSION_FUNCTION_VALIDATE(options->GetString( 521 typedef extensions::api::downloads::HeaderNameValuePair HeaderNameValuePair;
457 kBodyKey, &iodata_->post_body)); 522 for (std::vector<linked_ptr<HeaderNameValuePair> >::const_iterator iter =
458 } 523 options.headers->begin();
459 524 iter != options.headers->end();
460 if (iodata_->extra_headers != NULL) { 525 ++iter) {
461 for (size_t index = 0; index < iodata_->extra_headers->GetSize(); ++index) { 526 const HeaderNameValuePair& name_value = **iter;
462 base::DictionaryValue* header = NULL; 527 if (!net::HttpUtil::IsSafeHeader(name_value.name)) {
463 std::string name;
464 EXTENSION_FUNCTION_VALIDATE(iodata_->extra_headers->GetDictionary(
465 index, &header));
466 EXTENSION_FUNCTION_VALIDATE(header->GetString(
467 kHeaderNameKey, &name));
468 if (!net::HttpUtil::IsSafeHeader(name)) {
469 error_ = download_extension_errors::kGenericError; 528 error_ = download_extension_errors::kGenericError;
470 return false; 529 return false;
471 } 530 }
472 } 531 download_params->add_request_header(name_value.name, name_value.value);
473 } 532 }
474 iodata_->rdh = content::ResourceDispatcherHost::Get(); 533 }
475 iodata_->resource_context = profile()->GetResourceContext(); 534
476 iodata_->render_process_host_id = render_view_host()->GetProcess()->GetID(); 535 if (options.method.get())
477 iodata_->render_view_host_routing_id = render_view_host()->GetRoutingID(); 536 download_params->set_method(*options.method.get());
537 if (options.body.get())
538 download_params->set_post_body(*options.body.get());
539 download_params->set_callback(base::Bind(
540 &DownloadsDownloadFunction::OnStarted, this));
541 // Prevent login prompts for 401/407 responses.
542 download_params->set_load_flags(net::LOAD_DO_NOT_PROMPT_FOR_LOGIN);
543
544 DownloadManager* manager = BrowserContext::GetDownloadManager(
545 current_profile);
546 manager->DownloadUrl(download_params.Pass());
547 RecordApiFunctions(DOWNLOADS_FUNCTION_DOWNLOAD);
478 return true; 548 return true;
479 } 549 }
480 550
481 bool DownloadsDownloadFunction::RunInternal() {
482 VLOG(1) << __FUNCTION__ << " " << iodata_->url.spec();
483 if (!BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
484 &DownloadsDownloadFunction::BeginDownloadOnIOThread, this))) {
485 error_ = download_extension_errors::kGenericError;
486 return false;
487 }
488 return true;
489 }
490
491 void DownloadsDownloadFunction::BeginDownloadOnIOThread() {
492 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
493 DVLOG(1) << __FUNCTION__ << " " << iodata_->url.spec();
494 content::DownloadSaveInfo save_info;
495 // TODO(benjhayden) Ensure that this filename is interpreted as a path
496 // relative to the default downloads directory without allowing '..'.
497 save_info.suggested_name = iodata_->filename;
498 save_info.prompt_for_save_location = iodata_->save_as;
499
500 scoped_ptr<net::URLRequest> request(new net::URLRequest(
501 iodata_->url,
502 NULL,
503 iodata_->resource_context->GetRequestContext()));
504 request->set_method(iodata_->method);
505 if (iodata_->extra_headers != NULL) {
506 for (size_t index = 0; index < iodata_->extra_headers->GetSize(); ++index) {
507 base::DictionaryValue* header = NULL;
508 std::string name, value;
509 CHECK(iodata_->extra_headers->GetDictionary(index, &header));
510 CHECK(header->GetString(kHeaderNameKey, &name));
511 CHECK(header->GetString(kHeaderValueKey, &value));
512 request->SetExtraRequestHeaderByName(name, value, false/*overwrite*/);
513 }
514 }
515 if (!iodata_->post_body.empty()) {
516 request->AppendBytesToUpload(iodata_->post_body.data(),
517 iodata_->post_body.size());
518 }
519
520 // Prevent login prompts for 401/407 responses.
521 request->set_load_flags(request->load_flags() |
522 net::LOAD_DO_NOT_PROMPT_FOR_LOGIN);
523
524 net::Error error = iodata_->rdh->BeginDownload(
525 request.Pass(),
526 false, // is_content_initiated
527 iodata_->resource_context,
528 iodata_->render_process_host_id,
529 iodata_->render_view_host_routing_id,
530 false, // prefer_cache
531 save_info,
532 base::Bind(&DownloadsDownloadFunction::OnStarted, this));
533 iodata_.reset();
534
535 if (error != net::OK) {
536 BrowserThread::PostTask(
537 BrowserThread::UI, FROM_HERE,
538 base::Bind(&DownloadsDownloadFunction::OnStarted, this,
539 DownloadId::Invalid(), error));
540 }
541 }
542
543 void DownloadsDownloadFunction::OnStarted(DownloadId dl_id, net::Error error) { 551 void DownloadsDownloadFunction::OnStarted(DownloadId dl_id, net::Error error) {
544 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 552 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
545 VLOG(1) << __FUNCTION__ << " " << dl_id << " " << error; 553 VLOG(1) << __FUNCTION__ << " " << dl_id << " " << error;
546 if (dl_id.local() >= 0) { 554 if (dl_id.local() >= 0) {
547 result_.reset(base::Value::CreateIntegerValue(dl_id.local())); 555 result_.reset(base::Value::CreateIntegerValue(dl_id.local()));
548 } else { 556 } else {
549 error_ = net::ErrorToString(error); 557 error_ = net::ErrorToString(error);
550 } 558 }
551 SendResponse(error_.empty()); 559 SendResponse(error_.empty());
552 } 560 }
553 561
554 DownloadsSearchFunction::DownloadsSearchFunction() 562 DownloadsSearchFunction::DownloadsSearchFunction() {}
555 : SyncDownloadsFunction(DOWNLOADS_FUNCTION_SEARCH),
556 query_(new DownloadQuery()),
557 get_id_(0),
558 has_get_id_(false) {
559 }
560
561 DownloadsSearchFunction::~DownloadsSearchFunction() {} 563 DownloadsSearchFunction::~DownloadsSearchFunction() {}
562 564
563 bool DownloadsSearchFunction::ParseArgs() { 565 bool DownloadsSearchFunction::RunImpl() {
564 static base::LazyInstance<FilterTypeMap> filter_types = 566 scoped_ptr<extensions::api::downloads::Search::Params> params(
565 LAZY_INSTANCE_INITIALIZER; 567 extensions::api::downloads::Search::Params::Create(*args_));
566 if (filter_types.Get().size() == 0) 568 EXTENSION_FUNCTION_VALIDATE(params.get());
567 InitFilterTypeMap(filter_types.Get()); 569 DownloadQuery::DownloadVector results;
568 570 RunDownloadQuery(params->query, profile(), include_incognito(),
569 base::DictionaryValue* query_json = NULL; 571 &error_, &results);
570 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &query_json)); 572 if (!error_.empty())
571 for (base::DictionaryValue::Iterator query_json_field(*query_json); 573 return false;
572 query_json_field.HasNext(); query_json_field.Advance()) {
573 FilterTypeMap::const_iterator filter_type =
574 filter_types.Get().find(query_json_field.key());
575
576 if (filter_type != filter_types.Get().end()) {
577 if (!query_->AddFilter(filter_type->second, query_json_field.value())) {
578 error_ = download_extension_errors::kInvalidFilterError;
579 return false;
580 }
581 } else if (query_json_field.key() == kIdKey) {
582 EXTENSION_FUNCTION_VALIDATE(query_json_field.value().GetAsInteger(
583 &get_id_));
584 has_get_id_ = true;
585 } else if (query_json_field.key() == kOrderByKey) {
586 if (!ParseOrderBy(query_json_field.value()))
587 return false;
588 } else if (query_json_field.key() == kDangerKey) {
589 std::string danger_str;
590 EXTENSION_FUNCTION_VALIDATE(query_json_field.value().GetAsString(
591 &danger_str));
592 content::DownloadDangerType danger_type =
593 DangerEnumFromString(danger_str);
594 if (danger_type == content::DOWNLOAD_DANGER_TYPE_MAX) {
595 error_ = download_extension_errors::kInvalidDangerTypeError;
596 return false;
597 }
598 query_->AddFilter(danger_type);
599 } else if (query_json_field.key() == kStateKey) {
600 std::string state_str;
601 EXTENSION_FUNCTION_VALIDATE(query_json_field.value().GetAsString(
602 &state_str));
603 DownloadItem::DownloadState state = StateEnumFromString(state_str);
604 if (state == DownloadItem::MAX_DOWNLOAD_STATE) {
605 error_ = download_extension_errors::kInvalidStateError;
606 return false;
607 }
608 query_->AddFilter(state);
609 } else if (query_json_field.key() == kLimitKey) {
610 int limit = 0;
611 EXTENSION_FUNCTION_VALIDATE(query_json_field.value().GetAsInteger(
612 &limit));
613 if (limit < 0) {
614 error_ = download_extension_errors::kInvalidQueryLimit;
615 return false;
616 }
617 query_->Limit(limit);
618 } else {
619 EXTENSION_FUNCTION_VALIDATE(false);
620 }
621 }
622 return true;
623 }
624
625 bool DownloadsSearchFunction::ParseOrderBy(const base::Value& order_by_value) {
626 static base::LazyInstance<SortTypeMap> sorter_types =
627 LAZY_INSTANCE_INITIALIZER;
628 if (sorter_types.Get().size() == 0)
629 InitSortTypeMap(sorter_types.Get());
630
631 std::string order_by_str;
632 EXTENSION_FUNCTION_VALIDATE(order_by_value.GetAsString(&order_by_str));
633 std::vector<std::string> order_by_strs;
634 base::SplitString(order_by_str, ' ', &order_by_strs);
635 for (std::vector<std::string>::const_iterator iter = order_by_strs.begin();
636 iter != order_by_strs.end(); ++iter) {
637 std::string term_str = *iter;
638 if (term_str.empty())
639 continue;
640 DownloadQuery::SortDirection direction = DownloadQuery::ASCENDING;
641 if (term_str[0] == '-') {
642 direction = DownloadQuery::DESCENDING;
643 term_str = term_str.substr(1);
644 }
645 SortTypeMap::const_iterator sorter_type =
646 sorter_types.Get().find(term_str);
647 if (sorter_type == sorter_types.Get().end()) {
648 error_ = download_extension_errors::kInvalidOrderByError;
649 return false;
650 }
651 query_->AddSorter(sorter_type->second, direction);
652 }
653 return true;
654 }
655
656 bool DownloadsSearchFunction::RunInternal() {
657 DownloadManager* manager = NULL;
658 DownloadManager* incognito_manager = NULL;
659 GetManagers(profile(), include_incognito(), &manager, &incognito_manager);
660 DownloadQuery::DownloadVector all_items, cpp_results;
661 if (has_get_id_) {
662 DownloadItem* item = manager->GetDownloadItem(get_id_);
663 if (!item && incognito_manager)
664 item = incognito_manager->GetDownloadItem(get_id_);
665 if (item)
666 all_items.push_back(item);
667 } else {
668 manager->GetAllDownloads(FilePath(FILE_PATH_LITERAL("")), &all_items);
669 if (incognito_manager)
670 incognito_manager->GetAllDownloads(
671 FilePath(FILE_PATH_LITERAL("")), &all_items);
672 }
673 query_->Search(all_items.begin(), all_items.end(), &cpp_results);
674 base::ListValue* json_results = new base::ListValue(); 574 base::ListValue* json_results = new base::ListValue();
675 for (DownloadManager::DownloadVector::const_iterator it = cpp_results.begin(); 575 for (DownloadManager::DownloadVector::const_iterator it = results.begin();
676 it != cpp_results.end(); ++it) { 576 it != results.end(); ++it) {
677 scoped_ptr<base::DictionaryValue> item(DownloadItemToJSON(*it)); 577 scoped_ptr<base::DictionaryValue> item(DownloadItemToJSON(*it));
678 json_results->Append(item.release()); 578 json_results->Append(item.release());
679 } 579 }
680 result_.reset(json_results); 580 result_.reset(json_results);
581 RecordApiFunctions(DOWNLOADS_FUNCTION_SEARCH);
681 return true; 582 return true;
682 } 583 }
683 584
684 DownloadsPauseFunction::DownloadsPauseFunction() 585 DownloadsPauseFunction::DownloadsPauseFunction() {}
685 : SyncDownloadsFunction(DOWNLOADS_FUNCTION_PAUSE),
686 download_id_(DownloadId::Invalid().local()) {
687 }
688
689 DownloadsPauseFunction::~DownloadsPauseFunction() {} 586 DownloadsPauseFunction::~DownloadsPauseFunction() {}
690 587
691 bool DownloadsPauseFunction::ParseArgs() { 588 bool DownloadsPauseFunction::RunImpl() {
692 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &download_id_)); 589 scoped_ptr<extensions::api::downloads::Pause::Params> params(
693 return true; 590 extensions::api::downloads::Pause::Params::Create(*args_));
694 } 591 EXTENSION_FUNCTION_VALIDATE(params.get());
695 592 DownloadItem* download_item = GetActiveItem(
696 bool DownloadsPauseFunction::RunInternal() { 593 profile(), include_incognito(), params->download_id);
697 DownloadItem* download_item = GetActiveItem(download_id_);
698 if ((download_item == NULL) || !download_item->IsInProgress()) { 594 if ((download_item == NULL) || !download_item->IsInProgress()) {
699 // This could be due to an invalid download ID, or it could be due to the 595 // This could be due to an invalid download ID, or it could be due to the
700 // download not being currently active. 596 // download not being currently active.
701 error_ = download_extension_errors::kInvalidOperationError; 597 error_ = download_extension_errors::kInvalidOperationError;
702 } else if (!download_item->IsPaused()) { 598 } else if (!download_item->IsPaused()) {
703 // If download_item->IsPaused() already then we treat it as a success. 599 // If download_item->IsPaused() already then we treat it as a success.
704 download_item->TogglePause(); 600 download_item->TogglePause();
705 } 601 }
602 if (error_.empty())
603 RecordApiFunctions(DOWNLOADS_FUNCTION_PAUSE);
706 return error_.empty(); 604 return error_.empty();
707 } 605 }
708 606
709 DownloadsResumeFunction::DownloadsResumeFunction() 607 DownloadsResumeFunction::DownloadsResumeFunction() {}
710 : SyncDownloadsFunction(DOWNLOADS_FUNCTION_RESUME),
711 download_id_(DownloadId::Invalid().local()) {
712 }
713
714 DownloadsResumeFunction::~DownloadsResumeFunction() {} 608 DownloadsResumeFunction::~DownloadsResumeFunction() {}
715 609
716 bool DownloadsResumeFunction::ParseArgs() { 610 bool DownloadsResumeFunction::RunImpl() {
717 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &download_id_)); 611 scoped_ptr<extensions::api::downloads::Resume::Params> params(
718 return true; 612 extensions::api::downloads::Resume::Params::Create(*args_));
719 } 613 EXTENSION_FUNCTION_VALIDATE(params.get());
720 614 DownloadItem* download_item = GetActiveItem(
721 bool DownloadsResumeFunction::RunInternal() { 615 profile(), include_incognito(), params->download_id);
722 DownloadItem* download_item = GetActiveItem(download_id_);
723 if (download_item == NULL) { 616 if (download_item == NULL) {
724 // This could be due to an invalid download ID, or it could be due to the 617 // This could be due to an invalid download ID, or it could be due to the
725 // download not being currently active. 618 // download not being currently active.
726 error_ = download_extension_errors::kInvalidOperationError; 619 error_ = download_extension_errors::kInvalidOperationError;
727 } else if (download_item->IsPaused()) { 620 } else if (download_item->IsPaused()) {
728 // If !download_item->IsPaused() already, then we treat it as a success. 621 // If !download_item->IsPaused() already, then we treat it as a success.
729 download_item->TogglePause(); 622 download_item->TogglePause();
730 } 623 }
624 if (error_.empty())
625 RecordApiFunctions(DOWNLOADS_FUNCTION_RESUME);
731 return error_.empty(); 626 return error_.empty();
732 } 627 }
733 628
734 DownloadsCancelFunction::DownloadsCancelFunction() 629 DownloadsCancelFunction::DownloadsCancelFunction() {}
735 : SyncDownloadsFunction(DOWNLOADS_FUNCTION_CANCEL),
736 download_id_(DownloadId::Invalid().local()) {
737 }
738
739 DownloadsCancelFunction::~DownloadsCancelFunction() {} 630 DownloadsCancelFunction::~DownloadsCancelFunction() {}
740 631
741 bool DownloadsCancelFunction::ParseArgs() { 632 bool DownloadsCancelFunction::RunImpl() {
742 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &download_id_)); 633 scoped_ptr<extensions::api::downloads::Resume::Params> params(
743 return true; 634 extensions::api::downloads::Resume::Params::Create(*args_));
744 } 635 EXTENSION_FUNCTION_VALIDATE(params.get());
745 636 DownloadItem* download_item = GetActiveItem(
746 bool DownloadsCancelFunction::RunInternal() { 637 profile(), include_incognito(), params->download_id);
747 DownloadItem* download_item = GetActiveItem(download_id_);
748 if (download_item != NULL) 638 if (download_item != NULL)
749 download_item->Cancel(true); 639 download_item->Cancel(true);
750 // |download_item| can be NULL if the download ID was invalid or if the 640 // |download_item| can be NULL if the download ID was invalid or if the
751 // download is not currently active. Either way, we don't consider it a 641 // download is not currently active. Either way, we don't consider it a
752 // failure. 642 // failure.
643 if (error_.empty())
644 RecordApiFunctions(DOWNLOADS_FUNCTION_CANCEL);
753 return error_.empty(); 645 return error_.empty();
754 } 646 }
755 647
756 DownloadsEraseFunction::DownloadsEraseFunction() 648 DownloadsEraseFunction::DownloadsEraseFunction() {}
757 : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_ERASE) { 649 DownloadsEraseFunction::~DownloadsEraseFunction() {}
650
651 bool DownloadsEraseFunction::RunImpl() {
652 scoped_ptr<extensions::api::downloads::Erase::Params> params(
653 extensions::api::downloads::Erase::Params::Create(*args_));
654 EXTENSION_FUNCTION_VALIDATE(params.get());
655 error_ = download_extension_errors::kNotImplementedError;
656 if (error_.empty())
657 RecordApiFunctions(DOWNLOADS_FUNCTION_ERASE);
658 return error_.empty();
758 } 659 }
759 660
760 DownloadsEraseFunction::~DownloadsEraseFunction() {} 661 DownloadsSetDestinationFunction::DownloadsSetDestinationFunction() {}
662 DownloadsSetDestinationFunction::~DownloadsSetDestinationFunction() {}
761 663
762 bool DownloadsEraseFunction::ParseArgs() { 664 bool DownloadsSetDestinationFunction::RunImpl() {
763 base::DictionaryValue* query_json = NULL; 665 scoped_ptr<extensions::api::downloads::SetDestination::Params> params(
764 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &query_json)); 666 extensions::api::downloads::SetDestination::Params::Create(*args_));
667 EXTENSION_FUNCTION_VALIDATE(params.get());
765 error_ = download_extension_errors::kNotImplementedError; 668 error_ = download_extension_errors::kNotImplementedError;
766 return false; 669 if (error_.empty())
670 RecordApiFunctions(DOWNLOADS_FUNCTION_SET_DESTINATION);
671 return error_.empty();
767 } 672 }
768 673
769 bool DownloadsEraseFunction::RunInternal() { 674 DownloadsAcceptDangerFunction::DownloadsAcceptDangerFunction() {}
770 NOTIMPLEMENTED(); 675 DownloadsAcceptDangerFunction::~DownloadsAcceptDangerFunction() {}
771 return false; 676
677 bool DownloadsAcceptDangerFunction::RunImpl() {
678 scoped_ptr<extensions::api::downloads::AcceptDanger::Params> params(
679 extensions::api::downloads::AcceptDanger::Params::Create(*args_));
680 EXTENSION_FUNCTION_VALIDATE(params.get());
681 error_ = download_extension_errors::kNotImplementedError;
682 if (error_.empty())
683 RecordApiFunctions(DOWNLOADS_FUNCTION_ACCEPT_DANGER);
684 return error_.empty();
772 } 685 }
773 686
774 DownloadsSetDestinationFunction::DownloadsSetDestinationFunction() 687 DownloadsShowFunction::DownloadsShowFunction() {}
775 : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_SET_DESTINATION) { 688 DownloadsShowFunction::~DownloadsShowFunction() {}
689
690 bool DownloadsShowFunction::RunImpl() {
691 scoped_ptr<extensions::api::downloads::Show::Params> params(
692 extensions::api::downloads::Show::Params::Create(*args_));
693 EXTENSION_FUNCTION_VALIDATE(params.get());
694 error_ = download_extension_errors::kNotImplementedError;
695 if (error_.empty())
696 RecordApiFunctions(DOWNLOADS_FUNCTION_SHOW);
697 return error_.empty();
776 } 698 }
777 699
778 DownloadsSetDestinationFunction::~DownloadsSetDestinationFunction() {} 700 DownloadsOpenFunction::DownloadsOpenFunction() {}
701 DownloadsOpenFunction::~DownloadsOpenFunction() {}
779 702
780 bool DownloadsSetDestinationFunction::ParseArgs() { 703 bool DownloadsOpenFunction::RunImpl() {
781 int dl_id = 0; 704 scoped_ptr<extensions::api::downloads::Open::Params> params(
782 std::string path; 705 extensions::api::downloads::Open::Params::Create(*args_));
783 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id)); 706 EXTENSION_FUNCTION_VALIDATE(params.get());
784 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &path));
785 VLOG(1) << __FUNCTION__ << " " << dl_id << " " << &path;
786 error_ = download_extension_errors::kNotImplementedError; 707 error_ = download_extension_errors::kNotImplementedError;
787 return false; 708 if (error_.empty())
709 RecordApiFunctions(DOWNLOADS_FUNCTION_OPEN);
710 return error_.empty();
788 } 711 }
789 712
790 bool DownloadsSetDestinationFunction::RunInternal() { 713 DownloadsDragFunction::DownloadsDragFunction() {}
791 NOTIMPLEMENTED();
792 return false;
793 }
794
795 DownloadsAcceptDangerFunction::DownloadsAcceptDangerFunction()
796 : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_ACCEPT_DANGER) {
797 }
798
799 DownloadsAcceptDangerFunction::~DownloadsAcceptDangerFunction() {}
800
801 bool DownloadsAcceptDangerFunction::ParseArgs() {
802 int dl_id = 0;
803 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id));
804 VLOG(1) << __FUNCTION__ << " " << dl_id;
805 error_ = download_extension_errors::kNotImplementedError;
806 return false;
807 }
808
809 bool DownloadsAcceptDangerFunction::RunInternal() {
810 NOTIMPLEMENTED();
811 return false;
812 }
813
814 DownloadsShowFunction::DownloadsShowFunction()
815 : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_SHOW) {
816 }
817
818 DownloadsShowFunction::~DownloadsShowFunction() {}
819
820 bool DownloadsShowFunction::ParseArgs() {
821 int dl_id = 0;
822 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id));
823 VLOG(1) << __FUNCTION__ << " " << dl_id;
824 error_ = download_extension_errors::kNotImplementedError;
825 return false;
826 }
827
828 bool DownloadsShowFunction::RunInternal() {
829 NOTIMPLEMENTED();
830 return false;
831 }
832
833 DownloadsDragFunction::DownloadsDragFunction()
834 : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_DRAG) {
835 }
836
837 DownloadsDragFunction::~DownloadsDragFunction() {} 714 DownloadsDragFunction::~DownloadsDragFunction() {}
838 715
839 bool DownloadsDragFunction::ParseArgs() { 716 bool DownloadsDragFunction::RunImpl() {
840 int dl_id = 0; 717 scoped_ptr<extensions::api::downloads::Drag::Params> params(
841 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id)); 718 extensions::api::downloads::Drag::Params::Create(*args_));
842 VLOG(1) << __FUNCTION__ << " " << dl_id; 719 EXTENSION_FUNCTION_VALIDATE(params.get());
843 error_ = download_extension_errors::kNotImplementedError; 720 error_ = download_extension_errors::kNotImplementedError;
844 return false; 721 if (error_.empty())
845 } 722 RecordApiFunctions(DOWNLOADS_FUNCTION_DRAG);
846 723 return error_.empty();
847 bool DownloadsDragFunction::RunInternal() {
848 NOTIMPLEMENTED();
849 return false;
850 } 724 }
851 725
852 DownloadsGetFileIconFunction::DownloadsGetFileIconFunction() 726 DownloadsGetFileIconFunction::DownloadsGetFileIconFunction()
853 : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_GET_FILE_ICON), 727 : icon_size_(kDefaultIconSize),
854 icon_size_(kDefaultIconSize),
855 icon_extractor_(new DownloadFileIconExtractorImpl()) { 728 icon_extractor_(new DownloadFileIconExtractorImpl()) {
856 } 729 }
857 730
858 DownloadsGetFileIconFunction::~DownloadsGetFileIconFunction() {} 731 DownloadsGetFileIconFunction::~DownloadsGetFileIconFunction() {}
859 732
860 void DownloadsGetFileIconFunction::SetIconExtractorForTesting( 733 void DownloadsGetFileIconFunction::SetIconExtractorForTesting(
861 DownloadFileIconExtractor* extractor) { 734 DownloadFileIconExtractor* extractor) {
862 DCHECK(extractor); 735 DCHECK(extractor);
863 icon_extractor_.reset(extractor); 736 icon_extractor_.reset(extractor);
864 } 737 }
865 738
866 bool DownloadsGetFileIconFunction::ParseArgs() { 739 bool DownloadsGetFileIconFunction::RunImpl() {
867 int dl_id = 0; 740 scoped_ptr<extensions::api::downloads::GetFileIcon::Params> params(
868 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id)); 741 extensions::api::downloads::GetFileIcon::Params::Create(*args_));
869 742 EXTENSION_FUNCTION_VALIDATE(params.get());
870 base::DictionaryValue* options = NULL; 743 const extensions::api::downloads::GetFileIconOptions* options =
871 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &options)); 744 params->options.get();
872 if (options->HasKey(kSizeKey)) { 745 int icon_size = kDefaultIconSize;
873 EXTENSION_FUNCTION_VALIDATE(options->GetInteger(kSizeKey, &icon_size_)); 746 if (options && options->size.get())
874 // We only support 16px and 32px icons. This is enforced in 747 icon_size = *options->size.get();
875 // downloads.json.
876 DCHECK(icon_size_ == 16 || icon_size_ == 32);
877 }
878
879 DownloadManager* manager = NULL; 748 DownloadManager* manager = NULL;
880 DownloadManager* incognito_manager = NULL; 749 DownloadManager* incognito_manager = NULL;
881 GetManagers(profile(), include_incognito(), &manager, &incognito_manager); 750 GetManagers(profile(), include_incognito(), &manager, &incognito_manager);
882 DownloadItem* download_item = manager->GetDownloadItem(dl_id); 751 DownloadItem* download_item = manager->GetDownloadItem(params->download_id);
883 if (!download_item && incognito_manager) 752 if (!download_item && incognito_manager)
884 download_item = incognito_manager->GetDownloadItem(dl_id); 753 download_item = incognito_manager->GetDownloadItem(params->download_id);
885 if (!download_item) { 754 if (!download_item) {
886 // The DownloadItem is is added to history when the path is determined. If 755 // The DownloadItem is is added to history when the path is determined. If
887 // the download is not in history, then we don't have a path / final 756 // the download is not in history, then we don't have a path / final
888 // filename and no icon. 757 // filename and no icon.
889 error_ = download_extension_errors::kInvalidOperationError; 758 error_ = download_extension_errors::kInvalidOperationError;
890 return false; 759 return false;
891 } 760 }
892 // In-progress downloads return the intermediate filename for GetFullPath() 761 // In-progress downloads return the intermediate filename for GetFullPath()
893 // which doesn't have the final extension. Therefore we won't be able to 762 // which doesn't have the final extension. Therefore we won't be able to
894 // derive a good file icon for it. So we use GetTargetFilePath() instead. 763 // derive a good file icon for it. So we use GetTargetFilePath() instead.
895 path_ = download_item->GetTargetFilePath(); 764 FilePath path = download_item->GetTargetFilePath();
896 DCHECK(!path_.empty()); 765 DCHECK(!path.empty());
897 return true;
898 }
899
900 bool DownloadsGetFileIconFunction::RunInternal() {
901 DCHECK(!path_.empty());
902 DCHECK(icon_extractor_.get()); 766 DCHECK(icon_extractor_.get());
767 DCHECK(icon_size == 16 || icon_size == 32);
903 EXTENSION_FUNCTION_VALIDATE(icon_extractor_->ExtractIconURLForPath( 768 EXTENSION_FUNCTION_VALIDATE(icon_extractor_->ExtractIconURLForPath(
904 path_, IconLoaderSizeFromPixelSize(icon_size_), 769 path, IconLoaderSizeFromPixelSize(icon_size),
905 base::Bind(&DownloadsGetFileIconFunction::OnIconURLExtracted, this))); 770 base::Bind(&DownloadsGetFileIconFunction::OnIconURLExtracted, this)));
906 return true; 771 return true;
907 } 772 }
908 773
909 void DownloadsGetFileIconFunction::OnIconURLExtracted(const std::string& url) { 774 void DownloadsGetFileIconFunction::OnIconURLExtracted(const std::string& url) {
910 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 775 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
911 if (url.empty()) 776 if (url.empty()) {
912 error_ = download_extension_errors::kIconNotFoundError; 777 error_ = download_extension_errors::kIconNotFoundError;
913 else 778 } else {
779 RecordApiFunctions(DOWNLOADS_FUNCTION_GET_FILE_ICON);
914 result_.reset(base::Value::CreateStringValue(url)); 780 result_.reset(base::Value::CreateStringValue(url));
781 }
915 SendResponse(error_.empty()); 782 SendResponse(error_.empty());
916 } 783 }
917 784
918 ExtensionDownloadsEventRouter::ExtensionDownloadsEventRouter( 785 ExtensionDownloadsEventRouter::ExtensionDownloadsEventRouter(
919 Profile* profile, 786 Profile* profile,
920 DownloadManager* manager) 787 DownloadManager* manager)
921 : profile_(profile), 788 : profile_(profile),
922 manager_(manager) { 789 manager_(manager) {
923 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 790 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
924 DCHECK(profile_); 791 DCHECK(profile_);
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 extensions::EventFilteringInfo()); 961 extensions::EventFilteringInfo());
1095 962
1096 DownloadsNotificationSource notification_source; 963 DownloadsNotificationSource notification_source;
1097 notification_source.event_name = event_name; 964 notification_source.event_name = event_name;
1098 notification_source.profile = profile_; 965 notification_source.profile = profile_;
1099 content::NotificationService::current()->Notify( 966 content::NotificationService::current()->Notify(
1100 chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, 967 chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
1101 content::Source<DownloadsNotificationSource>(&notification_source), 968 content::Source<DownloadsNotificationSource>(&notification_source),
1102 content::Details<std::string>(&json_args)); 969 content::Details<std::string>(&json_args));
1103 } 970 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698