blob: 7a1fb4a4b8976ad0a81222d0282d1cda5807222a [file] [log] [blame]
// Copyright (c) 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_utils.h"
#include "chrome/grit/generated_resources.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/download_item_utils.h"
#include "third_party/blink/public/common/mime_util/mime_util.h"
#include "ui/base/l10n/l10n_util.h"
using DownloadItem = download::DownloadItem;
using ContentId = offline_items_collection::ContentId;
using OfflineItem = offline_items_collection::OfflineItem;
using OfflineItemFilter = offline_items_collection::OfflineItemFilter;
using OfflineItemState = offline_items_collection::OfflineItemState;
using OfflineItemProgressUnit =
offline_items_collection::OfflineItemProgressUnit;
using FailState = offline_items_collection::FailState;
using PendingState = offline_items_collection::PendingState;
namespace {
// The namespace for downloads.
const char kDownloadNamespace[] = "LEGACY_DOWNLOAD";
// The namespace for incognito downloads.
const char kDownloadIncognitoNamespace[] = "LEGACY_DOWNLOAD_INCOGNITO";
// Prefix that all download namespaces should start with.
const char kDownloadNamespacePrefix[] = "LEGACY_DOWNLOAD";
// The remaining time for a download item if it cannot be calculated.
constexpr int64_t kUnknownRemainingTime = -1;
OfflineItemFilter MimeTypeToOfflineItemFilter(const std::string& mime_type) {
OfflineItemFilter filter = OfflineItemFilter::FILTER_OTHER;
if (base::StartsWith(mime_type, "audio/", base::CompareCase::SENSITIVE)) {
filter = OfflineItemFilter::FILTER_AUDIO;
} else if (base::StartsWith(mime_type, "video/",
base::CompareCase::SENSITIVE)) {
filter = OfflineItemFilter::FILTER_VIDEO;
} else if (base::StartsWith(mime_type, "image/",
base::CompareCase::SENSITIVE)) {
filter = OfflineItemFilter::FILTER_IMAGE;
} else if (base::StartsWith(mime_type, "text/",
base::CompareCase::SENSITIVE)) {
filter = OfflineItemFilter::FILTER_DOCUMENT;
} else {
filter = OfflineItemFilter::FILTER_OTHER;
}
return filter;
}
} // namespace
OfflineItem OfflineItemUtils::CreateOfflineItem(const std::string& name_space,
DownloadItem* download_item) {
bool off_the_record =
content::DownloadItemUtils::GetBrowserContext(download_item)
->IsOffTheRecord();
OfflineItem item;
item.id = ContentId(name_space, download_item->GetGuid());
item.title = download_item->GetFileNameToReportUser().AsUTF8Unsafe();
item.description = download_item->GetFileNameToReportUser().AsUTF8Unsafe();
item.filter = MimeTypeToOfflineItemFilter(download_item->GetMimeType());
item.is_transient = download_item->IsTransient();
item.is_suggested = false;
item.is_accelerated = download_item->IsParallelDownload();
item.total_size_bytes = download_item->GetTotalBytes();
item.externally_removed = download_item->GetFileExternallyRemoved();
item.creation_time = download_item->GetStartTime();
item.last_accessed_time = download_item->GetLastAccessTime();
item.is_openable = download_item->CanOpenDownload() &&
blink::IsSupportedMimeType(download_item->GetMimeType());
item.file_path = download_item->GetTargetFilePath();
item.mime_type = download_item->GetMimeType();
item.page_url = download_item->GetTabUrl();
item.original_url = download_item->GetOriginalUrl();
item.is_off_the_record = off_the_record;
item.is_resumable = download_item->CanResume();
item.received_bytes = download_item->GetReceivedBytes();
item.is_dangerous = download_item->IsDangerous();
base::TimeDelta time_delta;
bool time_remaining_known = download_item->TimeRemaining(&time_delta);
item.time_remaining_ms = time_remaining_known ? time_delta.InMilliseconds()
: kUnknownRemainingTime;
// TODO(crbug.com/857549): Add allow_metered, fail_state, pending_state.
item.fail_state =
ConvertDownloadInterruptReasonToFailState(download_item->GetLastReason());
switch (download_item->GetState()) {
case DownloadItem::IN_PROGRESS:
item.state = download_item->IsPaused() ? OfflineItemState::PAUSED
: OfflineItemState::IN_PROGRESS;
break;
case DownloadItem::COMPLETE:
item.state = download_item->GetReceivedBytes() == 0
? OfflineItemState::FAILED
: OfflineItemState::COMPLETE;
break;
case DownloadItem::CANCELLED:
item.state = OfflineItemState::CANCELLED;
break;
case DownloadItem::INTERRUPTED:
item.state = download_item->CanResume() ? OfflineItemState::INTERRUPTED
: OfflineItemState::FAILED;
break;
default:
NOTREACHED();
}
item.progress.value = download_item->GetReceivedBytes();
if (download_item->PercentComplete() != -1)
item.progress.max = download_item->GetTotalBytes();
item.progress.unit = OfflineItemProgressUnit::BYTES;
return item;
}
std::string OfflineItemUtils::GetDownloadNamespacePrefix(
bool is_off_the_record) {
return is_off_the_record ? kDownloadIncognitoNamespace : kDownloadNamespace;
}
bool OfflineItemUtils::IsDownload(const ContentId& id) {
return id.name_space.find(kDownloadNamespacePrefix) != std::string::npos;
}
// static
FailState OfflineItemUtils::ConvertDownloadInterruptReasonToFailState(
download::DownloadInterruptReason reason) {
switch (reason) {
case download::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED:
return FailState::FILE_FAILED;
case download::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED:
return FailState::FILE_ACCESS_DENIED;
case download::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE:
return FailState::FILE_NO_SPACE;
case download::DOWNLOAD_INTERRUPT_REASON_FILE_NAME_TOO_LONG:
return FailState::FILE_NAME_TOO_LONG;
case download::DOWNLOAD_INTERRUPT_REASON_FILE_TOO_LARGE:
return FailState::FILE_TOO_LARGE;
case download::DOWNLOAD_INTERRUPT_REASON_FILE_VIRUS_INFECTED:
return FailState::FILE_VIRUS_INFECTED;
case download::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR:
return FailState::FILE_TRANSIENT_ERROR;
case download::DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED:
return FailState::FILE_BLOCKED;
case download::DOWNLOAD_INTERRUPT_REASON_FILE_SECURITY_CHECK_FAILED:
return FailState::FILE_SECURITY_CHECK_FAILED;
case download::DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT:
return FailState::FILE_TOO_SHORT;
case download::DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH:
return FailState::FILE_HASH_MISMATCH;
case download::DOWNLOAD_INTERRUPT_REASON_FILE_SAME_AS_SOURCE:
return FailState::FILE_SAME_AS_SOURCE;
case download::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED:
return FailState::NETWORK_FAILED;
case download::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT:
return FailState::NETWORK_TIMEOUT;
case download::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED:
return FailState::NETWORK_DISCONNECTED;
case download::DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN:
return FailState::NETWORK_SERVER_DOWN;
case download::DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST:
return FailState::NETWORK_INVALID_REQUEST;
case download::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED:
return FailState::SERVER_FAILED;
case download::DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE:
return FailState::SERVER_NO_RANGE;
case download::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT:
return FailState::SERVER_BAD_CONTENT;
case download::DOWNLOAD_INTERRUPT_REASON_SERVER_UNAUTHORIZED:
return FailState::SERVER_UNAUTHORIZED;
case download::DOWNLOAD_INTERRUPT_REASON_SERVER_CERT_PROBLEM:
return FailState::SERVER_CERT_PROBLEM;
case download::DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN:
return FailState::SERVER_FORBIDDEN;
case download::DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE:
return FailState::SERVER_UNREACHABLE;
case download::DOWNLOAD_INTERRUPT_REASON_SERVER_CONTENT_LENGTH_MISMATCH:
return FailState::SERVER_CONTENT_LENGTH_MISMATCH;
case download::DOWNLOAD_INTERRUPT_REASON_SERVER_CROSS_ORIGIN_REDIRECT:
return FailState::SERVER_CROSS_ORIGIN_REDIRECT;
case download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED:
return FailState::USER_CANCELED;
case download::DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN:
return FailState::USER_SHUTDOWN;
case download::DOWNLOAD_INTERRUPT_REASON_CRASH:
return FailState::CRASH;
case download::DOWNLOAD_INTERRUPT_REASON_NONE:
return FailState::NO_FAILURE;
}
}
// static
base::string16 OfflineItemUtils::GetFailStateMessage(FailState fail_state) {
int string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS;
switch (fail_state) {
case FailState::FILE_ACCESS_DENIED:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_ACCESS_DENIED;
break;
case FailState::FILE_NO_SPACE:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_DISK_FULL;
break;
case FailState::FILE_NAME_TOO_LONG:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_PATH_TOO_LONG;
break;
case FailState::FILE_TOO_LARGE:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_FILE_TOO_LARGE;
break;
case FailState::FILE_VIRUS_INFECTED:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_VIRUS;
break;
case FailState::FILE_TRANSIENT_ERROR:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_TEMPORARY_PROBLEM;
break;
case FailState::FILE_BLOCKED:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_BLOCKED;
break;
case FailState::FILE_SECURITY_CHECK_FAILED:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_SECURITY_CHECK_FAILED;
break;
case FailState::FILE_TOO_SHORT:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_FILE_TOO_SHORT;
break;
case FailState::FILE_SAME_AS_SOURCE:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_FILE_SAME_AS_SOURCE;
break;
case FailState::NETWORK_INVALID_REQUEST:
FALLTHROUGH;
case FailState::NETWORK_FAILED:
FALLTHROUGH;
case FailState::NETWORK_INSTABILITY:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_NETWORK_ERROR;
break;
case FailState::NETWORK_TIMEOUT:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_NETWORK_TIMEOUT;
break;
case FailState::NETWORK_DISCONNECTED:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_NETWORK_DISCONNECTED;
break;
case FailState::NETWORK_SERVER_DOWN:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_SERVER_DOWN;
break;
case FailState::SERVER_FAILED:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_SERVER_PROBLEM;
break;
case FailState::SERVER_BAD_CONTENT:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_NO_FILE;
break;
case FailState::USER_CANCELED:
string_id = IDS_DOWNLOAD_STATUS_CANCELLED;
break;
case FailState::USER_SHUTDOWN:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_SHUTDOWN;
break;
case FailState::CRASH:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_CRASH;
break;
case FailState::SERVER_UNAUTHORIZED:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_UNAUTHORIZED;
break;
case FailState::SERVER_CERT_PROBLEM:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_SERVER_CERT_PROBLEM;
break;
case FailState::SERVER_FORBIDDEN:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_FORBIDDEN;
break;
case FailState::SERVER_UNREACHABLE:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_UNREACHABLE;
break;
case FailState::SERVER_CONTENT_LENGTH_MISMATCH:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS_CONTENT_LENGTH_MISMATCH;
break;
case FailState::NO_FAILURE:
NOTREACHED();
FALLTHROUGH;
case FailState::CANNOT_DOWNLOAD:
FALLTHROUGH;
case FailState::SERVER_NO_RANGE:
FALLTHROUGH;
case FailState::SERVER_CROSS_ORIGIN_REDIRECT:
FALLTHROUGH;
case FailState::FILE_FAILED:
FALLTHROUGH;
case FailState::FILE_HASH_MISMATCH:
string_id = IDS_DOWNLOAD_INTERRUPTED_STATUS;
}
return l10n_util::GetStringUTF16(string_id);
}