Chromium Code Reviews| 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/ui/webui/downloads_dom_handler.h" | 5 #include "chrome/browser/ui/webui/downloads_dom_handler.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <functional> | 8 #include <functional> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
| 13 #include "base/i18n/rtl.h" | 13 #include "base/i18n/rtl.h" |
| 14 #include "base/i18n/time_formatting.h" | 14 #include "base/i18n/time_formatting.h" |
| 15 #include "base/memory/singleton.h" | 15 #include "base/memory/singleton.h" |
| 16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
| 17 #include "base/string_piece.h" | 17 #include "base/string_piece.h" |
| 18 #include "base/threading/thread.h" | 18 #include "base/threading/thread.h" |
| 19 #include "base/utf_string_conversions.h" | 19 #include "base/utf_string_conversions.h" |
| 20 #include "base/value_conversions.h" | 20 #include "base/value_conversions.h" |
| 21 #include "base/values.h" | 21 #include "base/values.h" |
| 22 #include "chrome/browser/browser_process.h" | 22 #include "chrome/browser/browser_process.h" |
| 23 #include "chrome/browser/download/download_crx_util.h" | 23 #include "chrome/browser/download/download_crx_util.h" |
| 24 #include "chrome/browser/download/download_danger_prompt.h" | 24 #include "chrome/browser/download/download_danger_prompt.h" |
| 25 #include "chrome/browser/download/download_history.h" | 25 #include "chrome/browser/download/download_history.h" |
| 26 #include "chrome/browser/download/download_item_model.h" | 26 #include "chrome/browser/download/download_item_model.h" |
| 27 #include "chrome/browser/download/download_prefs.h" | 27 #include "chrome/browser/download/download_prefs.h" |
| 28 #include "chrome/browser/download/download_query.h" | |
| 28 #include "chrome/browser/download/download_service.h" | 29 #include "chrome/browser/download/download_service.h" |
| 29 #include "chrome/browser/download/download_service_factory.h" | 30 #include "chrome/browser/download/download_service_factory.h" |
| 30 #include "chrome/browser/download/download_util.h" | 31 #include "chrome/browser/download/download_util.h" |
| 31 #include "chrome/browser/platform_util.h" | 32 #include "chrome/browser/platform_util.h" |
| 32 #include "chrome/browser/profiles/profile.h" | 33 #include "chrome/browser/profiles/profile.h" |
| 33 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 34 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
| 34 #include "chrome/browser/ui/webui/chrome_url_data_manager.h" | 35 #include "chrome/browser/ui/webui/chrome_url_data_manager.h" |
| 35 #include "chrome/browser/ui/webui/fileicon_source.h" | 36 #include "chrome/browser/ui/webui/fileicon_source.h" |
| 36 #include "chrome/common/time_format.h" | 37 #include "chrome/common/time_format.h" |
| 37 #include "chrome/common/url_constants.h" | 38 #include "chrome/common/url_constants.h" |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 54 using content::BrowserContext; | 55 using content::BrowserContext; |
| 55 using content::BrowserThread; | 56 using content::BrowserThread; |
| 56 using content::UserMetricsAction; | 57 using content::UserMetricsAction; |
| 57 | 58 |
| 58 namespace { | 59 namespace { |
| 59 | 60 |
| 60 // Maximum number of downloads to show. TODO(glen): Remove this and instead | 61 // Maximum number of downloads to show. TODO(glen): Remove this and instead |
| 61 // stuff the downloads down the pipe slowly. | 62 // stuff the downloads down the pipe slowly. |
| 62 static const size_t kMaxDownloads = 150; | 63 static const size_t kMaxDownloads = 150; |
| 63 | 64 |
| 64 // Sorts DownloadItems into descending order by their start time. | |
| 65 class DownloadItemSorter : public std::binary_function<content::DownloadItem*, | |
| 66 content::DownloadItem*, | |
| 67 bool> { | |
| 68 public: | |
| 69 bool operator()(const content::DownloadItem* lhs, | |
| 70 const content::DownloadItem* rhs) { | |
| 71 return lhs->GetStartTime() > rhs->GetStartTime(); | |
| 72 } | |
| 73 }; | |
| 74 | |
| 75 enum DownloadsDOMEvent { | 65 enum DownloadsDOMEvent { |
| 76 DOWNLOADS_DOM_EVENT_GET_DOWNLOADS = 0, | 66 DOWNLOADS_DOM_EVENT_GET_DOWNLOADS = 0, |
| 77 DOWNLOADS_DOM_EVENT_OPEN_FILE = 1, | 67 DOWNLOADS_DOM_EVENT_OPEN_FILE = 1, |
| 78 DOWNLOADS_DOM_EVENT_DRAG = 2, | 68 DOWNLOADS_DOM_EVENT_DRAG = 2, |
| 79 DOWNLOADS_DOM_EVENT_SAVE_DANGEROUS = 3, | 69 DOWNLOADS_DOM_EVENT_SAVE_DANGEROUS = 3, |
| 80 DOWNLOADS_DOM_EVENT_DISCARD_DANGEROUS = 4, | 70 DOWNLOADS_DOM_EVENT_DISCARD_DANGEROUS = 4, |
| 81 DOWNLOADS_DOM_EVENT_SHOW = 5, | 71 DOWNLOADS_DOM_EVENT_SHOW = 5, |
| 82 DOWNLOADS_DOM_EVENT_PAUSE = 6, | 72 DOWNLOADS_DOM_EVENT_PAUSE = 6, |
| 83 DOWNLOADS_DOM_EVENT_REMOVE = 7, | 73 DOWNLOADS_DOM_EVENT_REMOVE = 7, |
| 84 DOWNLOADS_DOM_EVENT_CANCEL = 8, | 74 DOWNLOADS_DOM_EVENT_CANCEL = 8, |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 // Observe the DownloadManagers. | 228 // Observe the DownloadManagers. |
| 239 download_manager_->AddObserver(this); | 229 download_manager_->AddObserver(this); |
| 240 if (profile->IsOffTheRecord()) { | 230 if (profile->IsOffTheRecord()) { |
| 241 original_profile_download_manager_ = | 231 original_profile_download_manager_ = |
| 242 BrowserContext::GetDownloadManager(profile->GetOriginalProfile()); | 232 BrowserContext::GetDownloadManager(profile->GetOriginalProfile()); |
| 243 original_profile_download_manager_->AddObserver(this); | 233 original_profile_download_manager_->AddObserver(this); |
| 244 } | 234 } |
| 245 | 235 |
| 246 // Observe all the DownloadItems. | 236 // Observe all the DownloadItems. |
| 247 content::DownloadManager::DownloadVector downloads; | 237 content::DownloadManager::DownloadVector downloads; |
| 248 SearchDownloads(&downloads); | 238 GetAllDownloads(&downloads); |
| 249 for (content::DownloadManager::DownloadVector::const_iterator | 239 for (content::DownloadManager::DownloadVector::const_iterator |
| 250 iter = downloads.begin(); | 240 iter = downloads.begin(); |
| 251 iter != downloads.end(); ++iter) { | 241 iter != downloads.end(); ++iter) { |
| 252 (*iter)->AddObserver(this); | 242 (*iter)->AddObserver(this); |
| 253 observing_items_.insert(*iter); | 243 observing_items_.insert(*iter); |
| 254 } | 244 } |
| 255 } | 245 } |
| 256 | 246 |
| 257 DownloadsDOMHandler::~DownloadsDOMHandler() { | 247 DownloadsDOMHandler::~DownloadsDOMHandler() { |
| 258 for (DownloadSet::const_iterator it = observing_items_.begin(); | 248 for (DownloadSet::const_iterator it = observing_items_.begin(); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 320 // IsDownloadDisplayable(). | 310 // IsDownloadDisplayable(). |
| 321 download_item->AddObserver(this); | 311 download_item->AddObserver(this); |
| 322 observing_items_.insert(download_item); | 312 observing_items_.insert(download_item); |
| 323 if (IsDownloadDisplayable(*download_item)) | 313 if (IsDownloadDisplayable(*download_item)) |
| 324 ScheduleSendCurrentDownloads(); | 314 ScheduleSendCurrentDownloads(); |
| 325 } | 315 } |
| 326 | 316 |
| 327 void DownloadsDOMHandler::OnDownloadUpdated( | 317 void DownloadsDOMHandler::OnDownloadUpdated( |
| 328 content::DownloadItem* download_item) { | 318 content::DownloadItem* download_item) { |
| 329 if (IsDownloadDisplayable(*download_item)) { | 319 if (IsDownloadDisplayable(*download_item)) { |
| 320 if (!search_text_.empty()) { | |
| 321 // Don't CallDownloadUpdated() if download_item doesn't match | |
| 322 // search_text_. TODO(benjhayden): Consider splitting MatchesQuery() out | |
|
James Hawkins
2012/09/13 16:08:29
nit: Put the TODO on its own line.
benjhayden
2012/09/13 16:24:22
Done.
| |
| 323 // into a util function. | |
| 324 content::DownloadManager::DownloadVector all_items, filtered_items; | |
| 325 all_items.push_back(download_item); | |
| 326 DownloadQuery query; | |
| 327 scoped_ptr<base::Value> query_text(base::Value::CreateStringValue( | |
| 328 search_text_)); | |
| 329 query.AddFilter(DownloadQuery::FILTER_QUERY, *query_text.get()); | |
| 330 query.Search(all_items.begin(), all_items.end(), &filtered_items); | |
| 331 if (filtered_items.empty()) | |
| 332 return; | |
| 333 } | |
| 330 base::ListValue results_value; | 334 base::ListValue results_value; |
| 331 results_value.Append(CreateDownloadItemValue(download_item, IsItemIncognito( | 335 results_value.Append(CreateDownloadItemValue(download_item, IsItemIncognito( |
| 332 download_item->GetId(), | 336 download_item->GetId(), |
| 333 download_manager_, | 337 download_manager_, |
| 334 original_profile_download_manager_))); | 338 original_profile_download_manager_))); |
| 335 CallDownloadUpdated(results_value); | 339 CallDownloadUpdated(results_value); |
| 336 } | 340 } |
| 337 } | 341 } |
| 338 | 342 |
| 339 void DownloadsDOMHandler::OnDownloadDestroyed( | 343 void DownloadsDOMHandler::OnDownloadDestroyed( |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 408 void DownloadsDOMHandler::HandlePause(const base::ListValue* args) { | 412 void DownloadsDOMHandler::HandlePause(const base::ListValue* args) { |
| 409 CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_PAUSE); | 413 CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_PAUSE); |
| 410 content::DownloadItem* file = GetDownloadByValue(args); | 414 content::DownloadItem* file = GetDownloadByValue(args); |
| 411 if (file) | 415 if (file) |
| 412 file->TogglePause(); | 416 file->TogglePause(); |
| 413 } | 417 } |
| 414 | 418 |
| 415 void DownloadsDOMHandler::HandleRemove(const base::ListValue* args) { | 419 void DownloadsDOMHandler::HandleRemove(const base::ListValue* args) { |
| 416 CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_REMOVE); | 420 CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_REMOVE); |
| 417 content::DownloadItem* file = GetDownloadByValue(args); | 421 content::DownloadItem* file = GetDownloadByValue(args); |
| 418 if (file) { | 422 if (file) |
| 419 DCHECK(file->IsPersisted()); | |
| 420 file->Remove(); | 423 file->Remove(); |
| 421 } | |
| 422 } | 424 } |
| 423 | 425 |
| 424 void DownloadsDOMHandler::HandleCancel(const base::ListValue* args) { | 426 void DownloadsDOMHandler::HandleCancel(const base::ListValue* args) { |
| 425 CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_CANCEL); | 427 CountDownloadsDOMEvents(DOWNLOADS_DOM_EVENT_CANCEL); |
| 426 content::DownloadItem* file = GetDownloadByValue(args); | 428 content::DownloadItem* file = GetDownloadByValue(args); |
| 427 if (file) | 429 if (file) |
| 428 file->Cancel(true); | 430 file->Cancel(true); |
| 429 } | 431 } |
| 430 | 432 |
| 431 void DownloadsDOMHandler::HandleClearAll(const base::ListValue* args) { | 433 void DownloadsDOMHandler::HandleClearAll(const base::ListValue* args) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 455 return; | 457 return; |
| 456 update_scheduled_ = true; | 458 update_scheduled_ = true; |
| 457 BrowserThread::PostTask( | 459 BrowserThread::PostTask( |
| 458 BrowserThread::UI, FROM_HERE, | 460 BrowserThread::UI, FROM_HERE, |
| 459 base::Bind(&DownloadsDOMHandler::SendCurrentDownloads, | 461 base::Bind(&DownloadsDOMHandler::SendCurrentDownloads, |
| 460 weak_ptr_factory_.GetWeakPtr())); | 462 weak_ptr_factory_.GetWeakPtr())); |
| 461 } | 463 } |
| 462 | 464 |
| 463 void DownloadsDOMHandler::SendCurrentDownloads() { | 465 void DownloadsDOMHandler::SendCurrentDownloads() { |
| 464 update_scheduled_ = false; | 466 update_scheduled_ = false; |
| 465 content::DownloadManager::DownloadVector downloads; | 467 content::DownloadManager::DownloadVector all_items, filtered_items; |
| 466 SearchDownloads(&downloads); | 468 GetAllDownloads(&all_items); |
| 467 sort(downloads.begin(), downloads.end(), DownloadItemSorter()); | 469 DownloadQuery query; |
| 470 if (!search_text_.empty()) { | |
| 471 scoped_ptr<base::Value> query_text(base::Value::CreateStringValue( | |
| 472 search_text_)); | |
| 473 query.AddFilter(DownloadQuery::FILTER_QUERY, *query_text.get()); | |
| 474 } | |
| 475 query.AddFilter(base::Bind(&IsDownloadDisplayable)); | |
| 476 query.AddSorter(DownloadQuery::SORT_START_TIME, DownloadQuery::DESCENDING); | |
| 477 query.Limit(kMaxDownloads); | |
| 478 query.Search(all_items.begin(), all_items.end(), &filtered_items); | |
| 468 base::ListValue results_value; | 479 base::ListValue results_value; |
| 469 for (content::DownloadManager::DownloadVector::const_iterator | 480 for (content::DownloadManager::DownloadVector::const_iterator |
| 470 iter = downloads.begin(); | 481 iter = filtered_items.begin(); iter != filtered_items.end(); ++iter) { |
| 471 iter != downloads.end(); ++iter) { | 482 results_value.Append(CreateDownloadItemValue(*iter, IsItemIncognito( |
| 472 if (IsDownloadDisplayable(**iter)) | 483 (*iter)->GetId(), download_manager_, |
| 473 results_value.Append(CreateDownloadItemValue(*iter, IsItemIncognito( | 484 original_profile_download_manager_))); |
| 474 (*iter)->GetId(), download_manager_, | |
| 475 original_profile_download_manager_))); | |
| 476 if (results_value.GetSize() == kMaxDownloads) | |
| 477 break; | |
| 478 } | 485 } |
| 479 CallDownloadsList(results_value); | 486 CallDownloadsList(results_value); |
| 480 } | 487 } |
| 481 | 488 |
| 482 void DownloadsDOMHandler::SearchDownloads( | 489 void DownloadsDOMHandler::GetAllDownloads( |
| 483 content::DownloadManager::DownloadVector* downloads) { | 490 content::DownloadManager::DownloadVector* downloads) { |
| 484 download_manager_->SearchDownloads(search_text_, downloads); | 491 download_manager_->GetAllDownloads(downloads); |
| 485 if (original_profile_download_manager_) | 492 if (original_profile_download_manager_) |
| 486 original_profile_download_manager_->SearchDownloads( | 493 original_profile_download_manager_->GetAllDownloads(downloads); |
| 487 search_text_, downloads); | |
| 488 } | 494 } |
| 489 | 495 |
| 490 void DownloadsDOMHandler::ShowDangerPrompt( | 496 void DownloadsDOMHandler::ShowDangerPrompt( |
| 491 content::DownloadItem* dangerous_item) { | 497 content::DownloadItem* dangerous_item) { |
| 492 DownloadDangerPrompt* danger_prompt = DownloadDangerPrompt::Create( | 498 DownloadDangerPrompt* danger_prompt = DownloadDangerPrompt::Create( |
| 493 dangerous_item, | 499 dangerous_item, |
| 494 TabContents::FromWebContents(GetWebUIWebContents()), | 500 TabContents::FromWebContents(GetWebUIWebContents()), |
| 495 base::Bind(&DownloadsDOMHandler::DangerPromptAccepted, | 501 base::Bind(&DownloadsDOMHandler::DangerPromptAccepted, |
| 496 weak_ptr_factory_.GetWeakPtr(), dangerous_item->GetId()), | 502 weak_ptr_factory_.GetWeakPtr(), dangerous_item->GetId()), |
| 497 base::Closure()); | 503 base::Closure()); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 524 } | 530 } |
| 525 | 531 |
| 526 void DownloadsDOMHandler::CallDownloadsList(const base::ListValue& downloads) { | 532 void DownloadsDOMHandler::CallDownloadsList(const base::ListValue& downloads) { |
| 527 web_ui()->CallJavascriptFunction("downloadsList", downloads); | 533 web_ui()->CallJavascriptFunction("downloadsList", downloads); |
| 528 } | 534 } |
| 529 | 535 |
| 530 void DownloadsDOMHandler::CallDownloadUpdated( | 536 void DownloadsDOMHandler::CallDownloadUpdated( |
| 531 const base::ListValue& download_item) { | 537 const base::ListValue& download_item) { |
| 532 web_ui()->CallJavascriptFunction("downloadUpdated", download_item); | 538 web_ui()->CallJavascriptFunction("downloadUpdated", download_item); |
| 533 } | 539 } |
| OLD | NEW |