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 <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 |
| 10 #include <algorithm> |
9 #include <memory> | 11 #include <memory> |
10 #include <set> | 12 #include <set> |
11 #include <string> | 13 #include <string> |
12 #include <utility> | 14 #include <utility> |
13 | 15 |
14 #include "base/bind.h" | 16 #include "base/bind.h" |
15 #include "base/bind_helpers.h" | 17 #include "base/bind_helpers.h" |
16 #include "base/callback.h" | 18 #include "base/callback.h" |
17 #include "base/files/file_path.h" | 19 #include "base/files/file_path.h" |
18 #include "base/files/file_util.h" | 20 #include "base/files/file_util.h" |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 const char kDangerUrl[] = "url"; | 153 const char kDangerUrl[] = "url"; |
152 const char kEndTimeKey[] = "endTime"; | 154 const char kEndTimeKey[] = "endTime"; |
153 const char kEndedAfterKey[] = "endedAfter"; | 155 const char kEndedAfterKey[] = "endedAfter"; |
154 const char kEndedBeforeKey[] = "endedBefore"; | 156 const char kEndedBeforeKey[] = "endedBefore"; |
155 const char kErrorKey[] = "error"; | 157 const char kErrorKey[] = "error"; |
156 const char kEstimatedEndTimeKey[] = "estimatedEndTime"; | 158 const char kEstimatedEndTimeKey[] = "estimatedEndTime"; |
157 const char kExistsKey[] = "exists"; | 159 const char kExistsKey[] = "exists"; |
158 const char kFileSizeKey[] = "fileSize"; | 160 const char kFileSizeKey[] = "fileSize"; |
159 const char kFilenameKey[] = "filename"; | 161 const char kFilenameKey[] = "filename"; |
160 const char kFilenameRegexKey[] = "filenameRegex"; | 162 const char kFilenameRegexKey[] = "filenameRegex"; |
| 163 const char kFinalUrlKey[] = "finalUrl"; |
| 164 const char kFinalUrlRegexKey[] = "finalUrlRegex"; |
161 const char kIdKey[] = "id"; | 165 const char kIdKey[] = "id"; |
162 const char kIncognitoKey[] = "incognito"; | 166 const char kIncognitoKey[] = "incognito"; |
163 const char kMimeKey[] = "mime"; | 167 const char kMimeKey[] = "mime"; |
164 const char kPausedKey[] = "paused"; | 168 const char kPausedKey[] = "paused"; |
165 const char kQueryKey[] = "query"; | 169 const char kQueryKey[] = "query"; |
166 const char kReferrerUrlKey[] = "referrer"; | 170 const char kReferrerUrlKey[] = "referrer"; |
167 const char kStartTimeKey[] = "startTime"; | 171 const char kStartTimeKey[] = "startTime"; |
168 const char kStartedAfterKey[] = "startedAfter"; | 172 const char kStartedAfterKey[] = "startedAfter"; |
169 const char kStartedBeforeKey[] = "startedBefore"; | 173 const char kStartedBeforeKey[] = "startedBefore"; |
170 const char kStateComplete[] = "complete"; | 174 const char kStateComplete[] = "complete"; |
171 const char kStateInProgress[] = "in_progress"; | 175 const char kStateInProgress[] = "in_progress"; |
172 const char kStateInterrupted[] = "interrupted"; | 176 const char kStateInterrupted[] = "interrupted"; |
173 const char kStateKey[] = "state"; | 177 const char kStateKey[] = "state"; |
174 const char kTotalBytesGreaterKey[] = "totalBytesGreater"; | 178 const char kTotalBytesGreaterKey[] = "totalBytesGreater"; |
175 const char kTotalBytesKey[] = "totalBytes"; | 179 const char kTotalBytesKey[] = "totalBytes"; |
176 const char kTotalBytesLessKey[] = "totalBytesLess"; | 180 const char kTotalBytesLessKey[] = "totalBytesLess"; |
177 const char kUrlKey[] = "url"; | 181 const char kUrlKey[] = "url"; |
178 const char kUrlRegexKey[] = "urlRegex"; | 182 const char kUrlRegexKey[] = "urlRegex"; |
179 const char kFinalUrlKey[] = "finalUrl"; | 183 |
180 const char kFinalUrlRegexKey[] = "finalUrlRegex"; | 184 // This list must be in order as determined by strcmp. The test |
| 185 // DownloadsApiInternalUnitTest.FilterTypeSorted will verify this. |
| 186 constexpr DownloadQueryFilterTypePair kFilterTypes[] = { |
| 187 {kBytesReceivedKey, DownloadQuery::FILTER_BYTES_RECEIVED}, |
| 188 {kEndTimeKey, DownloadQuery::FILTER_END_TIME}, |
| 189 {kEndedAfterKey, DownloadQuery::FILTER_ENDED_AFTER}, |
| 190 {kEndedBeforeKey, DownloadQuery::FILTER_ENDED_BEFORE}, |
| 191 {kExistsKey, DownloadQuery::FILTER_EXISTS}, |
| 192 {kFilenameKey, DownloadQuery::FILTER_FILENAME}, |
| 193 {kFilenameRegexKey, DownloadQuery::FILTER_FILENAME_REGEX}, |
| 194 {kFinalUrlKey, DownloadQuery::FILTER_URL}, |
| 195 {kFinalUrlRegexKey, DownloadQuery::FILTER_URL_REGEX}, |
| 196 {kMimeKey, DownloadQuery::FILTER_MIME}, |
| 197 {kPausedKey, DownloadQuery::FILTER_PAUSED}, |
| 198 {kQueryKey, DownloadQuery::FILTER_QUERY}, |
| 199 {kStartTimeKey, DownloadQuery::FILTER_START_TIME}, |
| 200 {kStartedAfterKey, DownloadQuery::FILTER_STARTED_AFTER}, |
| 201 {kStartedBeforeKey, DownloadQuery::FILTER_STARTED_BEFORE}, |
| 202 {kTotalBytesKey, DownloadQuery::FILTER_TOTAL_BYTES}, |
| 203 {kTotalBytesGreaterKey, DownloadQuery::FILTER_TOTAL_BYTES_GREATER}, |
| 204 {kTotalBytesLessKey, DownloadQuery::FILTER_TOTAL_BYTES_LESS}, |
| 205 {kUrlKey, DownloadQuery::FILTER_ORIGINAL_URL}, |
| 206 {kUrlRegexKey, DownloadQuery::FILTER_ORIGINAL_URL_REGEX}, |
| 207 }; |
| 208 |
| 209 // This list must be in order as determined by strcmp. The test |
| 210 // DownloadsApiInternalUnitTest.SortTypeSorted will verify this. |
| 211 constexpr DownloadQuerySortTypePair kSortTypes[] = { |
| 212 {kBytesReceivedKey, DownloadQuery::SORT_BYTES_RECEIVED}, |
| 213 {kDangerKey, DownloadQuery::SORT_DANGER}, |
| 214 {kEndTimeKey, DownloadQuery::SORT_END_TIME}, |
| 215 {kExistsKey, DownloadQuery::SORT_EXISTS}, |
| 216 {kFilenameKey, DownloadQuery::SORT_FILENAME}, |
| 217 {kFinalUrlKey, DownloadQuery::SORT_URL}, |
| 218 {kMimeKey, DownloadQuery::SORT_MIME}, |
| 219 {kPausedKey, DownloadQuery::SORT_PAUSED}, |
| 220 {kStartTimeKey, DownloadQuery::SORT_START_TIME}, |
| 221 {kStateKey, DownloadQuery::SORT_STATE}, |
| 222 {kTotalBytesKey, DownloadQuery::SORT_TOTAL_BYTES}, |
| 223 {kUrlKey, DownloadQuery::SORT_ORIGINAL_URL}, |
| 224 }; |
181 | 225 |
182 // Note: Any change to the danger type strings, should be accompanied by a | 226 // Note: Any change to the danger type strings, should be accompanied by a |
183 // corresponding change to downloads.json. | 227 // corresponding change to downloads.json. |
184 const char* const kDangerStrings[] = { | 228 const char* const kDangerStrings[] = { |
185 kDangerSafe, | 229 kDangerSafe, |
186 kDangerFile, | 230 kDangerFile, |
187 kDangerUrl, | 231 kDangerUrl, |
188 kDangerContent, | 232 kDangerContent, |
189 kDangerSafe, | 233 kDangerSafe, |
190 kDangerUncommon, | 234 kDangerUncommon, |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 IconLoader::IconSize IconLoaderSizeFromPixelSize(int pixel_size) { | 399 IconLoader::IconSize IconLoaderSizeFromPixelSize(int pixel_size) { |
356 switch (pixel_size) { | 400 switch (pixel_size) { |
357 case 16: return IconLoader::SMALL; | 401 case 16: return IconLoader::SMALL; |
358 case 32: return IconLoader::NORMAL; | 402 case 32: return IconLoader::NORMAL; |
359 default: | 403 default: |
360 NOTREACHED(); | 404 NOTREACHED(); |
361 return IconLoader::NORMAL; | 405 return IconLoader::NORMAL; |
362 } | 406 } |
363 } | 407 } |
364 | 408 |
365 typedef base::hash_map<std::string, DownloadQuery::FilterType> FilterTypeMap; | |
366 | |
367 void InitFilterTypeMap(FilterTypeMap* filter_types_ptr) { | |
368 FilterTypeMap& filter_types = *filter_types_ptr; | |
369 filter_types[kBytesReceivedKey] = DownloadQuery::FILTER_BYTES_RECEIVED; | |
370 filter_types[kExistsKey] = DownloadQuery::FILTER_EXISTS; | |
371 filter_types[kFilenameKey] = DownloadQuery::FILTER_FILENAME; | |
372 filter_types[kFilenameRegexKey] = DownloadQuery::FILTER_FILENAME_REGEX; | |
373 filter_types[kMimeKey] = DownloadQuery::FILTER_MIME; | |
374 filter_types[kPausedKey] = DownloadQuery::FILTER_PAUSED; | |
375 filter_types[kQueryKey] = DownloadQuery::FILTER_QUERY; | |
376 filter_types[kEndedAfterKey] = DownloadQuery::FILTER_ENDED_AFTER; | |
377 filter_types[kEndedBeforeKey] = DownloadQuery::FILTER_ENDED_BEFORE; | |
378 filter_types[kEndTimeKey] = DownloadQuery::FILTER_END_TIME; | |
379 filter_types[kStartedAfterKey] = DownloadQuery::FILTER_STARTED_AFTER; | |
380 filter_types[kStartedBeforeKey] = DownloadQuery::FILTER_STARTED_BEFORE; | |
381 filter_types[kStartTimeKey] = DownloadQuery::FILTER_START_TIME; | |
382 filter_types[kTotalBytesKey] = DownloadQuery::FILTER_TOTAL_BYTES; | |
383 filter_types[kTotalBytesGreaterKey] = | |
384 DownloadQuery::FILTER_TOTAL_BYTES_GREATER; | |
385 filter_types[kTotalBytesLessKey] = DownloadQuery::FILTER_TOTAL_BYTES_LESS; | |
386 filter_types[kUrlKey] = DownloadQuery::FILTER_ORIGINAL_URL; | |
387 filter_types[kUrlRegexKey] = DownloadQuery::FILTER_ORIGINAL_URL_REGEX; | |
388 filter_types[kFinalUrlKey] = DownloadQuery::FILTER_URL; | |
389 filter_types[kFinalUrlRegexKey] = DownloadQuery::FILTER_URL_REGEX; | |
390 } | |
391 | |
392 typedef base::hash_map<std::string, DownloadQuery::SortType> SortTypeMap; | |
393 | |
394 void InitSortTypeMap(SortTypeMap* sorter_types_ptr) { | |
395 SortTypeMap& sorter_types = *sorter_types_ptr; | |
396 sorter_types[kBytesReceivedKey] = DownloadQuery::SORT_BYTES_RECEIVED; | |
397 sorter_types[kDangerKey] = DownloadQuery::SORT_DANGER; | |
398 sorter_types[kEndTimeKey] = DownloadQuery::SORT_END_TIME; | |
399 sorter_types[kExistsKey] = DownloadQuery::SORT_EXISTS; | |
400 sorter_types[kFilenameKey] = DownloadQuery::SORT_FILENAME; | |
401 sorter_types[kMimeKey] = DownloadQuery::SORT_MIME; | |
402 sorter_types[kPausedKey] = DownloadQuery::SORT_PAUSED; | |
403 sorter_types[kStartTimeKey] = DownloadQuery::SORT_START_TIME; | |
404 sorter_types[kStateKey] = DownloadQuery::SORT_STATE; | |
405 sorter_types[kTotalBytesKey] = DownloadQuery::SORT_TOTAL_BYTES; | |
406 sorter_types[kUrlKey] = DownloadQuery::SORT_ORIGINAL_URL; | |
407 sorter_types[kFinalUrlKey] = DownloadQuery::SORT_URL; | |
408 } | |
409 | |
410 bool IsNotTemporaryDownloadFilter(const DownloadItem& download_item) { | 409 bool IsNotTemporaryDownloadFilter(const DownloadItem& download_item) { |
411 return !download_item.IsTemporary(); | 410 return !download_item.IsTemporary(); |
412 } | 411 } |
413 | 412 |
414 // Set |manager| to the on-record DownloadManager, and |incognito_manager| to | 413 // Set |manager| to the on-record DownloadManager, and |incognito_manager| to |
415 // the off-record DownloadManager if one exists and is requested via | 414 // the off-record DownloadManager if one exists and is requested via |
416 // |include_incognito|. This should work regardless of whether |profile| is | 415 // |include_incognito|. This should work regardless of whether |profile| is |
417 // original or incognito. | 416 // original or incognito. |
418 void GetManagers(content::BrowserContext* context, | 417 void GetManagers(content::BrowserContext* context, |
419 bool include_incognito, | 418 bool include_incognito, |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 void RecordApiFunctions(DownloadsFunctionName function) { | 468 void RecordApiFunctions(DownloadsFunctionName function) { |
470 UMA_HISTOGRAM_ENUMERATION("Download.ApiFunctions", | 469 UMA_HISTOGRAM_ENUMERATION("Download.ApiFunctions", |
471 function, | 470 function, |
472 DOWNLOADS_FUNCTION_LAST); | 471 DOWNLOADS_FUNCTION_LAST); |
473 } | 472 } |
474 | 473 |
475 void CompileDownloadQueryOrderBy( | 474 void CompileDownloadQueryOrderBy( |
476 const std::vector<std::string>& order_by_strs, | 475 const std::vector<std::string>& order_by_strs, |
477 std::string* error, | 476 std::string* error, |
478 DownloadQuery* query) { | 477 DownloadQuery* query) { |
479 // TODO(benjhayden): Consider switching from LazyInstance to explicit string | |
480 // comparisons. | |
481 static base::LazyInstance<SortTypeMap>::DestructorAtExit sorter_types = | |
482 LAZY_INSTANCE_INITIALIZER; | |
483 if (sorter_types.Get().empty()) | |
484 InitSortTypeMap(sorter_types.Pointer()); | |
485 | |
486 for (std::vector<std::string>::const_iterator iter = order_by_strs.begin(); | 478 for (std::vector<std::string>::const_iterator iter = order_by_strs.begin(); |
487 iter != order_by_strs.end(); ++iter) { | 479 iter != order_by_strs.end(); ++iter) { |
488 std::string term_str = *iter; | 480 std::string term_str = *iter; |
489 if (term_str.empty()) | 481 if (term_str.empty()) |
490 continue; | 482 continue; |
491 DownloadQuery::SortDirection direction = DownloadQuery::ASCENDING; | 483 DownloadQuery::SortDirection direction = DownloadQuery::ASCENDING; |
492 if (term_str[0] == '-') { | 484 if (term_str[0] == '-') { |
493 direction = DownloadQuery::DESCENDING; | 485 direction = DownloadQuery::DESCENDING; |
494 term_str = term_str.substr(1); | 486 term_str = term_str.substr(1); |
495 } | 487 } |
496 SortTypeMap::const_iterator sorter_type = | 488 const DownloadQuerySortTypePair* found_sort = |
497 sorter_types.Get().find(term_str); | 489 FindDownloadSortTypeByString(term_str.c_str()); |
498 if (sorter_type == sorter_types.Get().end()) { | 490 if (!found_sort) { |
499 *error = errors::kInvalidOrderBy; | 491 *error = errors::kInvalidOrderBy; |
500 return; | 492 return; |
501 } | 493 } |
502 query->AddSorter(sorter_type->second, direction); | 494 query->AddSorter(found_sort->second, direction); |
503 } | 495 } |
504 } | 496 } |
505 | 497 |
506 void RunDownloadQuery( | 498 void RunDownloadQuery( |
507 const downloads::DownloadQuery& query_in, | 499 const downloads::DownloadQuery& query_in, |
508 DownloadManager* manager, | 500 DownloadManager* manager, |
509 DownloadManager* incognito_manager, | 501 DownloadManager* incognito_manager, |
510 std::string* error, | 502 std::string* error, |
511 DownloadQuery::DownloadVector* results) { | 503 DownloadQuery::DownloadVector* results) { |
512 // TODO(benjhayden): Consider switching from LazyInstance to explicit string | |
513 // comparisons. | |
514 static base::LazyInstance<FilterTypeMap>::DestructorAtExit filter_types = | |
515 LAZY_INSTANCE_INITIALIZER; | |
516 if (filter_types.Get().empty()) | |
517 InitFilterTypeMap(filter_types.Pointer()); | |
518 | |
519 DownloadQuery query_out; | 504 DownloadQuery query_out; |
520 | 505 |
521 size_t limit = 1000; | 506 size_t limit = 1000; |
522 if (query_in.limit.get()) { | 507 if (query_in.limit.get()) { |
523 if (*query_in.limit < 0) { | 508 if (*query_in.limit < 0) { |
524 *error = errors::kInvalidQueryLimit; | 509 *error = errors::kInvalidQueryLimit; |
525 return; | 510 return; |
526 } | 511 } |
527 limit = *query_in.limit; | 512 limit = *query_in.limit; |
528 } | 513 } |
(...skipping 23 matching lines...) Expand all Loading... |
552 } | 537 } |
553 if (query_in.order_by.get()) { | 538 if (query_in.order_by.get()) { |
554 CompileDownloadQueryOrderBy(*query_in.order_by, error, &query_out); | 539 CompileDownloadQueryOrderBy(*query_in.order_by, error, &query_out); |
555 if (!error->empty()) | 540 if (!error->empty()) |
556 return; | 541 return; |
557 } | 542 } |
558 | 543 |
559 std::unique_ptr<base::DictionaryValue> query_in_value(query_in.ToValue()); | 544 std::unique_ptr<base::DictionaryValue> query_in_value(query_in.ToValue()); |
560 for (base::DictionaryValue::Iterator query_json_field(*query_in_value); | 545 for (base::DictionaryValue::Iterator query_json_field(*query_in_value); |
561 !query_json_field.IsAtEnd(); query_json_field.Advance()) { | 546 !query_json_field.IsAtEnd(); query_json_field.Advance()) { |
562 FilterTypeMap::const_iterator filter_type = | 547 const DownloadQueryFilterTypePair* found_filter = |
563 filter_types.Get().find(query_json_field.key()); | 548 FindDownloadFilterTypeByString(query_json_field.key().c_str()); |
564 if (filter_type != filter_types.Get().end()) { | 549 if (found_filter) { |
565 if (!query_out.AddFilter(filter_type->second, query_json_field.value())) { | 550 if (!query_out.AddFilter(found_filter->second, |
| 551 query_json_field.value())) { |
566 *error = errors::kInvalidFilter; | 552 *error = errors::kInvalidFilter; |
567 return; | 553 return; |
568 } | 554 } |
569 } | 555 } |
570 } | 556 } |
571 | 557 |
572 DownloadQuery::DownloadVector all_items; | 558 DownloadQuery::DownloadVector all_items; |
573 if (query_in.id.get()) { | 559 if (query_in.id.get()) { |
574 DownloadItem* download_item = manager->GetDownload(*query_in.id); | 560 DownloadItem* download_item = manager->GetDownload(*query_in.id); |
575 if (!download_item && incognito_manager) | 561 if (!download_item && incognito_manager) |
(...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1960 if (!manager) | 1946 if (!manager) |
1961 return; | 1947 return; |
1962 base::Time now(base::Time::Now()); | 1948 base::Time now(base::Time::Now()); |
1963 int delta = now.ToTimeT() - last_checked_removal_.ToTimeT(); | 1949 int delta = now.ToTimeT() - last_checked_removal_.ToTimeT(); |
1964 if (delta <= kFileExistenceRateLimitSeconds) | 1950 if (delta <= kFileExistenceRateLimitSeconds) |
1965 return; | 1951 return; |
1966 last_checked_removal_ = now; | 1952 last_checked_removal_ = now; |
1967 manager->CheckForHistoryFilesRemoval(); | 1953 manager->CheckForHistoryFilesRemoval(); |
1968 } | 1954 } |
1969 | 1955 |
| 1956 const DownloadQueryFilterTypePair* FindDownloadFilterTypeByString( |
| 1957 const char* key) { |
| 1958 struct FilterTypeKeyLess { |
| 1959 bool operator()(const DownloadQueryFilterTypePair& a, const char* b) const { |
| 1960 return strcmp(a.first, b) < 0; |
| 1961 } |
| 1962 }; |
| 1963 |
| 1964 const DownloadQueryFilterTypePair* found = |
| 1965 std::lower_bound(std::begin(kFilterTypes), std::end(kFilterTypes), key, |
| 1966 FilterTypeKeyLess()); |
| 1967 if (found == std::end(kFilterTypes) || strcmp(key, found->first) != 0) |
| 1968 return nullptr; |
| 1969 return found; |
| 1970 } |
| 1971 |
| 1972 const DownloadQuerySortTypePair* FindDownloadSortTypeByString(const char* key) { |
| 1973 struct SortTypeKeyLess { |
| 1974 bool operator()(const DownloadQuerySortTypePair& a, const char* b) const { |
| 1975 return strcmp(a.first, b) < 0; |
| 1976 } |
| 1977 }; |
| 1978 |
| 1979 const DownloadQuerySortTypePair* found = std::lower_bound( |
| 1980 std::begin(kSortTypes), std::end(kSortTypes), key, SortTypeKeyLess()); |
| 1981 if (found == std::end(kSortTypes) || strcmp(key, found->first) != 0) |
| 1982 return nullptr; |
| 1983 return found; |
| 1984 } |
| 1985 |
| 1986 const DownloadQueryFilterTypePair* DownloadQueryFilterTypeBeginForTest() { |
| 1987 return std::begin(kFilterTypes); |
| 1988 } |
| 1989 |
| 1990 const DownloadQueryFilterTypePair* DownloadQueryFilterTypeEndForTest() { |
| 1991 return std::end(kFilterTypes); |
| 1992 } |
| 1993 |
| 1994 const DownloadQuerySortTypePair* DownloadQuerySortTypeBeginForTest() { |
| 1995 return std::begin(kSortTypes); |
| 1996 } |
| 1997 |
| 1998 const DownloadQuerySortTypePair* DownloadQuerySortTypeEndForTest() { |
| 1999 return std::end(kSortTypes); |
| 2000 } |
| 2001 |
1970 } // namespace extensions | 2002 } // namespace extensions |
OLD | NEW |