blob: 39906066c58d82a1eb38e94dd0454d830a8fba39 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/download/download_commands.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/download_crx_util.h"
#include "chrome/browser/download/download_extensions.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/safe_browsing/download_protection_service.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "components/google/core/browser/google_util.h"
#include "grit/theme_resources.h"
#include "net/base/url_util.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#if defined(OS_WIN)
#include "chrome/browser/download/download_target_determiner.h"
#include "chrome/browser/ui/pdf/adobe_reader_info_win.h"
#endif
DownloadCommands::DownloadCommands(content::DownloadItem* download_item)
: download_item_(download_item) {
DCHECK(download_item);
}
int DownloadCommands::GetCommandIconId(Command command) const {
switch (command) {
case PAUSE:
return IDR_DOWNLOAD_NOTIFICATION_MENU_PAUSE;
case RESUME:
return IDR_DOWNLOAD_NOTIFICATION_MENU_RESUME;
case SHOW_IN_FOLDER:
return IDR_DOWNLOAD_NOTIFICATION_MENU_FOLDER;
case KEEP:
return IDR_DOWNLOAD_NOTIFICATION_MENU_DOWNLOAD;
case DISCARD:
return IDR_DOWNLOAD_NOTIFICATION_MENU_DELETE;
case CANCEL:
// TODO(yoshiki): This is a temporary image for Download Notification
// feature behind the flag. We have to replace the image with proper one
// before the feature launch. http://crbug.com/468559
return IDR_DOWNLOAD_NOTIFICATION_MENU_DELETE;
case OPEN_WHEN_COMPLETE:
case ALWAYS_OPEN_TYPE:
case PLATFORM_OPEN:
case LEARN_MORE_SCANNING:
case LEARN_MORE_INTERRUPTED:
return -1;
}
NOTREACHED();
return -1;
}
GURL DownloadCommands::GetLearnMoreURLForInterruptedDownload() const {
GURL learn_more_url(chrome::kDownloadInterruptedLearnMoreURL);
learn_more_url = google_util::AppendGoogleLocaleParam(
learn_more_url, g_browser_process->GetApplicationLocale());
return net::AppendQueryParameter(
learn_more_url, "ctx",
base::StringPrintf("%d",
static_cast<int>(download_item_->GetLastReason())));
}
gfx::Image DownloadCommands::GetCommandIcon(Command command) {
ResourceBundle& bundle = ResourceBundle::GetSharedInstance();
return bundle.GetImageNamed(GetCommandIconId(command));
}
bool DownloadCommands::IsCommandEnabled(Command command) const {
switch (command) {
case SHOW_IN_FOLDER:
return download_item_->CanShowInFolder();
case OPEN_WHEN_COMPLETE:
case PLATFORM_OPEN:
return download_item_->CanOpenDownload() &&
!download_crx_util::IsExtensionDownload(*download_item_);
case ALWAYS_OPEN_TYPE:
// For temporary downloads, the target filename might be a temporary
// filename. Don't base an "Always open" decision based on it. Also
// exclude extensions.
return download_item_->CanOpenDownload() &&
download_util::IsAllowedToOpenAutomatically(
download_item_->GetTargetFilePath()) &&
!download_crx_util::IsExtensionDownload(*download_item_);
case CANCEL:
return !download_item_->IsDone();
case PAUSE:
return !download_item_->IsDone() && !download_item_->IsPaused() &&
download_item_->GetState() == content::DownloadItem::IN_PROGRESS;
case RESUME:
return download_item_->CanResume() &&
(download_item_->IsPaused() ||
download_item_->GetState() != content::DownloadItem::IN_PROGRESS);
case DISCARD:
case KEEP:
case LEARN_MORE_SCANNING:
case LEARN_MORE_INTERRUPTED:
return true;
}
NOTREACHED();
return false;
}
bool DownloadCommands::IsCommandChecked(Command command) const {
switch (command) {
case OPEN_WHEN_COMPLETE:
return download_item_->GetOpenWhenComplete() ||
download_crx_util::IsExtensionDownload(*download_item_);
case ALWAYS_OPEN_TYPE:
#if defined(OS_WIN) || defined(OS_LINUX) || \
(defined(OS_MACOSX) && !defined(OS_IOS))
if (CanOpenPdfInSystemViewer()) {
DownloadPrefs* prefs = DownloadPrefs::FromBrowserContext(
download_item_->GetBrowserContext());
return prefs->ShouldOpenPdfInSystemReader();
}
#endif
return download_item_->ShouldOpenFileBasedOnExtension();
case PAUSE:
case RESUME:
return download_item_->IsPaused();
case SHOW_IN_FOLDER:
case PLATFORM_OPEN:
case CANCEL:
case DISCARD:
case KEEP:
case LEARN_MORE_SCANNING:
case LEARN_MORE_INTERRUPTED:
return false;
}
return false;
}
bool DownloadCommands::IsCommandVisible(Command command) const {
if (command == PLATFORM_OPEN)
return (DownloadItemModel(download_item_).ShouldPreferOpeningInBrowser());
return true;
}
void DownloadCommands::ExecuteCommand(Command command) {
switch (command) {
case SHOW_IN_FOLDER:
download_item_->ShowDownloadInShell();
break;
case OPEN_WHEN_COMPLETE:
download_item_->OpenDownload();
break;
case ALWAYS_OPEN_TYPE: {
bool is_checked = IsCommandChecked(ALWAYS_OPEN_TYPE);
DownloadPrefs* prefs = DownloadPrefs::FromBrowserContext(
download_item_->GetBrowserContext());
#if defined(OS_WIN) || defined(OS_LINUX) || \
(defined(OS_MACOSX) && !defined(OS_IOS))
if (CanOpenPdfInSystemViewer()) {
prefs->SetShouldOpenPdfInSystemReader(!is_checked);
DownloadItemModel(download_item_)
.SetShouldPreferOpeningInBrowser(is_checked);
break;
}
#endif
base::FilePath path = download_item_->GetTargetFilePath();
if (is_checked)
prefs->DisableAutoOpenBasedOnExtension(path);
else
prefs->EnableAutoOpenBasedOnExtension(path);
break;
}
case PLATFORM_OPEN:
DownloadItemModel(download_item_).OpenUsingPlatformHandler();
break;
case CANCEL:
download_item_->Cancel(true /* Cancelled by user */);
break;
case DISCARD:
download_item_->Remove();
break;
case KEEP:
download_item_->ValidateDangerousDownload();
break;
case LEARN_MORE_SCANNING: {
#if defined(FULL_SAFE_BROWSING)
using safe_browsing::DownloadProtectionService;
SafeBrowsingService* sb_service =
g_browser_process->safe_browsing_service();
DownloadProtectionService* protection_service =
(sb_service ? sb_service->download_protection_service() : nullptr);
if (protection_service)
protection_service->ShowDetailsForDownload(*download_item_,
GetBrowser());
#else
// Should only be getting invoked if we are using safe browsing.
NOTREACHED();
#endif
break;
}
case LEARN_MORE_INTERRUPTED:
GetBrowser()->OpenURL(content::OpenURLParams(
GetLearnMoreURLForInterruptedDownload(), content::Referrer(),
NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_LINK, false));
break;
case PAUSE:
download_item_->Pause();
break;
case RESUME:
download_item_->Resume();
break;
}
}
Browser* DownloadCommands::GetBrowser() const {
Profile* profile =
Profile::FromBrowserContext(download_item_->GetBrowserContext());
chrome::ScopedTabbedBrowserDisplayer browser_displayer(
profile, chrome::GetActiveDesktop());
DCHECK(browser_displayer.browser());
return browser_displayer.browser();
}
#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
bool DownloadCommands::IsDownloadPdf() const {
base::FilePath path = download_item_->GetTargetFilePath();
return path.MatchesExtension(FILE_PATH_LITERAL(".pdf"));
}
#endif
bool DownloadCommands::CanOpenPdfInSystemViewer() const {
#if defined(OS_WIN)
bool is_adobe_pdf_reader_up_to_date = false;
if (IsDownloadPdf() && IsAdobeReaderDefaultPDFViewer()) {
is_adobe_pdf_reader_up_to_date =
DownloadTargetDeterminer::IsAdobeReaderUpToDate();
}
return IsDownloadPdf() &&
(IsAdobeReaderDefaultPDFViewer() ? is_adobe_pdf_reader_up_to_date
: true);
#elif defined(OS_MACOSX) || defined(OS_LINUX)
return IsDownloadPdf();
#endif
}