blob: a7387fed4e3a1ffd9fcfa85a8be026c8d6e9120d [file] [log] [blame]
// Copyright 2018 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/offline_item_model.h"
#include "base/time/time.h"
#include "chrome/browser/download/offline_item_model_manager.h"
#include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h"
#include "components/offline_items_collection/core/fail_state.h"
#include "components/offline_items_collection/core/offline_content_aggregator.h"
using offline_items_collection::ContentId;
using offline_items_collection::FailState;
using offline_items_collection::OfflineItem;
using offline_items_collection::OfflineItemState;
// static
DownloadUIModel::DownloadUIModelPtr OfflineItemModel::Wrap(
OfflineItemModelManager* manager,
const OfflineItem& offline_item) {
DownloadUIModel::DownloadUIModelPtr model(
new OfflineItemModel(manager, offline_item),
base::OnTaskRunnerDeleter(base::ThreadTaskRunnerHandle::Get()));
return model;
}
OfflineItemModel::OfflineItemModel(OfflineItemModelManager* manager,
const OfflineItem& offline_item)
: manager_(manager),
offline_item_(std::make_unique<OfflineItem>(offline_item)) {
offline_items_collection::OfflineContentAggregator* aggregator =
OfflineContentAggregatorFactory::GetForBrowserContext(
manager_->browser_context());
offline_item_observer_ =
std::make_unique<FilteredOfflineItemObserver>(aggregator);
offline_item_observer_->AddObserver(offline_item_->id, this);
}
OfflineItemModel::~OfflineItemModel() {
if (offline_item_)
offline_item_observer_->RemoveObserver(offline_item_->id, this);
}
Profile* OfflineItemModel::profile() const {
return Profile::FromBrowserContext(manager_->browser_context());
}
ContentId OfflineItemModel::GetContentId() const {
return offline_item_ ? offline_item_->id : ContentId();
}
int64_t OfflineItemModel::GetCompletedBytes() const {
return offline_item_ ? offline_item_->received_bytes : 0;
}
int64_t OfflineItemModel::GetTotalBytes() const {
if (!offline_item_)
return 0;
return offline_item_->total_size_bytes > 0 ? offline_item_->total_size_bytes
: 0;
}
int OfflineItemModel::PercentComplete() const {
if (GetTotalBytes() <= 0)
return -1;
return static_cast<int>(GetCompletedBytes() * 100.0 / GetTotalBytes());
}
bool OfflineItemModel::WasUINotified() const {
const OfflineItemModelData* data =
manager_->GetOrCreateOfflineItemModelData(offline_item_->id);
return data->was_ui_notified_;
}
void OfflineItemModel::SetWasUINotified(bool was_ui_notified) {
OfflineItemModelData* data =
manager_->GetOrCreateOfflineItemModelData(offline_item_->id);
data->was_ui_notified_ = was_ui_notified;
}
base::FilePath OfflineItemModel::GetFileNameToReportUser() const {
return offline_item_ ? base::FilePath::FromUTF8Unsafe(offline_item_->title)
: base::FilePath();
}
base::FilePath OfflineItemModel::GetTargetFilePath() const {
return offline_item_ ? offline_item_->file_path : base::FilePath();
}
void OfflineItemModel::OpenDownload() {
if (!offline_item_)
return;
GetProvider()->OpenItem(
offline_items_collection::LaunchLocation::DOWNLOAD_SHELF,
offline_item_->id);
}
void OfflineItemModel::Pause() {
if (!offline_item_)
return;
GetProvider()->PauseDownload(offline_item_->id);
}
void OfflineItemModel::Resume() {
if (!offline_item_)
return;
GetProvider()->ResumeDownload(offline_item_->id, true /* has_user_gesture */);
}
void OfflineItemModel::Cancel(bool user_cancel) {
if (!offline_item_)
return;
GetProvider()->CancelDownload(offline_item_->id);
}
void OfflineItemModel::Remove() {
if (!offline_item_)
return;
GetProvider()->RemoveItem(offline_item_->id);
}
download::DownloadItem::DownloadState OfflineItemModel::GetState() const {
if (!offline_item_)
return download::DownloadItem::CANCELLED;
switch (offline_item_->state) {
case OfflineItemState::IN_PROGRESS:
FALLTHROUGH;
case OfflineItemState::PAUSED:
return download::DownloadItem::IN_PROGRESS;
case OfflineItemState::PENDING:
FALLTHROUGH;
case OfflineItemState::INTERRUPTED:
FALLTHROUGH;
case OfflineItemState::FAILED:
return download::DownloadItem::INTERRUPTED;
case OfflineItemState::COMPLETE:
return download::DownloadItem::COMPLETE;
case OfflineItemState::CANCELLED:
return download::DownloadItem::CANCELLED;
case OfflineItemState::MAX_DOWNLOAD_STATE:
NOTREACHED();
return download::DownloadItem::CANCELLED;
}
}
bool OfflineItemModel::IsPaused() const {
return offline_item_ ? offline_item_->state == OfflineItemState::PAUSED
: true;
}
bool OfflineItemModel::TimeRemaining(base::TimeDelta* remaining) const {
if (!offline_item_ || offline_item_->time_remaining_ms == -1)
return false;
*remaining =
base::TimeDelta::FromMilliseconds(offline_item_->time_remaining_ms);
return true;
}
bool OfflineItemModel::IsDone() const {
if (!offline_item_)
return true;
switch (offline_item_->state) {
case OfflineItemState::IN_PROGRESS:
FALLTHROUGH;
case OfflineItemState::PAUSED:
FALLTHROUGH;
case OfflineItemState::PENDING:
return false;
case OfflineItemState::INTERRUPTED:
return !offline_item_->is_resumable;
case OfflineItemState::FAILED:
FALLTHROUGH;
case OfflineItemState::COMPLETE:
FALLTHROUGH;
case OfflineItemState::CANCELLED:
return true;
case OfflineItemState::MAX_DOWNLOAD_STATE:
NOTREACHED();
}
return false;
}
base::FilePath OfflineItemModel::GetFullPath() const {
return GetTargetFilePath();
}
bool OfflineItemModel::CanResume() const {
return offline_item_ ? offline_item_->is_resumable : false;
}
bool OfflineItemModel::AllDataSaved() const {
return offline_item_ ? offline_item_->state == OfflineItemState::COMPLETE
: false;
}
bool OfflineItemModel::GetFileExternallyRemoved() const {
return offline_item_ ? offline_item_->externally_removed : true;
}
GURL OfflineItemModel::GetURL() const {
return offline_item_ ? offline_item_->page_url : GURL();
}
bool OfflineItemModel::ShouldRemoveFromShelfWhenComplete() const {
// TODO(shaktisahu): Add more appropriate logic.
return false;
}
OfflineContentProvider* OfflineItemModel::GetProvider() const {
offline_items_collection::OfflineContentAggregator* aggregator =
OfflineContentAggregatorFactory::GetForBrowserContext(
manager_->browser_context());
return aggregator;
}
void OfflineItemModel::OnItemRemoved(const ContentId& id) {
for (auto& obs : observers_)
obs.OnDownloadDestroyed();
offline_item_.reset();
}
void OfflineItemModel::OnItemUpdated(const OfflineItem& item) {
offline_item_ = std::make_unique<OfflineItem>(item);
for (auto& obs : observers_)
obs.OnDownloadUpdated();
}
FailState OfflineItemModel::GetLastFailState() const {
return offline_item_ ? offline_item_->fail_state : FailState::USER_CANCELED;
}
GURL OfflineItemModel::GetOriginalURL() const {
return offline_item_ ? offline_item_->original_url : GURL();
}
bool OfflineItemModel::ShouldPromoteOrigin() const {
return offline_item_ && offline_item_->promote_origin;
}
#if !defined(OS_ANDROID)
bool OfflineItemModel::IsCommandEnabled(
const DownloadCommands* download_commands,
DownloadCommands::Command command) const {
switch (command) {
case DownloadCommands::SHOW_IN_FOLDER:
case DownloadCommands::OPEN_WHEN_COMPLETE:
case DownloadCommands::PLATFORM_OPEN:
case DownloadCommands::ALWAYS_OPEN_TYPE:
NOTIMPLEMENTED();
return false;
case DownloadCommands::PAUSE:
case DownloadCommands::CANCEL:
case DownloadCommands::RESUME:
case DownloadCommands::COPY_TO_CLIPBOARD:
case DownloadCommands::ANNOTATE:
case DownloadCommands::DISCARD:
case DownloadCommands::KEEP:
case DownloadCommands::LEARN_MORE_SCANNING:
case DownloadCommands::LEARN_MORE_INTERRUPTED:
return DownloadUIModel::IsCommandEnabled(download_commands, command);
}
NOTREACHED();
return false;
}
bool OfflineItemModel::IsCommandChecked(
const DownloadCommands* download_commands,
DownloadCommands::Command command) const {
switch (command) {
case DownloadCommands::OPEN_WHEN_COMPLETE:
case DownloadCommands::ALWAYS_OPEN_TYPE:
NOTIMPLEMENTED();
return false;
case DownloadCommands::PAUSE:
case DownloadCommands::RESUME:
return IsPaused();
case DownloadCommands::SHOW_IN_FOLDER:
case DownloadCommands::PLATFORM_OPEN:
case DownloadCommands::CANCEL:
case DownloadCommands::DISCARD:
case DownloadCommands::KEEP:
case DownloadCommands::LEARN_MORE_SCANNING:
case DownloadCommands::LEARN_MORE_INTERRUPTED:
case DownloadCommands::COPY_TO_CLIPBOARD:
case DownloadCommands::ANNOTATE:
return false;
}
return false;
}
void OfflineItemModel::ExecuteCommand(DownloadCommands* download_commands,
DownloadCommands::Command command) {
switch (command) {
case DownloadCommands::SHOW_IN_FOLDER:
case DownloadCommands::OPEN_WHEN_COMPLETE:
case DownloadCommands::ALWAYS_OPEN_TYPE:
case DownloadCommands::KEEP:
case DownloadCommands::LEARN_MORE_SCANNING:
NOTIMPLEMENTED();
return;
case DownloadCommands::PLATFORM_OPEN:
case DownloadCommands::CANCEL:
case DownloadCommands::DISCARD:
case DownloadCommands::LEARN_MORE_INTERRUPTED:
case DownloadCommands::PAUSE:
case DownloadCommands::RESUME:
case DownloadCommands::COPY_TO_CLIPBOARD:
case DownloadCommands::ANNOTATE:
DownloadUIModel::ExecuteCommand(download_commands, command);
break;
}
}
#endif
std::string OfflineItemModel::GetMimeType() const {
return offline_item_ ? offline_item_->mime_type : "";
}