This source file includes following definitions.
- verdict
- SetVerdict
- GetPlatformDownloadPath
- CheckDownloadUrlDone
- GetMimeTypeAndReplyOnUIThread
- IsOpenInBrowserPreferreredForFile
- weak_ptr_factory_
- SetDownloadManager
- Shutdown
- GetDownloadIdReceiverCallback
- SetNextId
- GetNextId
- ReturnNextId
- DetermineDownloadTarget
- ShouldOpenFileBasedOnExtension
- DisableSafeBrowsing
- IsDownloadReadyForCompletion
- ShouldCompleteDownloadInternal
- ShouldCompleteDownload
- ShouldOpenDownload
- GenerateFileHash
- GetSaveDir
- ChooseSavePath
- OpenDownloadUsingPlatformHandler
- OpenDownload
- ShowDownloadInShell
- CheckForFileExistence
- ApplicationClientIdForFileScanning
- GetDownloadProtectionService
- NotifyExtensions
- ReserveVirtualPath
- PromptUserForDownloadPath
- DetermineLocalPath
- CheckDownloadUrl
- GetFileMimeType
- CheckClientDownloadDone
- Observe
- OnDownloadTargetDetermined
#include "chrome/browser/download/chrome_download_manager_delegate.h"
#include <string>
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/file_util.h"
#include "base/prefs/pref_member.h"
#include "base/prefs/pref_service.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/time/time.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/download/download_completion_blocker.h"
#include "chrome/browser/download/download_crx_util.h"
#include "chrome/browser/download/download_file_picker.h"
#include "chrome/browser/download/download_history.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_path_reservation_tracker.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/download/download_service.h"
#include "chrome/browser/download/download_service_factory.h"
#include "chrome/browser/download/download_stats.h"
#include "chrome/browser/download/download_target_determiner.h"
#include "chrome/browser/download/save_package_file_picker.h"
#include "chrome/browser/extensions/api/downloads/downloads_api.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/pref_names.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/page_navigator.h"
#include "extensions/common/constants.h"
#include "net/base/mime_util.h"
#include "net/base/net_util.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/drive/download_handler.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
#endif
using content::BrowserThread;
using content::DownloadItem;
using content::DownloadManager;
using safe_browsing::DownloadProtectionService;
namespace {
#if defined(FULL_SAFE_BROWSING)
const char kSafeBrowsingUserDataKey[] = "Safe Browsing ID";
class SafeBrowsingState : public DownloadCompletionBlocker {
public:
SafeBrowsingState()
: verdict_(DownloadProtectionService::SAFE) {
}
virtual ~SafeBrowsingState();
DownloadProtectionService::DownloadCheckResult verdict() const {
return verdict_;
}
void SetVerdict(DownloadProtectionService::DownloadCheckResult result) {
verdict_ = result;
CompleteDownload();
}
private:
DownloadProtectionService::DownloadCheckResult verdict_;
DISALLOW_COPY_AND_ASSIGN(SafeBrowsingState);
};
SafeBrowsingState::~SafeBrowsingState() {}
#endif
enum PlatformDownloadPathType {
PLATFORM_TARGET_PATH,
PLATFORM_CURRENT_PATH
};
base::FilePath GetPlatformDownloadPath(Profile* profile,
const DownloadItem* download,
PlatformDownloadPathType path_type) {
#if defined(OS_CHROMEOS)
drive::DownloadHandler* drive_download_handler =
drive::DownloadHandler::GetForProfile(profile);
if (drive_download_handler &&
drive_download_handler->IsDriveDownload(download))
return drive_download_handler->GetTargetPath(download);
#endif
if (path_type == PLATFORM_TARGET_PATH)
return download->GetTargetFilePath();
return download->GetFullPath();
}
#if defined(FULL_SAFE_BROWSING)
void CheckDownloadUrlDone(
const DownloadTargetDeterminerDelegate::CheckDownloadUrlCallback& callback,
bool is_content_check_supported,
DownloadProtectionService::DownloadCheckResult result) {
content::DownloadDangerType danger_type;
if (result == DownloadProtectionService::SAFE) {
if (is_content_check_supported)
danger_type = content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT;
else
danger_type = content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS;
} else {
danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL;
}
callback.Run(danger_type);
}
#endif
void GetMimeTypeAndReplyOnUIThread(
const base::FilePath& path,
const base::Callback<void(const std::string&)>& callback) {
std::string mime_type;
net::GetMimeTypeFromFile(path, &mime_type);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE, base::Bind(callback, mime_type));
}
bool IsOpenInBrowserPreferreredForFile(const base::FilePath& path) {
#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) && defined(ENABLE_PLUGINS)
if (path.MatchesExtension(FILE_PATH_LITERAL(".pdf")) ||
path.MatchesExtension(FILE_PATH_LITERAL(".htm")) ||
path.MatchesExtension(FILE_PATH_LITERAL(".html")) ||
path.MatchesExtension(FILE_PATH_LITERAL(".shtm")) ||
path.MatchesExtension(FILE_PATH_LITERAL(".shtml")) ||
path.MatchesExtension(FILE_PATH_LITERAL(".svg")) ||
path.MatchesExtension(FILE_PATH_LITERAL(".xht")) ||
path.MatchesExtension(FILE_PATH_LITERAL(".xhtm")) ||
path.MatchesExtension(FILE_PATH_LITERAL(".xhtml")) ||
path.MatchesExtension(FILE_PATH_LITERAL(".xml")) ||
path.MatchesExtension(FILE_PATH_LITERAL(".xsl")) ||
path.MatchesExtension(FILE_PATH_LITERAL(".xslt"))) {
return true;
}
#endif
return false;
}
}
ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile)
: profile_(profile),
next_download_id_(content::DownloadItem::kInvalidId),
download_prefs_(new DownloadPrefs(profile)),
weak_ptr_factory_(this) {
}
ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() {
DCHECK(!download_manager_);
}
void ChromeDownloadManagerDelegate::SetDownloadManager(DownloadManager* dm) {
download_manager_ = dm;
}
void ChromeDownloadManagerDelegate::Shutdown() {
download_prefs_.reset();
weak_ptr_factory_.InvalidateWeakPtrs();
download_manager_ = NULL;
}
content::DownloadIdCallback
ChromeDownloadManagerDelegate::GetDownloadIdReceiverCallback() {
return base::Bind(&ChromeDownloadManagerDelegate::SetNextId,
weak_ptr_factory_.GetWeakPtr());
}
void ChromeDownloadManagerDelegate::SetNextId(uint32 next_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(!profile_->IsOffTheRecord());
DCHECK_NE(content::DownloadItem::kInvalidId, next_id);
next_download_id_ = next_id;
IdCallbackVector callbacks;
id_callbacks_.swap(callbacks);
for (IdCallbackVector::const_iterator it = callbacks.begin();
it != callbacks.end(); ++it) {
ReturnNextId(*it);
}
}
void ChromeDownloadManagerDelegate::GetNextId(
const content::DownloadIdCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (profile_->IsOffTheRecord()) {
content::BrowserContext::GetDownloadManager(
profile_->GetOriginalProfile())->GetDelegate()->GetNextId(callback);
return;
}
if (next_download_id_ == content::DownloadItem::kInvalidId) {
id_callbacks_.push_back(callback);
return;
}
ReturnNextId(callback);
}
void ChromeDownloadManagerDelegate::ReturnNextId(
const content::DownloadIdCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(!profile_->IsOffTheRecord());
DCHECK_NE(content::DownloadItem::kInvalidId, next_download_id_);
callback.Run(next_download_id_++);
}
bool ChromeDownloadManagerDelegate::DetermineDownloadTarget(
DownloadItem* download,
const content::DownloadTargetCallback& callback) {
DownloadTargetDeterminer::CompletionCallback target_determined_callback =
base::Bind(&ChromeDownloadManagerDelegate::OnDownloadTargetDetermined,
weak_ptr_factory_.GetWeakPtr(),
download->GetId(),
callback);
DownloadTargetDeterminer::Start(
download,
GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH),
download_prefs_.get(),
this,
target_determined_callback);
return true;
}
bool ChromeDownloadManagerDelegate::ShouldOpenFileBasedOnExtension(
const base::FilePath& path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (path.Extension().empty())
return false;
if (path.MatchesExtension(extensions::kExtensionFileExtension))
return false;
return download_prefs_->IsAutoOpenEnabledBasedOnExtension(path);
}
void ChromeDownloadManagerDelegate::DisableSafeBrowsing(DownloadItem* item) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
#if defined(FULL_SAFE_BROWSING)
SafeBrowsingState* state = static_cast<SafeBrowsingState*>(
item->GetUserData(&kSafeBrowsingUserDataKey));
if (!state) {
state = new SafeBrowsingState();
item->SetUserData(&kSafeBrowsingUserDataKey, state);
}
state->SetVerdict(DownloadProtectionService::SAFE);
#endif
}
bool ChromeDownloadManagerDelegate::IsDownloadReadyForCompletion(
DownloadItem* item,
const base::Closure& internal_complete_callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
#if defined(FULL_SAFE_BROWSING)
SafeBrowsingState* state = static_cast<SafeBrowsingState*>(
item->GetUserData(&kSafeBrowsingUserDataKey));
if (!state) {
DownloadProtectionService* service = GetDownloadProtectionService();
if (service) {
VLOG(2) << __FUNCTION__ << "() Start SB download check for download = "
<< item->DebugString(false);
state = new SafeBrowsingState();
state->set_callback(internal_complete_callback);
item->SetUserData(&kSafeBrowsingUserDataKey, state);
service->CheckClientDownload(
item,
base::Bind(
&ChromeDownloadManagerDelegate::CheckClientDownloadDone,
weak_ptr_factory_.GetWeakPtr(),
item->GetId()));
return false;
}
} else if (!state->is_complete()) {
state->set_callback(internal_complete_callback);
return false;
}
#endif
return true;
}
void ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal(
uint32 download_id,
const base::Closure& user_complete_callback) {
DownloadItem* item = download_manager_->GetDownload(download_id);
if (!item)
return;
if (ShouldCompleteDownload(item, user_complete_callback))
user_complete_callback.Run();
}
bool ChromeDownloadManagerDelegate::ShouldCompleteDownload(
DownloadItem* item,
const base::Closure& user_complete_callback) {
return IsDownloadReadyForCompletion(item, base::Bind(
&ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal,
weak_ptr_factory_.GetWeakPtr(), item->GetId(), user_complete_callback));
}
bool ChromeDownloadManagerDelegate::ShouldOpenDownload(
DownloadItem* item, const content::DownloadOpenDelayedCallback& callback) {
if (download_crx_util::IsExtensionDownload(*item)) {
scoped_refptr<extensions::CrxInstaller> crx_installer =
download_crx_util::OpenChromeExtension(profile_, *item);
registrar_.Add(
this,
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
content::Source<extensions::CrxInstaller>(crx_installer.get()));
crx_installers_[crx_installer.get()] = callback;
item->UpdateObservers();
return false;
}
return true;
}
bool ChromeDownloadManagerDelegate::GenerateFileHash() {
#if defined(FULL_SAFE_BROWSING)
return profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled) &&
g_browser_process->safe_browsing_service()->DownloadBinHashNeeded();
#else
return false;
#endif
}
void ChromeDownloadManagerDelegate::GetSaveDir(
content::BrowserContext* browser_context,
base::FilePath* website_save_dir,
base::FilePath* download_save_dir,
bool* skip_dir_check) {
*website_save_dir = download_prefs_->SaveFilePath();
DCHECK(!website_save_dir->empty());
*download_save_dir = download_prefs_->DownloadPath();
*skip_dir_check = false;
#if defined(OS_CHROMEOS)
*skip_dir_check = drive::util::IsUnderDriveMountPoint(*website_save_dir);
#endif
}
void ChromeDownloadManagerDelegate::ChooseSavePath(
content::WebContents* web_contents,
const base::FilePath& suggested_path,
const base::FilePath::StringType& default_extension,
bool can_save_as_complete,
const content::SavePackagePathPickedCallback& callback) {
new SavePackageFilePicker(
web_contents,
suggested_path,
default_extension,
can_save_as_complete,
download_prefs_.get(),
callback);
}
void ChromeDownloadManagerDelegate::OpenDownloadUsingPlatformHandler(
DownloadItem* download) {
base::FilePath platform_path(
GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH));
DCHECK(!platform_path.empty());
platform_util::OpenItem(profile_, platform_path);
}
void ChromeDownloadManagerDelegate::OpenDownload(DownloadItem* download) {
DCHECK_EQ(DownloadItem::COMPLETE, download->GetState());
DCHECK(!download->GetTargetFilePath().empty());
if (!download->CanOpenDownload())
return;
if (!DownloadItemModel(download).ShouldPreferOpeningInBrowser()) {
RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_PLATFORM);
OpenDownloadUsingPlatformHandler(download);
return;
}
#if !defined(OS_ANDROID)
content::WebContents* web_contents = download->GetWebContents();
Browser* browser =
web_contents ? chrome::FindBrowserWithWebContents(web_contents) : NULL;
scoped_ptr<chrome::ScopedTabbedBrowserDisplayer> browser_displayer;
if (!browser ||
!browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
browser_displayer.reset(new chrome::ScopedTabbedBrowserDisplayer(
profile_, chrome::GetActiveDesktop()));
browser = browser_displayer->browser();
}
content::OpenURLParams params(
net::FilePathToFileURL(download->GetTargetFilePath()),
content::Referrer(),
NEW_FOREGROUND_TAB,
content::PAGE_TRANSITION_LINK,
false);
browser->OpenURL(params);
RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_BROWSER);
#else
NOTREACHED();
#endif
}
void ChromeDownloadManagerDelegate::ShowDownloadInShell(
DownloadItem* download) {
if (!download->CanShowInFolder())
return;
base::FilePath platform_path(
GetPlatformDownloadPath(profile_, download, PLATFORM_CURRENT_PATH));
DCHECK(!platform_path.empty());
platform_util::ShowItemInFolder(profile_, platform_path);
}
void ChromeDownloadManagerDelegate::CheckForFileExistence(
DownloadItem* download,
const content::CheckForFileExistenceCallback& callback) {
#if defined(OS_CHROMEOS)
drive::DownloadHandler* drive_download_handler =
drive::DownloadHandler::GetForProfile(profile_);
if (drive_download_handler &&
drive_download_handler->IsDriveDownload(download)) {
drive_download_handler->CheckForFileExistence(download, callback);
return;
}
#endif
static const char kSequenceToken[] = "ChromeDMD-FileExistenceChecker";
base::SequencedWorkerPool* worker_pool = BrowserThread::GetBlockingPool();
scoped_refptr<base::SequencedTaskRunner> task_runner =
worker_pool->GetSequencedTaskRunnerWithShutdownBehavior(
worker_pool->GetNamedSequenceToken(kSequenceToken),
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
base::PostTaskAndReplyWithResult(
task_runner.get(),
FROM_HERE,
base::Bind(&base::PathExists, download->GetTargetFilePath()),
callback);
}
std::string
ChromeDownloadManagerDelegate::ApplicationClientIdForFileScanning() const {
return std::string(chrome::kApplicationClientIDStringForAVScanning);
}
DownloadProtectionService*
ChromeDownloadManagerDelegate::GetDownloadProtectionService() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
#if defined(FULL_SAFE_BROWSING)
SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
if (sb_service && sb_service->download_protection_service() &&
profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) {
return sb_service->download_protection_service();
}
#endif
return NULL;
}
void ChromeDownloadManagerDelegate::NotifyExtensions(
DownloadItem* download,
const base::FilePath& virtual_path,
const NotifyExtensionsCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
#if !defined(OS_ANDROID)
ExtensionDownloadsEventRouter* router =
DownloadServiceFactory::GetForBrowserContext(profile_)->
GetExtensionEventRouter();
if (router) {
base::Closure original_path_callback =
base::Bind(callback, base::FilePath(),
DownloadPathReservationTracker::UNIQUIFY);
router->OnDeterminingFilename(download, virtual_path.BaseName(),
original_path_callback,
callback);
return;
}
#endif
callback.Run(base::FilePath(), DownloadPathReservationTracker::UNIQUIFY);
}
void ChromeDownloadManagerDelegate::ReserveVirtualPath(
content::DownloadItem* download,
const base::FilePath& virtual_path,
bool create_directory,
DownloadPathReservationTracker::FilenameConflictAction conflict_action,
const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(!virtual_path.empty());
#if defined(OS_CHROMEOS)
if (drive::util::IsUnderDriveMountPoint(virtual_path)) {
callback.Run(virtual_path, true);
return;
}
#endif
DownloadPathReservationTracker::GetReservedPath(
download,
virtual_path,
download_prefs_->DownloadPath(),
create_directory,
conflict_action,
callback);
}
void ChromeDownloadManagerDelegate::PromptUserForDownloadPath(
DownloadItem* download,
const base::FilePath& suggested_path,
const DownloadTargetDeterminerDelegate::FileSelectedCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DownloadFilePicker::ShowFilePicker(download, suggested_path, callback);
}
void ChromeDownloadManagerDelegate::DetermineLocalPath(
DownloadItem* download,
const base::FilePath& virtual_path,
const DownloadTargetDeterminerDelegate::LocalPathCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
#if defined(OS_CHROMEOS)
drive::DownloadHandler* drive_download_handler =
drive::DownloadHandler::GetForProfile(profile_);
if (drive_download_handler) {
drive_download_handler->SubstituteDriveDownloadPath(
virtual_path, download, callback);
return;
}
#endif
callback.Run(virtual_path);
}
void ChromeDownloadManagerDelegate::CheckDownloadUrl(
DownloadItem* download,
const base::FilePath& suggested_path,
const CheckDownloadUrlCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
#if defined(FULL_SAFE_BROWSING)
safe_browsing::DownloadProtectionService* service =
GetDownloadProtectionService();
if (service) {
bool is_content_check_supported =
service->IsSupportedDownload(*download, suggested_path);
VLOG(2) << __FUNCTION__ << "() Start SB URL check for download = "
<< download->DebugString(false);
service->CheckDownloadUrl(*download,
base::Bind(&CheckDownloadUrlDone,
callback,
is_content_check_supported));
return;
}
#endif
callback.Run(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
}
void ChromeDownloadManagerDelegate::GetFileMimeType(
const base::FilePath& path,
const GetFileMimeTypeCallback& callback) {
BrowserThread::PostBlockingPoolTask(
FROM_HERE,
base::Bind(&GetMimeTypeAndReplyOnUIThread, path, callback));
}
#if defined(FULL_SAFE_BROWSING)
void ChromeDownloadManagerDelegate::CheckClientDownloadDone(
uint32 download_id,
DownloadProtectionService::DownloadCheckResult result) {
DownloadItem* item = download_manager_->GetDownload(download_id);
if (!item || (item->GetState() != DownloadItem::IN_PROGRESS))
return;
VLOG(2) << __FUNCTION__ << "() download = " << item->DebugString(false)
<< " verdict = " << result;
if (item->GetDangerType() == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS ||
item->GetDangerType() ==
content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT) {
content::DownloadDangerType danger_type =
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS;
switch (result) {
case DownloadProtectionService::SAFE:
break;
case DownloadProtectionService::DANGEROUS:
danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT;
break;
case DownloadProtectionService::UNCOMMON:
danger_type = content::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT;
break;
case DownloadProtectionService::DANGEROUS_HOST:
danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST;
break;
case DownloadProtectionService::POTENTIALLY_UNWANTED:
danger_type = content::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED;
break;
}
if (danger_type != content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)
item->OnContentCheckCompleted(danger_type);
}
SafeBrowsingState* state = static_cast<SafeBrowsingState*>(
item->GetUserData(&kSafeBrowsingUserDataKey));
state->SetVerdict(result);
}
#endif
void ChromeDownloadManagerDelegate::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
DCHECK(type == chrome::NOTIFICATION_CRX_INSTALLER_DONE);
registrar_.Remove(this,
chrome::NOTIFICATION_CRX_INSTALLER_DONE,
source);
scoped_refptr<extensions::CrxInstaller> installer =
content::Source<extensions::CrxInstaller>(source).ptr();
content::DownloadOpenDelayedCallback callback =
crx_installers_[installer.get()];
crx_installers_.erase(installer.get());
callback.Run(installer->did_handle_successfully());
}
void ChromeDownloadManagerDelegate::OnDownloadTargetDetermined(
int32 download_id,
const content::DownloadTargetCallback& callback,
scoped_ptr<DownloadTargetInfo> target_info) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DownloadItem* item = download_manager_->GetDownload(download_id);
if (!target_info->target_path.empty() && item &&
IsOpenInBrowserPreferreredForFile(target_info->target_path) &&
target_info->is_filetype_handled_safely)
DownloadItemModel(item).SetShouldPreferOpeningInBrowser(true);
callback.Run(target_info->target_path,
target_info->target_disposition,
target_info->danger_type,
target_info->intermediate_path);
}