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

Side by Side Diff: chrome/browser/extensions/extension_downloads_api.cc

Issue 7825035: Implement chrome.experimental.downloads.search() (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: comments Created 9 years, 2 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/extension_downloads_api.h" 5 #include "chrome/browser/extensions/extension_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>
11 #include <string> 11 #include <string>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/callback.h" 14 #include "base/callback.h"
15 #include "base/json/json_writer.h" 15 #include "base/json/json_writer.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "base/stl_util.h" 18 #include "base/stl_util.h"
19 #include "base/string16.h" 19 #include "base/string16.h"
20 #include "base/string_util.h" 20 #include "base/string_util.h"
21 #include "base/stringprintf.h" 21 #include "base/stringprintf.h"
22 #include "base/values.h" 22 #include "base/values.h"
23 #include "chrome/browser/browser_process.h" 23 #include "chrome/browser/browser_process.h"
24 #include "chrome/browser/download/download_service.h" 24 #include "chrome/browser/download/download_service.h"
25 #include "chrome/browser/download/download_service_factory.h" 25 #include "chrome/browser/download/download_service_factory.h"
26 #include "chrome/browser/download/download_util.h" 26 #include "chrome/browser/download/download_util.h"
27 #include "chrome/browser/extensions/extension_downloads_api_constants.h"
28 #include "chrome/browser/extensions/extension_event_names.h" 27 #include "chrome/browser/extensions/extension_event_names.h"
29 #include "chrome/browser/extensions/extension_event_router.h" 28 #include "chrome/browser/extensions/extension_event_router.h"
30 #include "chrome/browser/icon_loader.h" 29 #include "chrome/browser/icon_loader.h"
31 #include "chrome/browser/icon_manager.h" 30 #include "chrome/browser/icon_manager.h"
32 #include "chrome/browser/renderer_host/chrome_render_message_filter.h" 31 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
33 #include "chrome/browser/ui/browser_list.h" 32 #include "chrome/browser/ui/browser_list.h"
34 #include "content/browser/download/download_file_manager.h" 33 #include "content/browser/download/download_file_manager.h"
35 #include "content/browser/download/download_item.h" 34 #include "content/browser/download/download_item.h"
36 #include "content/browser/download/download_types.h" 35 #include "content/browser/download/download_types.h"
37 #include "content/browser/download/interrupt_reasons.h" 36 #include "content/browser/download/interrupt_reasons.h"
38 #include "content/browser/renderer_host/render_process_host.h" 37 #include "content/browser/renderer_host/render_process_host.h"
39 #include "content/browser/renderer_host/render_view_host.h" 38 #include "content/browser/renderer_host/render_view_host.h"
40 #include "content/browser/renderer_host/resource_dispatcher_host.h" 39 #include "content/browser/renderer_host/resource_dispatcher_host.h"
41 #include "net/http/http_util.h" 40 #include "net/http/http_util.h"
42 #include "net/url_request/url_request.h" 41 #include "net/url_request/url_request.h"
43 42
44 namespace constants = extension_downloads_api_constants; 43 namespace {
44
45 namespace constants {
46
47 // Error messages
48 const char kNotImplemented[] = "NotImplemented";
49 const char kGenericError[] = "I'm afraid I can't do that.";
50 const char kInvalidURL[] = "Invalid URL";
51
52 // Parameter keys
53 const char kBodyKey[] = "body";
54 const char kBytesReceivedKey[] = "bytesReceived";
55 const char kDangerAcceptedKey[] = "dangerAccepted";
56 const char kDangerFile[] = "file";
57 const char kDangerKey[] = "danger";
58 const char kDangerSafe[] = "safe";
59 const char kDangerUrl[] = "url";
60 const char kEndTimeKey[] = "endTime";
61 const char kEndedAfterKey[] = "endedAfter";
62 const char kEndedBeforeKey[] = "endedBefore";
63 const char kErrorKey[] = "error";
64 const char kFileSizeGreaterKey[] = "fileSizeGreater";
65 const char kFileSizeKey[] = "fileSize";
66 const char kFileSizeLessKey[] = "fileSizeLess";
67 const char kFilenameKey[] = "filename";
68 const char kFilenameRegexKey[] = "filenameRegex";
69 const char kHeaderNameKey[] = "name";
70 const char kHeaderValueKey[] = "value";
71 const char kHeadersKey[] = "headers";
72 const char kIdKey[] = "id";
73 const char kLimitKey[] = "limit";
74 const char kMethodKey[] = "method";
75 const char kMimeKey[] = "mime";
76 const char kOrderByKey[] = "orderBy";
77 const char kPausedKey[] = "paused";
78 const char kQueryKey[] = "query";
79 const char kSaveAsKey[] = "saveAs";
80 const char kStartTimeKey[] = "startTime";
81 const char kStartedAfterKey[] = "startedAfter";
82 const char kStartedBeforeKey[] = "startedBefore";
83 const char kStateComplete[] = "complete";
84 const char kStateInProgress[] = "in_progress";
85 const char kStateInterrupted[] = "interrupted";
86 const char kStateKey[] = "state";
87 const char kTotalBytesGreaterKey[] = "totalBytesGreater";
88 const char kTotalBytesKey[] = "totalBytes";
89 const char kTotalBytesLessKey[] = "totalBytesLess";
90 const char kUrlKey[] = "url";
91 const char kUrlRegexKey[] = "urlRegex";
92
93 const char* DangerString(DownloadItem::DangerType danger) {
94 switch (danger) {
95 case DownloadItem::NOT_DANGEROUS: return kDangerSafe;
96 case DownloadItem::DANGEROUS_FILE: return kDangerFile;
97 case DownloadItem::DANGEROUS_URL: return kDangerUrl;
98 default:
99 NOTREACHED();
100 return "";
101 }
102 }
103
104 const char* StateString(DownloadItem::DownloadState state) {
105 switch (state) {
106 case DownloadItem::IN_PROGRESS: return kStateInProgress;
107 case DownloadItem::COMPLETE: return kStateComplete;
108 case DownloadItem::INTERRUPTED: // fall through
109 case DownloadItem::CANCELLED: return kStateInterrupted;
110 case DownloadItem::REMOVING: // fall through
111 default:
112 NOTREACHED();
113 return "";
114 }
115 }
116
117 DownloadItem::DangerType DangerEnumFromString(const std::string& danger) {
118 if (danger == kDangerSafe) return DownloadItem::NOT_DANGEROUS;
119 if (danger == kDangerFile) return DownloadItem::DANGEROUS_FILE;
120 if (danger == kDangerUrl) return DownloadItem::DANGEROUS_URL;
121 return DownloadItem::DANGEROUS_TYPE_MAX;
122 }
123
124 DownloadItem::DownloadState StateEnumFromString(const std::string& state) {
125 if (state == kStateInProgress) return DownloadItem::IN_PROGRESS;
126 if (state == kStateComplete) return DownloadItem::COMPLETE;
127 if (state == kStateInterrupted) return DownloadItem::INTERRUPTED;
128 return DownloadItem::MAX_DOWNLOAD_STATE;
129 }
130
131 } // namespace constants
132
133 base::DictionaryValue* DownloadItemToJSON(DownloadItem* item) {
134 base::DictionaryValue* json = new base::DictionaryValue();
135 json->SetInteger(constants::kIdKey, item->id());
136 json->SetString(constants::kUrlKey, item->original_url().spec());
137 json->SetString(constants::kFilenameKey,
138 item->full_path().LossyDisplayName());
139 json->SetString(constants::kDangerKey,
140 constants::DangerString(item->GetDangerType()));
141 json->SetBoolean(constants::kDangerAcceptedKey,
142 item->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED);
Randy Smith (Not in Mondays) 2011/10/13 23:23:11 If it's not dangerous, should this value be set at
benjhayden 2011/10/14 19:31:02 I hadn't thought about it, that makes sense.
143 json->SetString(constants::kStateKey,
144 constants::StateString(item->state()));
145 json->SetBoolean(constants::kPausedKey, item->is_paused());
146 json->SetString(constants::kMimeKey, item->mime_type());
147 // TODO(benjhayden): Change startTime to a double!
148 json->SetInteger(constants::kStartTimeKey,
149 (item->start_time() - base::Time::UnixEpoch()).InMilliseconds());
150 json->SetInteger(constants::kBytesReceivedKey, item->received_bytes());
151 json->SetInteger(constants::kTotalBytesKey, item->total_bytes());
152 if (item->state() == DownloadItem::INTERRUPTED)
153 json->SetInteger(constants::kErrorKey,
154 static_cast<int>(item->last_reason()));
155 // TODO(benjhayden): Implement endTime and fileSize.
156 // json->SetInteger(constants::kEndTimeKey, -1);
157 json->SetInteger(constants::kFileSizeKey, item->total_bytes());
158 return json;
159 }
160
161 template <typename T>
162 bool GetJsonValue(base::DictionaryValue* json, const char* name, T* value);
163
164 template<>
165 bool GetJsonValue(base::DictionaryValue* json, const char* name, int* value) {
166 return json->GetInteger(name, value);
167 }
168
169 template<>
170 bool GetJsonValue(base::DictionaryValue* json, const char* name,
171 string16* value) {
172 return json->GetString(name, value);
173 }
174
175 template<>
176 bool GetJsonValue(base::DictionaryValue* json, const char* name,
177 std::string* value) {
178 return json->GetString(name, value);
179 }
180
181 template<>
182 bool GetJsonValue(base::DictionaryValue* json, const char* name, bool* value) {
183 return json->GetBoolean(name, value);
184 }
185
186 } // anonymous namespace
45 187
46 bool DownloadsFunctionInterface::RunImplImpl( 188 bool DownloadsFunctionInterface::RunImplImpl(
47 DownloadsFunctionInterface* pimpl) { 189 DownloadsFunctionInterface* pimpl) {
48 CHECK(pimpl); 190 CHECK(pimpl);
49 if (!pimpl->ParseArgs()) return false; 191 if (!pimpl->ParseArgs()) return false;
50 UMA_HISTOGRAM_ENUMERATION( 192 UMA_HISTOGRAM_ENUMERATION(
51 "Download.ApiFunctions", pimpl->function(), DOWNLOADS_FUNCTION_LAST); 193 "Download.ApiFunctions", pimpl->function(), DOWNLOADS_FUNCTION_LAST);
52 pimpl->RunInternal(); 194 pimpl->RunInternal();
53 return true; 195 return true;
54 } 196 }
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 VLOG(1) << __FUNCTION__; 359 VLOG(1) << __FUNCTION__;
218 if (dl_id >= 0) { 360 if (dl_id >= 0) {
219 result_.reset(base::Value::CreateIntegerValue(dl_id)); 361 result_.reset(base::Value::CreateIntegerValue(dl_id));
220 } else { 362 } else {
221 error_ = net::ErrorToString(error); 363 error_ = net::ErrorToString(error);
222 } 364 }
223 SendResponse(error_.empty()); 365 SendResponse(error_.empty());
224 } 366 }
225 367
226 DownloadsSearchFunction::DownloadsSearchFunction() 368 DownloadsSearchFunction::DownloadsSearchFunction()
227 : SyncDownloadsFunction(DOWNLOADS_FUNCTION_SEARCH) { 369 : SyncDownloadsFunction(DOWNLOADS_FUNCTION_SEARCH),
370 get_id_(0),
371 has_get_id_(false) {
228 } 372 }
229 373
230 DownloadsSearchFunction::~DownloadsSearchFunction() {} 374 DownloadsSearchFunction::~DownloadsSearchFunction() {}
231 375
376 template <typename ValueType>
377 bool DownloadsSearchFunction::Parse(base::DictionaryValue* json,
378 const char* name) {
379 if (json->HasKey(name)) {
380 ValueType value;
381 EXTENSION_FUNCTION_VALIDATE(GetJsonValue(json, name, &value));
382 if (!query_.Set(name, value)) {
383 error_ = constants::kGenericError; // TODO(benjhayden)
384 return false;
385 }
386 }
387 return true;
388 }
389
232 bool DownloadsSearchFunction::ParseArgs() { 390 bool DownloadsSearchFunction::ParseArgs() {
233 base::DictionaryValue* query_json = NULL; 391 base::DictionaryValue* query_json = NULL;
234 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &query_json)); 392 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &query_json));
235 error_ = constants::kNotImplemented; 393 if (query_json->HasKey(constants::kDangerKey)) {
236 return false; 394 std::string danger;
395 EXTENSION_FUNCTION_VALIDATE(query_json->GetString(
396 constants::kDangerKey, &danger));
397 if (!query_.Set(constants::kDangerKey,
398 constants::DangerEnumFromString(danger))) {
399 error_ = constants::kGenericError; // TODO
400 return false;
401 }
402 }
403 if (query_json->HasKey(constants::kStateKey)) {
404 std::string state;
405 EXTENSION_FUNCTION_VALIDATE(query_json->GetString(
406 constants::kStateKey, &state));
407 if (!query_.Set(constants::kStateKey,
408 constants::StateEnumFromString(state))) {
409 error_ = constants::kGenericError; // TODO
410 return false;
411 }
412 }
413 if (query_json->HasKey(constants::kIdKey)) {
414 EXTENSION_FUNCTION_VALIDATE(query_json->GetInteger(
415 constants::kIdKey, &get_id_));
416 has_get_id_ = true;
417 }
418 if (query_json->HasKey(constants::kOrderByKey)) {
419 std::string order_by;
420 EXTENSION_FUNCTION_VALIDATE(query_json->GetString(
421 constants::kOrderByKey, &order_by));
422 if (!query_.OrderBy(order_by)) {
423 error_ = constants::kGenericError; // TODO
424 return false;
425 }
426 }
427 if (query_json->HasKey(constants::kLimitKey)) {
428 int limit = 0;
429 EXTENSION_FUNCTION_VALIDATE(query_json->GetInteger(
430 constants::kLimitKey, &limit));
431 query_.Limit(limit);
432 }
433 return Parse<int>(query_json, constants::kStartTimeKey) &&
434 Parse<int>(query_json, constants::kEndTimeKey) &&
435 Parse<int>(query_json, constants::kStartedBeforeKey) &&
436 Parse<int>(query_json, constants::kStartedAfterKey) &&
437 Parse<int>(query_json, constants::kEndedBeforeKey) &&
438 Parse<int>(query_json, constants::kEndedAfterKey) &&
439 Parse<int>(query_json, constants::kBytesReceivedKey) &&
440 Parse<int>(query_json, constants::kTotalBytesKey) &&
441 Parse<int>(query_json, constants::kTotalBytesGreaterKey) &&
442 Parse<int>(query_json, constants::kTotalBytesLessKey) &&
443 Parse<int>(query_json, constants::kFileSizeKey) &&
444 Parse<int>(query_json, constants::kFileSizeGreaterKey) &&
445 Parse<int>(query_json, constants::kFileSizeLessKey) &&
446 Parse<int>(query_json, constants::kErrorKey) &&
447 Parse<bool>(query_json, constants::kDangerAcceptedKey) &&
448 Parse<bool>(query_json, constants::kPausedKey) &&
449 Parse<string16>(query_json, constants::kFilenameKey) &&
450 Parse<std::string>(query_json, constants::kMimeKey) &&
451 Parse<std::string>(query_json, constants::kQueryKey) &&
452 Parse<std::string>(query_json, constants::kFilenameRegexKey) &&
453 Parse<std::string>(query_json, constants::kUrlRegexKey) &&
454 Parse<std::string>(query_json, constants::kUrlKey);
237 } 455 }
238 456
239 void DownloadsSearchFunction::RunInternal() { 457 void DownloadsSearchFunction::RunInternal() {
240 NOTIMPLEMENTED(); 458 DownloadManager::DownloadVector cpp_results;
459 if (has_get_id_) {
460 DownloadItem* item = profile()->GetDownloadManager()->GetDownloadItem(
461 get_id_);
462 if (item && query_.Matches(*item))
463 cpp_results.push_back(item);
464 } else {
465 profile()->GetDownloadManager()->Search(query_, &cpp_results);
466 }
467 base::ListValue* json_results = new base::ListValue();
468 for (DownloadManager::DownloadVector::const_iterator it = cpp_results.begin();
469 it != cpp_results.end(); ++it) {
470 json_results->Append(DownloadItemToJSON(*it));
471 }
472 result_.reset(json_results);
241 } 473 }
242 474
243 DownloadsPauseFunction::DownloadsPauseFunction() 475 DownloadsPauseFunction::DownloadsPauseFunction()
244 : SyncDownloadsFunction(DOWNLOADS_FUNCTION_PAUSE) { 476 : SyncDownloadsFunction(DOWNLOADS_FUNCTION_PAUSE) {
245 } 477 }
246 478
247 DownloadsPauseFunction::~DownloadsPauseFunction() {} 479 DownloadsPauseFunction::~DownloadsPauseFunction() {}
248 480
249 bool DownloadsPauseFunction::ParseArgs() { 481 bool DownloadsPauseFunction::ParseArgs() {
250 int dl_id = 0; 482 int dl_id = 0;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id)); 610 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &dl_id));
379 VLOG(1) << __FUNCTION__ << " " << dl_id; 611 VLOG(1) << __FUNCTION__ << " " << dl_id;
380 error_ = constants::kNotImplemented; 612 error_ = constants::kNotImplemented;
381 return false; 613 return false;
382 } 614 }
383 615
384 void DownloadsDragFunction::RunInternal() { 616 void DownloadsDragFunction::RunInternal() {
385 NOTIMPLEMENTED(); 617 NOTIMPLEMENTED();
386 } 618 }
387 619
388 namespace {
389 base::DictionaryValue* DownloadItemToJSON(DownloadItem* item) {
390 base::DictionaryValue* json = new base::DictionaryValue();
391 json->SetInteger(constants::kIdKey, item->id());
392 json->SetString(constants::kUrlKey, item->original_url().spec());
393 json->SetString(constants::kFilenameKey,
394 item->full_path().LossyDisplayName());
395 json->SetString(constants::kDangerKey,
396 constants::DangerString(item->GetDangerType()));
397 json->SetBoolean(constants::kDangerAcceptedKey,
398 item->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED);
399 json->SetString(constants::kStateKey,
400 constants::StateString(item->state()));
401 json->SetBoolean(constants::kPausedKey, item->is_paused());
402 json->SetString(constants::kMimeKey, item->mime_type());
403 json->SetInteger(constants::kStartTimeKey,
404 (item->start_time() - base::Time::UnixEpoch()).InMilliseconds());
405 json->SetInteger(constants::kBytesReceivedKey, item->received_bytes());
406 json->SetInteger(constants::kTotalBytesKey, item->total_bytes());
407 if (item->state() == DownloadItem::INTERRUPTED)
408 json->SetInteger(constants::kErrorKey,
409 static_cast<int>(item->last_reason()));
410 // TODO(benjhayden): Implement endTime and fileSize.
411 // json->SetInteger(constants::kEndTimeKey, -1);
412 json->SetInteger(constants::kFileSizeKey, item->total_bytes());
413 return json;
414 }
415 } // anonymous namespace
416
417 ExtensionDownloadsEventRouter::ExtensionDownloadsEventRouter( 620 ExtensionDownloadsEventRouter::ExtensionDownloadsEventRouter(
418 Profile* profile) 621 Profile* profile)
419 : profile_(profile), 622 : profile_(profile),
420 manager_( 623 manager_(
421 profile ? 624 profile ?
422 DownloadServiceFactory::GetForProfile(profile)->GetDownloadManager() : 625 DownloadServiceFactory::GetForProfile(profile)->GetDownloadManager() :
423 NULL) { 626 NULL) {
424 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 627 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
425 DCHECK(profile_); 628 DCHECK(profile_);
426 DCHECK(manager_); 629 DCHECK(manager_);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 ListValue args; 689 ListValue args;
487 args.Append(arg); 690 args.Append(arg);
488 std::string json_args; 691 std::string json_args;
489 base::JSONWriter::Write(&args, false, &json_args); 692 base::JSONWriter::Write(&args, false, &json_args);
490 profile_->GetExtensionEventRouter()->DispatchEventToRenderers( 693 profile_->GetExtensionEventRouter()->DispatchEventToRenderers(
491 event_name, 694 event_name,
492 json_args, 695 json_args,
493 profile_, 696 profile_,
494 GURL()); 697 GURL());
495 } 698 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698