blob: c1c3b7f9696cb5088546754d51ae649ad74c6c3d [file] [log] [blame]
// Copyright (c) 2012 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_shelf.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/message_loop.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_started_animation.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "ui/base/animation/animation.h"
using content::DownloadItem;
namespace {
// Delay before we show a transient download.
const int64 kDownloadShowDelayInSeconds = 2;
} // namespace
DownloadShelf::DownloadShelf()
: should_show_on_unhide_(false),
is_hidden_(false),
weak_ptr_factory_(this) {
}
DownloadShelf::~DownloadShelf() {
}
void DownloadShelf::AddDownload(DownloadItem* download) {
DCHECK(download);
if (DownloadItemModel(download).ShouldRemoveFromShelfWhenComplete()) {
// If we are going to remove the download from the shelf upon completion,
// wait a few seconds to see if it completes quickly. If it's a small
// download, then the user won't have time to interact with it.
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&DownloadShelf::ShowDownloadById,
weak_ptr_factory_.GetWeakPtr(),
download->GetId()),
GetTransientDownloadShowDelay());
} else {
ShowDownload(download);
}
}
void DownloadShelf::Show() {
if (is_hidden_) {
should_show_on_unhide_ = true;
return;
}
DoShow();
}
void DownloadShelf::Close(CloseReason reason) {
if (is_hidden_) {
should_show_on_unhide_ = false;
return;
}
DoClose(reason);
}
void DownloadShelf::Hide() {
if (is_hidden_)
return;
is_hidden_ = true;
if (IsShowing()) {
should_show_on_unhide_ = true;
DoClose(AUTOMATIC);
}
}
void DownloadShelf::Unhide() {
if (!is_hidden_)
return;
is_hidden_ = false;
if (should_show_on_unhide_) {
should_show_on_unhide_ = false;
DoShow();
}
}
base::TimeDelta DownloadShelf::GetTransientDownloadShowDelay() {
return base::TimeDelta::FromSeconds(kDownloadShowDelayInSeconds);
}
content::DownloadManager* DownloadShelf::GetDownloadManager() {
DCHECK(browser());
return content::BrowserContext::GetDownloadManager(browser()->profile());
}
void DownloadShelf::ShowDownload(DownloadItem* download) {
if (download->GetState() == DownloadItem::COMPLETE &&
DownloadItemModel(download).ShouldRemoveFromShelfWhenComplete()) {
return;
}
if (is_hidden_)
Unhide();
Show();
DoAddDownload(download);
// browser() can be NULL for tests.
if (!browser())
return;
// Show the download started animation if:
// - Download started animation is enabled for this download. It is disabled
// for "Save As" downloads and extension installs, for example.
// - The browser has an active visible WebContents. (browser isn't minimized,
// or running under a test etc.)
// - Rich animations are enabled.
content::WebContents* shelf_tab =
browser()->tab_strip_model()->GetActiveWebContents();
if (DownloadItemModel(download).ShouldShowDownloadStartedAnimation() &&
shelf_tab &&
platform_util::IsVisible(shelf_tab->GetView()->GetNativeView()) &&
ui::Animation::ShouldRenderRichAnimation()) {
DownloadStartedAnimation::Show(shelf_tab);
}
}
void DownloadShelf::ShowDownloadById(int32 download_id) {
content::DownloadManager* download_manager = GetDownloadManager();
if (!download_manager)
return;
DownloadItem* download = download_manager->GetDownload(download_id);
if (!download)
return;
ShowDownload(download);
}