| 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/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 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 bool ValidateFilename(const string16& filename) { | 183 bool ValidateFilename(const string16& filename) { |
| 184 // TODO(benjhayden): More robust validation of filename. | 184 // TODO(benjhayden): More robust validation of filename. |
| 185 if ((filename.find('/') != string16::npos) || | 185 if ((filename.find('/') != string16::npos) || |
| 186 (filename.find('\\') != string16::npos)) | 186 (filename.find('\\') != string16::npos)) |
| 187 return false; | 187 return false; |
| 188 if (filename.size() >= 2u && filename[0] == L'.' && filename[1] == L'.') | 188 if (filename.size() >= 2u && filename[0] == L'.' && filename[1] == L'.') |
| 189 return false; | 189 return false; |
| 190 return true; | 190 return true; |
| 191 } | 191 } |
| 192 | 192 |
| 193 scoped_ptr<base::DictionaryValue> DownloadItemToJSON(DownloadItem* item) { | 193 scoped_ptr<base::DictionaryValue> DownloadItemToJSON( |
| 194 DownloadItem* item, |
| 195 bool incognito) { |
| 194 base::DictionaryValue* json = new base::DictionaryValue(); | 196 base::DictionaryValue* json = new base::DictionaryValue(); |
| 195 json->SetInteger(kIdKey, item->GetId()); | 197 json->SetInteger(kIdKey, item->GetId()); |
| 196 json->SetString(kUrlKey, item->GetOriginalUrl().spec()); | 198 json->SetString(kUrlKey, item->GetOriginalUrl().spec()); |
| 197 json->SetString(kFilenameKey, item->GetFullPath().LossyDisplayName()); | 199 json->SetString(kFilenameKey, item->GetFullPath().LossyDisplayName()); |
| 198 json->SetString(kDangerKey, DangerString(item->GetDangerType())); | 200 json->SetString(kDangerKey, DangerString(item->GetDangerType())); |
| 199 if (item->GetDangerType() != content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) | 201 if (item->GetDangerType() != content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) |
| 200 json->SetBoolean(kDangerAcceptedKey, | 202 json->SetBoolean(kDangerAcceptedKey, |
| 201 item->GetSafetyState() == DownloadItem::DANGEROUS_BUT_VALIDATED); | 203 item->GetSafetyState() == DownloadItem::DANGEROUS_BUT_VALIDATED); |
| 202 json->SetString(kStateKey, StateString(item->GetState())); | 204 json->SetString(kStateKey, StateString(item->GetState())); |
| 203 json->SetBoolean(kPausedKey, item->IsPaused()); | 205 json->SetBoolean(kPausedKey, item->IsPaused()); |
| 204 json->SetString(kMimeKey, item->GetMimeType()); | 206 json->SetString(kMimeKey, item->GetMimeType()); |
| 205 json->SetInteger(kStartTimeKey, | 207 json->SetInteger(kStartTimeKey, |
| 206 (item->GetStartTime() - base::Time::UnixEpoch()).InMilliseconds()); | 208 (item->GetStartTime() - base::Time::UnixEpoch()).InMilliseconds()); |
| 207 json->SetInteger(kBytesReceivedKey, item->GetReceivedBytes()); | 209 json->SetInteger(kBytesReceivedKey, item->GetReceivedBytes()); |
| 208 json->SetInteger(kTotalBytesKey, item->GetTotalBytes()); | 210 json->SetInteger(kTotalBytesKey, item->GetTotalBytes()); |
| 209 json->SetBoolean(kIncognito, item->IsOtr()); | 211 json->SetBoolean(kIncognito, incognito); |
| 210 if (item->GetState() == DownloadItem::INTERRUPTED) { | 212 if (item->GetState() == DownloadItem::INTERRUPTED) { |
| 211 json->SetInteger(kErrorKey, static_cast<int>(item->GetLastReason())); | 213 json->SetInteger(kErrorKey, static_cast<int>(item->GetLastReason())); |
| 212 } else if (item->GetState() == DownloadItem::CANCELLED) { | 214 } else if (item->GetState() == DownloadItem::CANCELLED) { |
| 213 json->SetInteger(kErrorKey, static_cast<int>( | 215 json->SetInteger(kErrorKey, static_cast<int>( |
| 214 content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED)); | 216 content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED)); |
| 215 } | 217 } |
| 216 // TODO(benjhayden): Implement endTime and fileSize. | 218 // TODO(benjhayden): Implement endTime and fileSize. |
| 217 // json->SetInteger(kEndTimeKey, -1); | 219 // json->SetInteger(kEndTimeKey, -1); |
| 218 json->SetInteger(kFileSizeKey, item->GetTotalBytes()); | 220 json->SetInteger(kFileSizeKey, item->GetTotalBytes()); |
| 219 return scoped_ptr<base::DictionaryValue>(json); | 221 return scoped_ptr<base::DictionaryValue>(json); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 sorter_types[kStartTimeKey] = DownloadQuery::SORT_START_TIME; | 313 sorter_types[kStartTimeKey] = DownloadQuery::SORT_START_TIME; |
| 312 sorter_types[kStateKey] = DownloadQuery::SORT_STATE; | 314 sorter_types[kStateKey] = DownloadQuery::SORT_STATE; |
| 313 sorter_types[kTotalBytesKey] = DownloadQuery::SORT_TOTAL_BYTES; | 315 sorter_types[kTotalBytesKey] = DownloadQuery::SORT_TOTAL_BYTES; |
| 314 sorter_types[kUrlKey] = DownloadQuery::SORT_URL; | 316 sorter_types[kUrlKey] = DownloadQuery::SORT_URL; |
| 315 } | 317 } |
| 316 | 318 |
| 317 bool IsNotTemporaryDownloadFilter(const DownloadItem& item) { | 319 bool IsNotTemporaryDownloadFilter(const DownloadItem& item) { |
| 318 return !item.IsTemporary(); | 320 return !item.IsTemporary(); |
| 319 } | 321 } |
| 320 | 322 |
| 323 // Set |manager| to the on-record DownloadManager, and |incognito_manager| to |
| 324 // the off-record DownloadManager if one exists and is requested via |
| 325 // |include_incognito|. This should work regardless of whether |profile| is |
| 326 // original or incognito. |
| 321 void GetManagers( | 327 void GetManagers( |
| 322 Profile* profile, | 328 Profile* profile, |
| 323 bool include_incognito, | 329 bool include_incognito, |
| 324 DownloadManager** manager, DownloadManager** incognito_manager) { | 330 DownloadManager** manager, |
| 325 *manager = BrowserContext::GetDownloadManager(profile); | 331 DownloadManager** incognito_manager) { |
| 326 *incognito_manager = NULL; | 332 *manager = BrowserContext::GetDownloadManager(profile->GetOriginalProfile()); |
| 327 if (include_incognito && profile->HasOffTheRecordProfile()) { | 333 if (profile->HasOffTheRecordProfile() && |
| 334 (include_incognito || |
| 335 profile->IsOffTheRecord())) { |
| 328 *incognito_manager = BrowserContext::GetDownloadManager( | 336 *incognito_manager = BrowserContext::GetDownloadManager( |
| 329 profile->GetOffTheRecordProfile()); | 337 profile->GetOffTheRecordProfile()); |
| 338 } else { |
| 339 *incognito_manager = NULL; |
| 330 } | 340 } |
| 331 } | 341 } |
| 332 | 342 |
| 333 DownloadItem* GetActiveItem(Profile* profile, bool include_incognito, int id) { | 343 DownloadItem* GetActiveItem(Profile* profile, bool include_incognito, int id) { |
| 334 DownloadManager* manager = NULL; | 344 DownloadManager* manager = NULL; |
| 335 DownloadManager* incognito_manager = NULL; | 345 DownloadManager* incognito_manager = NULL; |
| 336 GetManagers(profile, include_incognito, &manager, &incognito_manager); | 346 GetManagers(profile, include_incognito, &manager, &incognito_manager); |
| 337 DownloadItem* download_item = manager->GetDownload(id); | 347 DownloadItem* download_item = manager->GetDownload(id); |
| 338 if (!download_item && incognito_manager) | 348 if (!download_item && incognito_manager) |
| 339 download_item = incognito_manager->GetDownload(id); | 349 download_item = incognito_manager->GetDownload(id); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 if (sorter_type == sorter_types.Get().end()) { | 399 if (sorter_type == sorter_types.Get().end()) { |
| 390 *error = download_extension_errors::kInvalidOrderByError; | 400 *error = download_extension_errors::kInvalidOrderByError; |
| 391 return; | 401 return; |
| 392 } | 402 } |
| 393 query->AddSorter(sorter_type->second, direction); | 403 query->AddSorter(sorter_type->second, direction); |
| 394 } | 404 } |
| 395 } | 405 } |
| 396 | 406 |
| 397 void RunDownloadQuery( | 407 void RunDownloadQuery( |
| 398 const extensions::api::downloads::DownloadQuery& query_in, | 408 const extensions::api::downloads::DownloadQuery& query_in, |
| 399 Profile* profile, | 409 DownloadManager* manager, |
| 400 bool include_incognito, | 410 DownloadManager* incognito_manager, |
| 401 std::string* error, | 411 std::string* error, |
| 402 DownloadQuery::DownloadVector* results) { | 412 DownloadQuery::DownloadVector* results) { |
| 403 // TODO(benjhayden): Consider switching from LazyInstance to explicit string | 413 // TODO(benjhayden): Consider switching from LazyInstance to explicit string |
| 404 // comparisons. | 414 // comparisons. |
| 405 static base::LazyInstance<FilterTypeMap> filter_types = | 415 static base::LazyInstance<FilterTypeMap> filter_types = |
| 406 LAZY_INSTANCE_INITIALIZER; | 416 LAZY_INSTANCE_INITIALIZER; |
| 407 if (filter_types.Get().size() == 0) | 417 if (filter_types.Get().size() == 0) |
| 408 InitFilterTypeMap(filter_types.Get()); | 418 InitFilterTypeMap(filter_types.Get()); |
| 409 | 419 |
| 410 DownloadQuery query_out; | 420 DownloadQuery query_out; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 FilterTypeMap::const_iterator filter_type = | 456 FilterTypeMap::const_iterator filter_type = |
| 447 filter_types.Get().find(query_json_field.key()); | 457 filter_types.Get().find(query_json_field.key()); |
| 448 if (filter_type != filter_types.Get().end()) { | 458 if (filter_type != filter_types.Get().end()) { |
| 449 if (!query_out.AddFilter(filter_type->second, query_json_field.value())) { | 459 if (!query_out.AddFilter(filter_type->second, query_json_field.value())) { |
| 450 *error = download_extension_errors::kInvalidFilterError; | 460 *error = download_extension_errors::kInvalidFilterError; |
| 451 return; | 461 return; |
| 452 } | 462 } |
| 453 } | 463 } |
| 454 } | 464 } |
| 455 | 465 |
| 456 DownloadManager* manager = NULL; | |
| 457 DownloadManager* incognito_manager = NULL; | |
| 458 GetManagers(profile, include_incognito, &manager, &incognito_manager); | |
| 459 DownloadQuery::DownloadVector all_items; | 466 DownloadQuery::DownloadVector all_items; |
| 460 if (query_in.id.get()) { | 467 if (query_in.id.get()) { |
| 461 DownloadItem* item = manager->GetDownload(*query_in.id.get()); | 468 DownloadItem* item = manager->GetDownload(*query_in.id.get()); |
| 462 if (!item && incognito_manager) | 469 if (!item && incognito_manager) |
| 463 item = incognito_manager->GetDownload(*query_in.id.get()); | 470 item = incognito_manager->GetDownload(*query_in.id.get()); |
| 464 if (item) | 471 if (item) |
| 465 all_items.push_back(item); | 472 all_items.push_back(item); |
| 466 } else { | 473 } else { |
| 467 manager->GetAllDownloads(FilePath(FILE_PATH_LITERAL("")), &all_items); | 474 manager->GetAllDownloads(FilePath(FILE_PATH_LITERAL("")), &all_items); |
| 468 if (incognito_manager) | 475 if (incognito_manager) |
| 469 incognito_manager->GetAllDownloads( | 476 incognito_manager->GetAllDownloads( |
| 470 FilePath(FILE_PATH_LITERAL("")), &all_items); | 477 FilePath(FILE_PATH_LITERAL("")), &all_items); |
| 471 } | 478 } |
| 472 query_out.Search(all_items.begin(), all_items.end(), results); | 479 query_out.Search(all_items.begin(), all_items.end(), results); |
| 473 } | 480 } |
| 474 | 481 |
| 482 void DispatchEventInternal( |
| 483 Profile* target_profile, |
| 484 const char* event_name, |
| 485 const std::string& json_args, |
| 486 scoped_ptr<base::ListValue> event_args) { |
| 487 target_profile->GetExtensionEventRouter()->DispatchEventToRenderers( |
| 488 event_name, |
| 489 event_args.Pass(), |
| 490 target_profile, |
| 491 GURL(), |
| 492 extensions::EventFilteringInfo()); |
| 493 |
| 494 ExtensionDownloadsEventRouter::DownloadsNotificationSource |
| 495 notification_source; |
| 496 notification_source.event_name = event_name; |
| 497 notification_source.profile = target_profile; |
| 498 content::Source<ExtensionDownloadsEventRouter::DownloadsNotificationSource> |
| 499 content_source(¬ification_source); |
| 500 std::string args_copy(json_args); |
| 501 content::NotificationService::current()->Notify( |
| 502 chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, |
| 503 content_source, |
| 504 content::Details<std::string>(&args_copy)); |
| 505 } |
| 506 |
| 475 } // namespace | 507 } // namespace |
| 476 | 508 |
| 477 DownloadsDownloadFunction::DownloadsDownloadFunction() {} | 509 DownloadsDownloadFunction::DownloadsDownloadFunction() {} |
| 478 DownloadsDownloadFunction::~DownloadsDownloadFunction() {} | 510 DownloadsDownloadFunction::~DownloadsDownloadFunction() {} |
| 479 | 511 |
| 480 bool DownloadsDownloadFunction::RunImpl() { | 512 bool DownloadsDownloadFunction::RunImpl() { |
| 481 scoped_ptr<extensions::api::downloads::Download::Params> params( | 513 scoped_ptr<extensions::api::downloads::Download::Params> params( |
| 482 extensions::api::downloads::Download::Params::Create(*args_)); | 514 extensions::api::downloads::Download::Params::Create(*args_)); |
| 483 EXTENSION_FUNCTION_VALIDATE(params.get()); | 515 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 484 const extensions::api::downloads::DownloadOptions& options = params->options; | 516 const extensions::api::downloads::DownloadOptions& options = params->options; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 SendResponse(error_.empty()); | 599 SendResponse(error_.empty()); |
| 568 } | 600 } |
| 569 | 601 |
| 570 DownloadsSearchFunction::DownloadsSearchFunction() {} | 602 DownloadsSearchFunction::DownloadsSearchFunction() {} |
| 571 DownloadsSearchFunction::~DownloadsSearchFunction() {} | 603 DownloadsSearchFunction::~DownloadsSearchFunction() {} |
| 572 | 604 |
| 573 bool DownloadsSearchFunction::RunImpl() { | 605 bool DownloadsSearchFunction::RunImpl() { |
| 574 scoped_ptr<extensions::api::downloads::Search::Params> params( | 606 scoped_ptr<extensions::api::downloads::Search::Params> params( |
| 575 extensions::api::downloads::Search::Params::Create(*args_)); | 607 extensions::api::downloads::Search::Params::Create(*args_)); |
| 576 EXTENSION_FUNCTION_VALIDATE(params.get()); | 608 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 609 DownloadManager* manager = NULL; |
| 610 DownloadManager* incognito_manager = NULL; |
| 611 GetManagers(profile(), include_incognito(), &manager, &incognito_manager); |
| 577 DownloadQuery::DownloadVector results; | 612 DownloadQuery::DownloadVector results; |
| 578 RunDownloadQuery(params->query, profile(), include_incognito(), | 613 RunDownloadQuery(params->query, |
| 579 &error_, &results); | 614 manager, |
| 615 incognito_manager, |
| 616 &error_, |
| 617 &results); |
| 580 if (!error_.empty()) | 618 if (!error_.empty()) |
| 581 return false; | 619 return false; |
| 620 |
| 582 base::ListValue* json_results = new base::ListValue(); | 621 base::ListValue* json_results = new base::ListValue(); |
| 583 for (DownloadManager::DownloadVector::const_iterator it = results.begin(); | 622 for (DownloadManager::DownloadVector::const_iterator it = results.begin(); |
| 584 it != results.end(); ++it) { | 623 it != results.end(); ++it) { |
| 585 scoped_ptr<base::DictionaryValue> item(DownloadItemToJSON(*it)); | 624 DownloadItem* item = *it; |
| 586 json_results->Append(item.release()); | 625 int32 download_id = item->GetId(); |
| 626 bool off_record = ((incognito_manager != NULL) && |
| 627 (incognito_manager->GetDownload(download_id) != NULL)); |
| 628 scoped_ptr<base::DictionaryValue> json_item(DownloadItemToJSON( |
| 629 *it, off_record)); |
| 630 json_results->Append(json_item.release()); |
| 587 } | 631 } |
| 588 SetResult(json_results); | 632 SetResult(json_results); |
| 589 RecordApiFunctions(DOWNLOADS_FUNCTION_SEARCH); | 633 RecordApiFunctions(DOWNLOADS_FUNCTION_SEARCH); |
| 590 return true; | 634 return true; |
| 591 } | 635 } |
| 592 | 636 |
| 593 DownloadsPauseFunction::DownloadsPauseFunction() {} | 637 DownloadsPauseFunction::DownloadsPauseFunction() {} |
| 594 DownloadsPauseFunction::~DownloadsPauseFunction() {} | 638 DownloadsPauseFunction::~DownloadsPauseFunction() {} |
| 595 | 639 |
| 596 bool DownloadsPauseFunction::RunImpl() { | 640 bool DownloadsPauseFunction::RunImpl() { |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 } | 833 } |
| 790 SendResponse(error_.empty()); | 834 SendResponse(error_.empty()); |
| 791 } | 835 } |
| 792 | 836 |
| 793 ExtensionDownloadsEventRouter::ExtensionDownloadsEventRouter( | 837 ExtensionDownloadsEventRouter::ExtensionDownloadsEventRouter( |
| 794 Profile* profile, | 838 Profile* profile, |
| 795 DownloadManager* manager) | 839 DownloadManager* manager) |
| 796 : profile_(profile), | 840 : profile_(profile), |
| 797 manager_(manager) { | 841 manager_(manager) { |
| 798 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 842 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 799 DCHECK(profile_); | |
| 800 DCHECK(manager_); | |
| 801 manager_->AddObserver(this); | 843 manager_->AddObserver(this); |
| 802 } | 844 } |
| 803 | 845 |
| 804 ExtensionDownloadsEventRouter::~ExtensionDownloadsEventRouter() { | 846 ExtensionDownloadsEventRouter::~ExtensionDownloadsEventRouter() { |
| 805 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 847 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 806 if (manager_ != NULL) | 848 if (manager_ != NULL) |
| 807 manager_->RemoveObserver(this); | 849 manager_->RemoveObserver(this); |
| 808 for (ItemMap::const_iterator iter = downloads_.begin(); | 850 for (ItemMap::const_iterator iter = downloads_.begin(); |
| 809 iter != downloads_.end(); ++iter) { | 851 iter != downloads_.end(); ++iter) { |
| 810 if (iter->second != NULL) | 852 if (iter->second != NULL) |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 844 base::Value::CreateIntegerValue(download_id)); | 886 base::Value::CreateIntegerValue(download_id)); |
| 845 } | 887 } |
| 846 | 888 |
| 847 void ExtensionDownloadsEventRouter::OnDownloadUpdated(DownloadItem* item) { | 889 void ExtensionDownloadsEventRouter::OnDownloadUpdated(DownloadItem* item) { |
| 848 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 890 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 849 if (!profile_) | 891 if (!profile_) |
| 850 return; | 892 return; |
| 851 int download_id = item->GetId(); | 893 int download_id = item->GetId(); |
| 852 | 894 |
| 853 base::DictionaryValue* old_json = item_jsons_[download_id]; | 895 base::DictionaryValue* old_json = item_jsons_[download_id]; |
| 854 scoped_ptr<base::DictionaryValue> new_json(DownloadItemToJSON(item)); | 896 scoped_ptr<base::DictionaryValue> new_json(DownloadItemToJSON( |
| 897 item, profile_->IsOffTheRecord())); |
| 855 scoped_ptr<base::DictionaryValue> delta(new base::DictionaryValue()); | 898 scoped_ptr<base::DictionaryValue> delta(new base::DictionaryValue()); |
| 856 delta->SetInteger(kIdKey, download_id); | 899 delta->SetInteger(kIdKey, download_id); |
| 857 std::set<std::string> new_fields; | 900 std::set<std::string> new_fields; |
| 858 bool changed = false; | 901 bool changed = false; |
| 859 | 902 |
| 860 // For each field in the new json representation of the item except the | 903 // For each field in the new json representation of the item except the |
| 861 // bytesReceived field, if the field has changed from the previous old json, | 904 // bytesReceived field, if the field has changed from the previous old json, |
| 862 // set the differences in the |delta| object and remember that something | 905 // set the differences in the |delta| object and remember that something |
| 863 // significant changed. | 906 // significant changed. |
| 864 for (base::DictionaryValue::Iterator iter(*new_json.get()); | 907 for (base::DictionaryValue::Iterator iter(*new_json.get()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 898 } | 941 } |
| 899 | 942 |
| 900 void ExtensionDownloadsEventRouter::OnDownloadCreated( | 943 void ExtensionDownloadsEventRouter::OnDownloadCreated( |
| 901 DownloadManager* manager, DownloadItem* download_item) { | 944 DownloadManager* manager, DownloadItem* download_item) { |
| 902 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 945 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 903 DCHECK(manager_ == manager); | 946 DCHECK(manager_ == manager); |
| 904 if (download_item->IsTemporary()) return; | 947 if (download_item->IsTemporary()) return; |
| 905 | 948 |
| 906 download_item->AddObserver(this); | 949 download_item->AddObserver(this); |
| 907 scoped_ptr<base::DictionaryValue> json_item( | 950 scoped_ptr<base::DictionaryValue> json_item( |
| 908 DownloadItemToJSON(download_item)); | 951 DownloadItemToJSON(download_item, profile_->IsOffTheRecord())); |
| 909 DispatchEvent(extensions::event_names::kOnDownloadCreated, | 952 DispatchEvent(extensions::event_names::kOnDownloadCreated, |
| 910 json_item->DeepCopy()); | 953 json_item->DeepCopy()); |
| 911 int32 download_id = download_item->GetId(); | 954 int32 download_id = download_item->GetId(); |
| 912 DCHECK(item_jsons_.find(download_id) == item_jsons_.end()); | 955 DCHECK(item_jsons_.find(download_id) == item_jsons_.end()); |
| 913 on_changed_stats_[download_id] = new OnChangedStat(); | 956 on_changed_stats_[download_id] = new OnChangedStat(); |
| 914 item_jsons_[download_id] = json_item.release(); | 957 item_jsons_[download_id] = json_item.release(); |
| 915 downloads_[download_id] = download_item; | 958 downloads_[download_id] = download_item; |
| 916 } | 959 } |
| 917 | 960 |
| 918 void ExtensionDownloadsEventRouter::ManagerGoingDown( | 961 void ExtensionDownloadsEventRouter::ManagerGoingDown( |
| 919 DownloadManager* manager) { | 962 DownloadManager* manager) { |
| 920 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 963 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 921 manager_->RemoveObserver(this); | 964 manager_->RemoveObserver(this); |
| 922 manager_ = NULL; | 965 manager_ = NULL; |
| 923 profile_ = NULL; | 966 profile_ = NULL; |
| 924 } | 967 } |
| 925 | 968 |
| 926 void ExtensionDownloadsEventRouter::DispatchEvent( | 969 void ExtensionDownloadsEventRouter::DispatchEvent( |
| 927 const char* event_name, base::Value* arg) { | 970 const char* event_name, base::Value* arg) { |
| 928 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 971 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 929 scoped_ptr<ListValue> args(new ListValue()); | 972 scoped_ptr<base::ListValue> args(new base::ListValue()); |
| 930 args->Append(arg); | 973 args->Append(arg); |
| 931 std::string json_args; | 974 std::string json_args; |
| 932 base::JSONWriter::Write(args.get(), &json_args); | 975 base::JSONWriter::Write(args.get(), &json_args); |
| 933 | 976 // There is a one EDER for each on-record Profile, and a separate EDER for |
| 934 profile_->GetExtensionEventRouter()->DispatchEventToRenderers( | 977 // each off-record Profile, so there is exactly one EDER for each |
| 935 event_name, | 978 // DownloadManager. EDER only watches its own DM, so all the items that an |
| 936 args.Pass(), | 979 // EDER sees are either all on-record or all off-record. However, we want |
| 937 profile_, | 980 // extensions in off-record contexts to see on-record items. So, if this EDER |
| 938 GURL(), | 981 // is watching an on-record DM, and there is a corresponding off-record |
| 939 extensions::EventFilteringInfo()); | 982 // Profile, then dispatch this event to both the on-record Profile and the |
| 940 | 983 // off-record Profile. There may or may not be an off-record Profile, so send |
| 941 DownloadsNotificationSource notification_source; | 984 // a *copy* of |args| to the off-record Profile, and Pass() |args| |
| 942 notification_source.event_name = event_name; | 985 // to the Profile that we know is there. |
| 943 notification_source.profile = profile_; | 986 if (profile_->HasOffTheRecordProfile() && |
| 944 content::NotificationService::current()->Notify( | 987 !profile_->IsOffTheRecord()) { |
| 945 chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, | 988 DispatchEventInternal( |
| 946 content::Source<DownloadsNotificationSource>(¬ification_source), | 989 profile_->GetOffTheRecordProfile(), |
| 947 content::Details<std::string>(&json_args)); | 990 event_name, |
| 991 json_args, |
| 992 scoped_ptr<base::ListValue>(args->DeepCopy())); |
| 993 } |
| 994 DispatchEventInternal(profile_, event_name, json_args, args.Pass()); |
| 948 } | 995 } |
| OLD | NEW |