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

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: merge 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 // TODO(benjhayden): Consider switching from LazyInstance to explicit string
365 // comparisons.
366 static base::LazyInstance<SortTypeMap> sorter_types =
367 LAZY_INSTANCE_INITIALIZER;
368 if (sorter_types.Get().size() == 0)
369 InitSortTypeMap(sorter_types.Get());
370
371 std::vector<std::string> order_by_strs;
372 base::SplitString(order_by_str, ' ', &order_by_strs);
373 for (std::vector<std::string>::const_iterator iter = order_by_strs.begin();
374 iter != order_by_strs.end(); ++iter) {
375 std::string term_str = *iter;
376 if (term_str.empty())
377 continue;
378 DownloadQuery::SortDirection direction = DownloadQuery::ASCENDING;
379 if (term_str[0] == '-') {
380 direction = DownloadQuery::DESCENDING;
381 term_str = term_str.substr(1);
382 }
383 SortTypeMap::const_iterator sorter_type =
384 sorter_types.Get().find(term_str);
385 if (sorter_type == sorter_types.Get().end()) {
386 *error = download_extension_errors::kInvalidOrderByError;
387 return;
388 }
389 query->AddSorter(sorter_type->second, direction);
390 }
391 }
392
393 void RunDownloadQuery(
394 const extensions::api::downloads::DownloadQuery& query_in,
395 Profile* profile,
396 bool include_incognito,
397 std::string* error,
398 DownloadQuery::DownloadVector* results) {
399 // TODO(benjhayden): Consider switching from LazyInstance to explicit string
400 // comparisons.
401 static base::LazyInstance<FilterTypeMap> filter_types =
402 LAZY_INSTANCE_INITIALIZER;
403 if (filter_types.Get().size() == 0)
404 InitFilterTypeMap(filter_types.Get());
405
406 DownloadQuery query_out;
407
408 if (query_in.limit.get()) {
409 if (*query_in.limit.get() < 0) {
410 *error = download_extension_errors::kInvalidQueryLimit;
411 return;
412 }
413 query_out.Limit(*query_in.limit.get());
414 }
415 if (query_in.state.get()) {
416 DownloadItem::DownloadState state = StateEnumFromString(
417 *query_in.state.get());
418 if (state == DownloadItem::MAX_DOWNLOAD_STATE) {
419 *error = download_extension_errors::kInvalidStateError;
420 return;
421 }
422 query_out.AddFilter(state);
423 }
424 if (query_in.danger.get()) {
425 content::DownloadDangerType danger_type =
426 DangerEnumFromString(*query_in.danger.get());
427 if (danger_type == content::DOWNLOAD_DANGER_TYPE_MAX) {
428 *error = download_extension_errors::kInvalidDangerTypeError;
429 return;
430 }
431 query_out.AddFilter(danger_type);
432 }
433 if (query_in.order_by.get()) {
434 CompileDownloadQueryOrderBy(*query_in.order_by.get(), error, &query_out);
435 if (!error->empty())
436 return;
437 }
438
439 scoped_ptr<base::DictionaryValue> query_in_value(query_in.ToValue().Pass());
440 for (base::DictionaryValue::Iterator query_json_field(*query_in_value.get());
441 query_json_field.HasNext(); query_json_field.Advance()) {
442 FilterTypeMap::const_iterator filter_type =
443 filter_types.Get().find(query_json_field.key());
444 if (filter_type != filter_types.Get().end()) {
445 if (!query_out.AddFilter(filter_type->second, query_json_field.value())) {
446 *error = download_extension_errors::kInvalidFilterError;
447 return;
448 }
449 }
450 }
451
452 DownloadManager* manager = NULL;
453 DownloadManager* incognito_manager = NULL;
454 GetManagers(profile, include_incognito, &manager, &incognito_manager);
455 DownloadQuery::DownloadVector all_items;
456 if (query_in.id.get()) {
457 DownloadItem* item = manager->GetDownloadItem(*query_in.id.get());
458 if (!item && incognito_manager)
459 item = incognito_manager->GetDownloadItem(*query_in.id.get());
460 if (item)
461 all_items.push_back(item);
462 } else {
463 manager->GetAllDownloads(FilePath(FILE_PATH_LITERAL("")), &all_items);
464 if (incognito_manager)
465 incognito_manager->GetAllDownloads(
466 FilePath(FILE_PATH_LITERAL("")), &all_items);
467 }
468 query_out.Search(all_items.begin(), all_items.end(), results);
469 }
470
340 } // namespace 471 } // namespace
341 472
342 bool DownloadsFunctionInterface::RunImplImpl( 473 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() {} 474 DownloadsDownloadFunction::~DownloadsDownloadFunction() {}
396 475
397 DownloadsDownloadFunction::IOData::IOData() 476 bool DownloadsDownloadFunction::RunImpl() {
398 : save_as(false), 477 scoped_ptr<extensions::api::downloads::Download::Params> params(
399 extra_headers(NULL), 478 extensions::api::downloads::Download::Params::Create(*args_));
400 method("GET"), 479 EXTENSION_FUNCTION_VALIDATE(params.get());
401 rdh(NULL), 480 const extensions::api::downloads::DownloadOptions& options = params->options;
402 resource_context(NULL), 481 GURL download_url(options.url);
403 render_process_host_id(0), 482 if (!download_url.is_valid() ||
404 render_view_host_routing_id(0) { 483 (!download_url.SchemeIs("data") &&
405 } 484 download_url.GetOrigin() != GetExtension()->url().GetOrigin() &&
406 485 !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; 486 error_ = download_extension_errors::kInvalidURLError;
418 return false; 487 return false;
419 } 488 }
420 489
421 if (!iodata_->url.SchemeIs("data") && 490 content::DownloadSaveInfo save_info;
422 iodata_->url.GetOrigin() != GetExtension()->url().GetOrigin() && 491 if (options.filename.get()) {
423 !GetExtension()->HasHostPermission(iodata_->url)) { 492 // TODO(benjhayden): Make json_schema_compiler generate string16s instead of
424 error_ = download_extension_errors::kInvalidURLError; 493 // std::strings. Can't get filename16 from options.ToValue() because that
425 return false; 494 // converts it from std::string.
426 } 495 base::DictionaryValue* options_value = NULL;
427 496 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &options_value));
428 if (options->HasKey(kFilenameKey)) { 497 string16 filename16;
429 EXTENSION_FUNCTION_VALIDATE(options->GetString( 498 EXTENSION_FUNCTION_VALIDATE(options_value->GetString(
430 kFilenameKey, &iodata_->filename)); 499 kFilenameKey, &filename16));
431 if (!ValidateFilename(iodata_->filename)) { 500 if (!ValidateFilename(filename16)) {
432 error_ = download_extension_errors::kGenericError; 501 error_ = download_extension_errors::kGenericError;
433 return false; 502 return false;
434 } 503 }
435 } 504 // TODO(benjhayden) Ensure that this filename is interpreted as a path
436 505 // relative to the default downloads directory without allowing '..'.
437 if (options->HasKey(kSaveAsKey)) { 506 save_info.suggested_name = filename16;
438 EXTENSION_FUNCTION_VALIDATE(options->GetBoolean( 507 }
439 kSaveAsKey, &iodata_->save_as)); 508
440 } 509 if (options.save_as.get())
441 510 save_info.prompt_for_save_location = *options.save_as.get();
442 if (options->HasKey(kMethodKey)) { 511
443 EXTENSION_FUNCTION_VALIDATE(options->GetString( 512 Profile* current_profile = profile();
444 kMethodKey, &iodata_->method)); 513 if (include_incognito() && profile()->HasOffTheRecordProfile())
445 } 514 current_profile = profile()->GetOffTheRecordProfile();
446 515
447 // It's ok to use a pointer to extra_headers without DeepCopy()ing because 516 scoped_ptr<content::DownloadUrlParameters> download_params(
448 // |args_| (which owns *extra_headers) is guaranteed to live as long as 517 new content::DownloadUrlParameters(
449 // |this|. 518 download_url,
450 if (options->HasKey(kHeadersKey)) { 519 render_view_host()->GetProcess()->GetID(),
451 EXTENSION_FUNCTION_VALIDATE(options->GetList( 520 render_view_host()->GetRoutingID(),
452 kHeadersKey, &iodata_->extra_headers)); 521 current_profile->GetResourceContext(),
453 } 522 save_info));
454 523
455 if (options->HasKey(kBodyKey)) { 524 if (options.headers.get()) {
456 EXTENSION_FUNCTION_VALIDATE(options->GetString( 525 typedef extensions::api::downloads::HeaderNameValuePair HeaderNameValuePair;
457 kBodyKey, &iodata_->post_body)); 526 for (std::vector<linked_ptr<HeaderNameValuePair> >::const_iterator iter =
458 } 527 options.headers->begin();
459 528 iter != options.headers->end();
460 if (iodata_->extra_headers != NULL) { 529 ++iter) {
461 for (size_t index = 0; index < iodata_->extra_headers->GetSize(); ++index) { 530 const HeaderNameValuePair& name_value = **iter;
462 base::DictionaryValue* header = NULL; 531 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; 532 error_ = download_extension_errors::kGenericError;
470 return false; 533 return false;
471 } 534 }
472 } 535 download_params->add_request_header(name_value.name, name_value.value);
473 } 536 }
474 iodata_->rdh = content::ResourceDispatcherHost::Get(); 537 }
475 iodata_->resource_context = profile()->GetResourceContext(); 538
476 iodata_->render_process_host_id = render_view_host()->GetProcess()->GetID(); 539 if (options.method.get())
477 iodata_->render_view_host_routing_id = render_view_host()->GetRoutingID(); 540 download_params->set_method(*options.method.get());
541 if (options.body.get())
542 download_params->set_post_body(*options.body.get());
543 download_params->set_callback(base::Bind(
544 &DownloadsDownloadFunction::OnStarted, this));
545 // Prevent login prompts for 401/407 responses.
546 download_params->set_load_flags(net::LOAD_DO_NOT_PROMPT_FOR_LOGIN);
547
548 DownloadManager* manager = BrowserContext::GetDownloadManager(
549 current_profile);
550 manager->DownloadUrl(download_params.Pass());
551 RecordApiFunctions(DOWNLOADS_FUNCTION_DOWNLOAD);
478 return true; 552 return true;
479 } 553 }
480 554
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) { 555 void DownloadsDownloadFunction::OnStarted(DownloadId dl_id, net::Error error) {
544 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 556 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
545 VLOG(1) << __FUNCTION__ << " " << dl_id << " " << error; 557 VLOG(1) << __FUNCTION__ << " " << dl_id << " " << error;
546 if (dl_id.local() >= 0) { 558 if (dl_id.local() >= 0) {
547 result_.reset(base::Value::CreateIntegerValue(dl_id.local())); 559 result_.reset(base::Value::CreateIntegerValue(dl_id.local()));
548 } else { 560 } else {
549 error_ = net::ErrorToString(error); 561 error_ = net::ErrorToString(error);
550 } 562 }
551 SendResponse(error_.empty()); 563 SendResponse(error_.empty());
552 } 564 }
553 565
554 DownloadsSearchFunction::DownloadsSearchFunction() 566 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() {} 567 DownloadsSearchFunction::~DownloadsSearchFunction() {}
562 568
563 bool DownloadsSearchFunction::ParseArgs() { 569 bool DownloadsSearchFunction::RunImpl() {
564 static base::LazyInstance<FilterTypeMap> filter_types = 570 scoped_ptr<extensions::api::downloads::Search::Params> params(
565 LAZY_INSTANCE_INITIALIZER; 571 extensions::api::downloads::Search::Params::Create(*args_));
566 if (filter_types.Get().size() == 0) 572 EXTENSION_FUNCTION_VALIDATE(params.get());
567 InitFilterTypeMap(filter_types.Get()); 573 DownloadQuery::DownloadVector results;
568 574 RunDownloadQuery(params->query, profile(), include_incognito(),
569 base::DictionaryValue* query_json = NULL; 575 &error_, &results);
570 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &query_json)); 576 if (!error_.empty())
571 for (base::DictionaryValue::Iterator query_json_field(*query_json); 577 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(); 578 base::ListValue* json_results = new base::ListValue();
675 for (DownloadManager::DownloadVector::const_iterator it = cpp_results.begin(); 579 for (DownloadManager::DownloadVector::const_iterator it = results.begin();
676 it != cpp_results.end(); ++it) { 580 it != results.end(); ++it) {
677 scoped_ptr<base::DictionaryValue> item(DownloadItemToJSON(*it)); 581 scoped_ptr<base::DictionaryValue> item(DownloadItemToJSON(*it));
678 json_results->Append(item.release()); 582 json_results->Append(item.release());
679 } 583 }
680 result_.reset(json_results); 584 result_.reset(json_results);
585 RecordApiFunctions(DOWNLOADS_FUNCTION_SEARCH);
681 return true; 586 return true;
682 } 587 }
683 588
684 DownloadsPauseFunction::DownloadsPauseFunction() 589 DownloadsPauseFunction::DownloadsPauseFunction() {}
685 : SyncDownloadsFunction(DOWNLOADS_FUNCTION_PAUSE),
686 download_id_(DownloadId::Invalid().local()) {
687 }
688
689 DownloadsPauseFunction::~DownloadsPauseFunction() {} 590 DownloadsPauseFunction::~DownloadsPauseFunction() {}
690 591
691 bool DownloadsPauseFunction::ParseArgs() { 592 bool DownloadsPauseFunction::RunImpl() {
692 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &download_id_)); 593 scoped_ptr<extensions::api::downloads::Pause::Params> params(
693 return true; 594 extensions::api::downloads::Pause::Params::Create(*args_));
694 } 595 EXTENSION_FUNCTION_VALIDATE(params.get());
695 596 DownloadItem* download_item = GetActiveItem(
696 bool DownloadsPauseFunction::RunInternal() { 597 profile(), include_incognito(), params->download_id);
697 DownloadItem* download_item = GetActiveItem(download_id_);
698 if ((download_item == NULL) || !download_item->IsInProgress()) { 598 if ((download_item == NULL) || !download_item->IsInProgress()) {
699 // This could be due to an invalid download ID, or it could be due to the 599 // This could be due to an invalid download ID, or it could be due to the
700 // download not being currently active. 600 // download not being currently active.
701 error_ = download_extension_errors::kInvalidOperationError; 601 error_ = download_extension_errors::kInvalidOperationError;
702 } else if (!download_item->IsPaused()) { 602 } else if (!download_item->IsPaused()) {
703 // If download_item->IsPaused() already then we treat it as a success. 603 // If download_item->IsPaused() already then we treat it as a success.
704 download_item->TogglePause(); 604 download_item->TogglePause();
705 } 605 }
606 if (error_.empty())
607 RecordApiFunctions(DOWNLOADS_FUNCTION_PAUSE);
706 return error_.empty(); 608 return error_.empty();
707 } 609 }
708 610
709 DownloadsResumeFunction::DownloadsResumeFunction() 611 DownloadsResumeFunction::DownloadsResumeFunction() {}
710 : SyncDownloadsFunction(DOWNLOADS_FUNCTION_RESUME),
711 download_id_(DownloadId::Invalid().local()) {
712 }
713
714 DownloadsResumeFunction::~DownloadsResumeFunction() {} 612 DownloadsResumeFunction::~DownloadsResumeFunction() {}
715 613
716 bool DownloadsResumeFunction::ParseArgs() { 614 bool DownloadsResumeFunction::RunImpl() {
717 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &download_id_)); 615 scoped_ptr<extensions::api::downloads::Resume::Params> params(
718 return true; 616 extensions::api::downloads::Resume::Params::Create(*args_));
719 } 617 EXTENSION_FUNCTION_VALIDATE(params.get());
720 618 DownloadItem* download_item = GetActiveItem(
721 bool DownloadsResumeFunction::RunInternal() { 619 profile(), include_incognito(), params->download_id);
722 DownloadItem* download_item = GetActiveItem(download_id_);
723 if (download_item == NULL) { 620 if (download_item == NULL) {
724 // This could be due to an invalid download ID, or it could be due to the 621 // This could be due to an invalid download ID, or it could be due to the
725 // download not being currently active. 622 // download not being currently active.
726 error_ = download_extension_errors::kInvalidOperationError; 623 error_ = download_extension_errors::kInvalidOperationError;
727 } else if (download_item->IsPaused()) { 624 } else if (download_item->IsPaused()) {
728 // If !download_item->IsPaused() already, then we treat it as a success. 625 // If !download_item->IsPaused() already, then we treat it as a success.
729 download_item->TogglePause(); 626 download_item->TogglePause();
730 } 627 }
628 if (error_.empty())
629 RecordApiFunctions(DOWNLOADS_FUNCTION_RESUME);
731 return error_.empty(); 630 return error_.empty();
732 } 631 }
733 632
734 DownloadsCancelFunction::DownloadsCancelFunction() 633 DownloadsCancelFunction::DownloadsCancelFunction() {}
735 : SyncDownloadsFunction(DOWNLOADS_FUNCTION_CANCEL),
736 download_id_(DownloadId::Invalid().local()) {
737 }
738
739 DownloadsCancelFunction::~DownloadsCancelFunction() {} 634 DownloadsCancelFunction::~DownloadsCancelFunction() {}
740 635
741 bool DownloadsCancelFunction::ParseArgs() { 636 bool DownloadsCancelFunction::RunImpl() {
742 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &download_id_)); 637 scoped_ptr<extensions::api::downloads::Resume::Params> params(
743 return true; 638 extensions::api::downloads::Resume::Params::Create(*args_));
744 } 639 EXTENSION_FUNCTION_VALIDATE(params.get());
745 640 DownloadItem* download_item = GetActiveItem(
746 bool DownloadsCancelFunction::RunInternal() { 641 profile(), include_incognito(), params->download_id);
747 DownloadItem* download_item = GetActiveItem(download_id_);
748 if (download_item != NULL) 642 if (download_item != NULL)
749 download_item->Cancel(true); 643 download_item->Cancel(true);
750 // |download_item| can be NULL if the download ID was invalid or if the 644 // |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 645 // download is not currently active. Either way, we don't consider it a
752 // failure. 646 // failure.
647 if (error_.empty())
648 RecordApiFunctions(DOWNLOADS_FUNCTION_CANCEL);
753 return error_.empty(); 649 return error_.empty();
754 } 650 }
755 651
756 DownloadsEraseFunction::DownloadsEraseFunction() 652 DownloadsEraseFunction::DownloadsEraseFunction() {}
757 : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_ERASE) { 653 DownloadsEraseFunction::~DownloadsEraseFunction() {}
654
655 bool DownloadsEraseFunction::RunImpl() {
656 scoped_ptr<extensions::api::downloads::Erase::Params> params(
657 extensions::api::downloads::Erase::Params::Create(*args_));
658 EXTENSION_FUNCTION_VALIDATE(params.get());
659 error_ = download_extension_errors::kNotImplementedError;
660 if (error_.empty())
661 RecordApiFunctions(DOWNLOADS_FUNCTION_ERASE);
662 return error_.empty();
758 } 663 }
759 664
760 DownloadsEraseFunction::~DownloadsEraseFunction() {} 665 DownloadsSetDestinationFunction::DownloadsSetDestinationFunction() {}
666 DownloadsSetDestinationFunction::~DownloadsSetDestinationFunction() {}
761 667
762 bool DownloadsEraseFunction::ParseArgs() { 668 bool DownloadsSetDestinationFunction::RunImpl() {
763 base::DictionaryValue* query_json = NULL; 669 scoped_ptr<extensions::api::downloads::SetDestination::Params> params(
764 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &query_json)); 670 extensions::api::downloads::SetDestination::Params::Create(*args_));
671 EXTENSION_FUNCTION_VALIDATE(params.get());
765 error_ = download_extension_errors::kNotImplementedError; 672 error_ = download_extension_errors::kNotImplementedError;
766 return false; 673 if (error_.empty())
674 RecordApiFunctions(DOWNLOADS_FUNCTION_SET_DESTINATION);
675 return error_.empty();
767 } 676 }
768 677
769 bool DownloadsEraseFunction::RunInternal() { 678 DownloadsAcceptDangerFunction::DownloadsAcceptDangerFunction() {}
770 NOTIMPLEMENTED(); 679 DownloadsAcceptDangerFunction::~DownloadsAcceptDangerFunction() {}
771 return false; 680
681 bool DownloadsAcceptDangerFunction::RunImpl() {
682 scoped_ptr<extensions::api::downloads::AcceptDanger::Params> params(
683 extensions::api::downloads::AcceptDanger::Params::Create(*args_));
684 EXTENSION_FUNCTION_VALIDATE(params.get());
685 error_ = download_extension_errors::kNotImplementedError;
686 if (error_.empty())
687 RecordApiFunctions(DOWNLOADS_FUNCTION_ACCEPT_DANGER);
688 return error_.empty();
772 } 689 }
773 690
774 DownloadsSetDestinationFunction::DownloadsSetDestinationFunction() 691 DownloadsShowFunction::DownloadsShowFunction() {}
775 : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_SET_DESTINATION) { 692 DownloadsShowFunction::~DownloadsShowFunction() {}
693
694 bool DownloadsShowFunction::RunImpl() {
695 scoped_ptr<extensions::api::downloads::Show::Params> params(
696 extensions::api::downloads::Show::Params::Create(*args_));
697 EXTENSION_FUNCTION_VALIDATE(params.get());
698 error_ = download_extension_errors::kNotImplementedError;
699 if (error_.empty())
700 RecordApiFunctions(DOWNLOADS_FUNCTION_SHOW);
701 return error_.empty();
776 } 702 }
777 703
778 DownloadsSetDestinationFunction::~DownloadsSetDestinationFunction() {} 704 DownloadsOpenFunction::DownloadsOpenFunction() {}
705 DownloadsOpenFunction::~DownloadsOpenFunction() {}
779 706
780 bool DownloadsSetDestinationFunction::ParseArgs() { 707 bool DownloadsOpenFunction::RunImpl() {
781 int dl_id = 0; 708 scoped_ptr<extensions::api::downloads::Open::Params> params(
782 std::string path; 709 extensions::api::downloads::Open::Params::Create(*args_));
783 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id)); 710 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; 711 error_ = download_extension_errors::kNotImplementedError;
787 return false; 712 if (error_.empty())
713 RecordApiFunctions(DOWNLOADS_FUNCTION_OPEN);
714 return error_.empty();
788 } 715 }
789 716
790 bool DownloadsSetDestinationFunction::RunInternal() { 717 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() {} 718 DownloadsDragFunction::~DownloadsDragFunction() {}
838 719
839 bool DownloadsDragFunction::ParseArgs() { 720 bool DownloadsDragFunction::RunImpl() {
840 int dl_id = 0; 721 scoped_ptr<extensions::api::downloads::Drag::Params> params(
841 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id)); 722 extensions::api::downloads::Drag::Params::Create(*args_));
842 VLOG(1) << __FUNCTION__ << " " << dl_id; 723 EXTENSION_FUNCTION_VALIDATE(params.get());
843 error_ = download_extension_errors::kNotImplementedError; 724 error_ = download_extension_errors::kNotImplementedError;
844 return false; 725 if (error_.empty())
845 } 726 RecordApiFunctions(DOWNLOADS_FUNCTION_DRAG);
846 727 return error_.empty();
847 bool DownloadsDragFunction::RunInternal() {
848 NOTIMPLEMENTED();
849 return false;
850 } 728 }
851 729
852 DownloadsGetFileIconFunction::DownloadsGetFileIconFunction() 730 DownloadsGetFileIconFunction::DownloadsGetFileIconFunction()
853 : AsyncDownloadsFunction(DOWNLOADS_FUNCTION_GET_FILE_ICON), 731 : icon_size_(kDefaultIconSize),
854 icon_size_(kDefaultIconSize),
855 icon_extractor_(new DownloadFileIconExtractorImpl()) { 732 icon_extractor_(new DownloadFileIconExtractorImpl()) {
856 } 733 }
857 734
858 DownloadsGetFileIconFunction::~DownloadsGetFileIconFunction() {} 735 DownloadsGetFileIconFunction::~DownloadsGetFileIconFunction() {}
859 736
860 void DownloadsGetFileIconFunction::SetIconExtractorForTesting( 737 void DownloadsGetFileIconFunction::SetIconExtractorForTesting(
861 DownloadFileIconExtractor* extractor) { 738 DownloadFileIconExtractor* extractor) {
862 DCHECK(extractor); 739 DCHECK(extractor);
863 icon_extractor_.reset(extractor); 740 icon_extractor_.reset(extractor);
864 } 741 }
865 742
866 bool DownloadsGetFileIconFunction::ParseArgs() { 743 bool DownloadsGetFileIconFunction::RunImpl() {
867 int dl_id = 0; 744 scoped_ptr<extensions::api::downloads::GetFileIcon::Params> params(
868 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id)); 745 extensions::api::downloads::GetFileIcon::Params::Create(*args_));
869 746 EXTENSION_FUNCTION_VALIDATE(params.get());
870 base::DictionaryValue* options = NULL; 747 const extensions::api::downloads::GetFileIconOptions* options =
871 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &options)); 748 params->options.get();
872 if (options->HasKey(kSizeKey)) { 749 int icon_size = kDefaultIconSize;
873 EXTENSION_FUNCTION_VALIDATE(options->GetInteger(kSizeKey, &icon_size_)); 750 if (options && options->size.get())
874 // We only support 16px and 32px icons. This is enforced in 751 icon_size = *options->size.get();
875 // downloads.json.
876 DCHECK(icon_size_ == 16 || icon_size_ == 32);
877 }
878
879 DownloadManager* manager = NULL; 752 DownloadManager* manager = NULL;
880 DownloadManager* incognito_manager = NULL; 753 DownloadManager* incognito_manager = NULL;
881 GetManagers(profile(), include_incognito(), &manager, &incognito_manager); 754 GetManagers(profile(), include_incognito(), &manager, &incognito_manager);
882 DownloadItem* download_item = manager->GetDownloadItem(dl_id); 755 DownloadItem* download_item = manager->GetDownloadItem(params->download_id);
883 if (!download_item && incognito_manager) 756 if (!download_item && incognito_manager)
884 download_item = incognito_manager->GetDownloadItem(dl_id); 757 download_item = incognito_manager->GetDownloadItem(params->download_id);
885 if (!download_item) { 758 if (!download_item) {
886 // The DownloadItem is is added to history when the path is determined. If 759 // 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 760 // the download is not in history, then we don't have a path / final
888 // filename and no icon. 761 // filename and no icon.
889 error_ = download_extension_errors::kInvalidOperationError; 762 error_ = download_extension_errors::kInvalidOperationError;
890 return false; 763 return false;
891 } 764 }
892 // In-progress downloads return the intermediate filename for GetFullPath() 765 // In-progress downloads return the intermediate filename for GetFullPath()
893 // which doesn't have the final extension. Therefore we won't be able to 766 // 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. 767 // derive a good file icon for it. So we use GetTargetFilePath() instead.
895 path_ = download_item->GetTargetFilePath(); 768 FilePath path = download_item->GetTargetFilePath();
896 DCHECK(!path_.empty()); 769 DCHECK(!path.empty());
897 return true;
898 }
899
900 bool DownloadsGetFileIconFunction::RunInternal() {
901 DCHECK(!path_.empty());
902 DCHECK(icon_extractor_.get()); 770 DCHECK(icon_extractor_.get());
771 DCHECK(icon_size == 16 || icon_size == 32);
903 EXTENSION_FUNCTION_VALIDATE(icon_extractor_->ExtractIconURLForPath( 772 EXTENSION_FUNCTION_VALIDATE(icon_extractor_->ExtractIconURLForPath(
904 path_, IconLoaderSizeFromPixelSize(icon_size_), 773 path, IconLoaderSizeFromPixelSize(icon_size),
905 base::Bind(&DownloadsGetFileIconFunction::OnIconURLExtracted, this))); 774 base::Bind(&DownloadsGetFileIconFunction::OnIconURLExtracted, this)));
906 return true; 775 return true;
907 } 776 }
908 777
909 void DownloadsGetFileIconFunction::OnIconURLExtracted(const std::string& url) { 778 void DownloadsGetFileIconFunction::OnIconURLExtracted(const std::string& url) {
910 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 779 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
911 if (url.empty()) 780 if (url.empty()) {
912 error_ = download_extension_errors::kIconNotFoundError; 781 error_ = download_extension_errors::kIconNotFoundError;
913 else 782 } else {
783 RecordApiFunctions(DOWNLOADS_FUNCTION_GET_FILE_ICON);
914 result_.reset(base::Value::CreateStringValue(url)); 784 result_.reset(base::Value::CreateStringValue(url));
785 }
915 SendResponse(error_.empty()); 786 SendResponse(error_.empty());
916 } 787 }
917 788
918 ExtensionDownloadsEventRouter::ExtensionDownloadsEventRouter( 789 ExtensionDownloadsEventRouter::ExtensionDownloadsEventRouter(
919 Profile* profile, 790 Profile* profile,
920 DownloadManager* manager) 791 DownloadManager* manager)
921 : profile_(profile), 792 : profile_(profile),
922 manager_(manager) { 793 manager_(manager) {
923 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 794 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
924 DCHECK(profile_); 795 DCHECK(profile_);
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 extensions::EventFilteringInfo()); 965 extensions::EventFilteringInfo());
1095 966
1096 DownloadsNotificationSource notification_source; 967 DownloadsNotificationSource notification_source;
1097 notification_source.event_name = event_name; 968 notification_source.event_name = event_name;
1098 notification_source.profile = profile_; 969 notification_source.profile = profile_;
1099 content::NotificationService::current()->Notify( 970 content::NotificationService::current()->Notify(
1100 chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, 971 chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
1101 content::Source<DownloadsNotificationSource>(&notification_source), 972 content::Source<DownloadsNotificationSource>(&notification_source),
1102 content::Details<std::string>(&json_args)); 973 content::Details<std::string>(&json_args));
1103 } 974 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/downloads/downloads_api.h ('k') | chrome/browser/extensions/extension_function_registry.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698