Index: chrome/browser/extensions/api/downloads/downloads_api.cc |
diff --git a/chrome/browser/extensions/api/downloads/downloads_api.cc b/chrome/browser/extensions/api/downloads/downloads_api.cc |
index 7273640ba14c7b2e9a24784fdc63b51bb7fc7c87..dc0a0a771df5c2a71efc0b484431d775d83201ca 100644 |
--- a/chrome/browser/extensions/api/downloads/downloads_api.cc |
+++ b/chrome/browser/extensions/api/downloads/downloads_api.cc |
@@ -29,6 +29,7 @@ |
#include "chrome/browser/browser_process.h" |
#include "chrome/browser/download/download_danger_prompt.h" |
#include "chrome/browser/download/download_file_icon_extractor.h" |
+#include "chrome/browser/download/download_prefs.h" |
#include "chrome/browser/download/download_query.h" |
#include "chrome/browser/download/download_service.h" |
#include "chrome/browser/download/download_service_factory.h" |
@@ -42,6 +43,7 @@ |
#include "chrome/browser/extensions/extension_system.h" |
#include "chrome/browser/icon_loader.h" |
#include "chrome/browser/icon_manager.h" |
+#include "chrome/browser/platform_util.h" |
#include "chrome/browser/renderer_host/chrome_render_message_filter.h" |
#include "chrome/browser/ui/browser.h" |
#include "chrome/common/cancelable_task_tracker.h" |
@@ -87,6 +89,8 @@ const char kInvalidOrderByError[] = "Invalid orderBy field"; |
const char kInvalidQueryLimit[] = "Invalid query limit"; |
const char kInvalidStateError[] = "Invalid state"; |
const char kInvalidURLError[] = "Invalid URL"; |
+const char kNotPermittedURLError[] = "In order to access that URL, this " |
+ "extension must add the host to \"permissions\" in manifest.json"; |
const char kNotImplementedError[] = "NotImplemented"; |
const char kTooManyListenersError[] = "Each extension may have at most one " |
"onDeterminingFilename listener between all of its renderer execution " |
@@ -101,19 +105,20 @@ const int kDefaultIconSize = 32; |
// Parameter keys |
const char kBytesReceivedKey[] = "bytesReceived"; |
-const char kDangerAcceptedKey[] = "dangerAccepted"; |
+const char kCanResumeKey[] = "canResume"; |
+const char kDangerAccepted[] = "accepted"; |
const char kDangerContent[] = "content"; |
const char kDangerFile[] = "file"; |
+const char kDangerHost[] = "host"; |
const char kDangerKey[] = "danger"; |
const char kDangerSafe[] = "safe"; |
const char kDangerUncommon[] = "uncommon"; |
-const char kDangerAccepted[] = "accepted"; |
-const char kDangerHost[] = "host"; |
const char kDangerUrl[] = "url"; |
const char kEndTimeKey[] = "endTime"; |
const char kEndedAfterKey[] = "endedAfter"; |
const char kEndedBeforeKey[] = "endedBefore"; |
const char kErrorKey[] = "error"; |
+const char kEstimatedEndTimeKey[] = "estimatedEndTime"; |
const char kExistsKey[] = "exists"; |
const char kFileSizeKey[] = "fileSize"; |
const char kFilenameKey[] = "filename"; |
@@ -123,6 +128,7 @@ const char kIncognito[] = "incognito"; |
const char kMimeKey[] = "mime"; |
const char kPausedKey[] = "paused"; |
const char kQueryKey[] = "query"; |
+const char kReferrerUrlKey[] = "referrer"; |
const char kStartTimeKey[] = "startTime"; |
const char kStartedAfterKey[] = "startedAfter"; |
const char kStartedBeforeKey[] = "startedBefore"; |
@@ -215,15 +221,14 @@ scoped_ptr<base::DictionaryValue> DownloadItemToJSON( |
json->SetInteger(kIdKey, download_item->GetId()); |
const GURL& url = download_item->GetOriginalUrl(); |
json->SetString(kUrlKey, (url.is_valid() ? url.spec() : std::string())); |
+ const GURL& referrer = download_item->GetReferrerUrl(); |
+ json->SetString(kReferrerUrlKey, (referrer.is_valid() ? referrer.spec() |
+ : std::string())); |
json->SetString(kFilenameKey, |
download_item->GetTargetFilePath().LossyDisplayName()); |
json->SetString(kDangerKey, DangerString(download_item->GetDangerType())); |
- if (download_item->GetDangerType() != |
- content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) |
- json->SetBoolean(kDangerAcceptedKey, |
- download_item->GetDangerType() == |
- content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED); |
json->SetString(kStateKey, StateString(download_item->GetState())); |
+ json->SetBoolean(kCanResumeKey, download_item->CanResume()); |
json->SetBoolean(kPausedKey, download_item->IsPaused()); |
json->SetString(kMimeKey, download_item->GetMimeType()); |
json->SetString(kStartTimeKey, TimeToISO8601(download_item->GetStartTime())); |
@@ -239,6 +244,11 @@ scoped_ptr<base::DictionaryValue> DownloadItemToJSON( |
} |
if (!download_item->GetEndTime().is_null()) |
json->SetString(kEndTimeKey, TimeToISO8601(download_item->GetEndTime())); |
+ base::TimeDelta time_remaining; |
+ if (download_item->TimeRemaining(&time_remaining)) { |
+ base::Time now = base::Time::Now(); |
+ json->SetString(kEstimatedEndTimeKey, TimeToISO8601(now + time_remaining)); |
+ } |
// TODO(benjhayden): Implement fileSize. |
json->SetInteger(kFileSizeKey, download_item->GetTotalBytes()); |
return scoped_ptr<base::DictionaryValue>(json); |
@@ -299,7 +309,6 @@ typedef base::hash_map<std::string, DownloadQuery::FilterType> FilterTypeMap; |
void InitFilterTypeMap(FilterTypeMap& filter_types) { |
filter_types[kBytesReceivedKey] = DownloadQuery::FILTER_BYTES_RECEIVED; |
- filter_types[kDangerAcceptedKey] = DownloadQuery::FILTER_DANGER_ACCEPTED; |
filter_types[kExistsKey] = DownloadQuery::FILTER_EXISTS; |
filter_types[kFilenameKey] = DownloadQuery::FILTER_FILENAME; |
filter_types[kFilenameRegexKey] = DownloadQuery::FILTER_FILENAME_REGEX; |
@@ -325,7 +334,6 @@ typedef base::hash_map<std::string, DownloadQuery::SortType> SortTypeMap; |
void InitSortTypeMap(SortTypeMap& sorter_types) { |
sorter_types[kBytesReceivedKey] = DownloadQuery::SORT_BYTES_RECEIVED; |
sorter_types[kDangerKey] = DownloadQuery::SORT_DANGER; |
- sorter_types[kDangerAcceptedKey] = DownloadQuery::SORT_DANGER_ACCEPTED; |
sorter_types[kEndTimeKey] = DownloadQuery::SORT_END_TIME; |
sorter_types[kExistsKey] = DownloadQuery::SORT_EXISTS; |
sorter_types[kFilenameKey] = DownloadQuery::SORT_FILENAME; |
@@ -807,13 +815,15 @@ bool DownloadsDownloadFunction::RunImpl() { |
EXTENSION_FUNCTION_VALIDATE(params.get()); |
const extensions::api::downloads::DownloadOptions& options = params->options; |
GURL download_url(options.url); |
- if (!download_url.is_valid() || |
- (!download_url.SchemeIs("data") && |
- download_url.GetOrigin() != GetExtension()->url().GetOrigin() && |
- !extensions::PermissionsData::HasHostPermission(GetExtension(), |
- download_url))) { |
+ if (!download_url.is_valid()) { |
error_ = download_extension_errors::kInvalidURLError; |
return false; |
+ } else if (!download_url.SchemeIs("data") && |
+ download_url.GetOrigin() != GetExtension()->url().GetOrigin() && |
+ !extensions::PermissionsData::HasHostPermission(GetExtension(), |
+ download_url)) { |
+ error_ = download_extension_errors::kNotPermittedURLError; |
+ return false; |
} |
Profile* current_profile = profile(); |
@@ -1063,19 +1073,29 @@ bool DownloadsAcceptDangerFunction::RunImpl() { |
base::Bind(&DownloadsAcceptDangerFunction::DangerPromptCallback, |
this, true, params->download_id), |
base::Bind(&DownloadsAcceptDangerFunction::DangerPromptCallback, |
- this, false, params->download_id)); |
+ this, false, params->download_id), |
+ base::Bind(&DownloadsAcceptDangerFunction::DangerPromptDestroyed, |
+ this)); |
// DownloadDangerPrompt deletes itself |
return true; |
} |
void DownloadsAcceptDangerFunction::DangerPromptCallback( |
bool accept, int download_id) { |
+ DownloadItem* download_item = GetDownloadIfInProgress( |
+ profile(), include_incognito(), download_id); |
+ if (!download_item) { |
+ error_ = download_extension_errors::kInvalidOperationError; |
+ return; |
+ } |
if (accept) { |
- DownloadItem* download_item = GetDownloadIfInProgress( |
- profile(), include_incognito(), download_id); |
- if (download_item) |
- download_item->ValidateDangerousDownload(); |
+ download_item->ValidateDangerousDownload(); |
+ } else { |
+ download_item->Remove(); |
} |
+} |
+ |
+void DownloadsAcceptDangerFunction::DangerPromptDestroyed() { |
SendResponse(error_.empty()); |
} |
@@ -1087,13 +1107,21 @@ bool DownloadsShowFunction::RunImpl() { |
scoped_ptr<extensions::api::downloads::Show::Params> params( |
extensions::api::downloads::Show::Params::Create(*args_)); |
EXTENSION_FUNCTION_VALIDATE(params.get()); |
- DownloadItem* download_item = GetDownload( |
- profile(), include_incognito(), params->download_id); |
- if (!download_item) { |
- error_ = download_extension_errors::kInvalidOperationError; |
- return false; |
+ if (params->download_id) { |
+ DownloadItem* download_item = GetDownload( |
+ profile(), include_incognito(), *params->download_id); |
+ if (!download_item) { |
+ error_ = download_extension_errors::kInvalidOperationError; |
+ return false; |
+ } |
+ download_item->ShowDownloadInShell(); |
+ } else { |
+ DownloadManager* manager = NULL; |
+ DownloadManager* incognito_manager = NULL; |
+ GetManagers(profile(), include_incognito(), &manager, &incognito_manager); |
+ platform_util::OpenItem(DownloadPrefs::FromDownloadManager( |
+ manager)->DownloadPath()); |
} |
- download_item->ShowDownloadInShell(); |
RecordApiFunctions(DOWNLOADS_FUNCTION_SHOW); |
return true; |
} |
@@ -1428,7 +1456,8 @@ void ExtensionDownloadsEventRouter::OnDownloadUpdated( |
for (base::DictionaryValue::Iterator iter(*new_json.get()); |
!iter.IsAtEnd(); iter.Advance()) { |
new_fields.insert(iter.key()); |
- if (iter.key() != kBytesReceivedKey) { |
+ if ((iter.key() != kBytesReceivedKey) && |
+ (iter.key() != kEstimatedEndTimeKey)) { |
const base::Value* old_value = NULL; |
if (!data->json().HasKey(iter.key()) || |
(data->json().Get(iter.key(), &old_value) && |
@@ -1445,7 +1474,9 @@ void ExtensionDownloadsEventRouter::OnDownloadUpdated( |
// difference in |delta|. |
for (base::DictionaryValue::Iterator iter(data->json()); |
!iter.IsAtEnd(); iter.Advance()) { |
- if (new_fields.find(iter.key()) == new_fields.end()) { |
+ if ((new_fields.find(iter.key()) == new_fields.end()) && |
+ (iter.key() != kEstimatedEndTimeKey)) { |
+ // estimatedEndTime disappears after completion, but bytesReceived stays. |
delta->Set(iter.key() + ".previous", iter.value().DeepCopy()); |
changed = true; |
} |