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 |