Commit 32528739 authored by Xing Liu's avatar Xing Liu Committed by Commit Bot

Download Home V2: Maps errors to OfflineItemStates.

This CL implements a code path to make Java side known how OfflineItem
should be resumed.

OfflineItemState::FAILED: Cannot resume, no further user actions.

OfflineItemState::INTERRUPTED: Can resume, but need to restart from
beginning. Should hook to retry button.

OfflineItemState::PENDING/PAUSE still uses
DownloadUtils.isDownloadPending/isDownloadPause, when download can be
resumed in the middle.


Bug: 895018,895013
Change-Id: I36a82cf3754093bfab85a623818d9e2392a6fc73
Reviewed-on: https://chromium-review.googlesource.com/c/1289677
Commit-Queue: Shakti Sahu <shaktisahu@chromium.org>
Reviewed-by: default avatarMin Qin <qinmin@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601713}
parent 64e2a6e7
......@@ -9,6 +9,7 @@ import android.graphics.Bitmap;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.chrome.browser.download.ui.DownloadFilter;
import org.chromium.components.download.DownloadState;
import org.chromium.components.download.ResumeMode;
import org.chromium.components.offline_items_collection.ContentId;
import org.chromium.components.offline_items_collection.FailState;
import org.chromium.components.offline_items_collection.LegacyHelpers;
......@@ -344,13 +345,25 @@ public final class DownloadInfo {
break;
case DownloadState.INTERRUPTED:
DownloadItem downloadItem = new DownloadItem(false, downloadInfo);
if (DownloadUtils.isDownloadPaused(downloadItem)) {
@ResumeMode
int resumeMode = DownloadUtils.getResumeMode(downloadInfo.getFailState());
if (resumeMode == ResumeMode.INVALID) {
// These are dead end states and no further user actions are needed.
offlineItem.state = OfflineItemState.FAILED;
} else if (resumeMode == ResumeMode.USER_RESTART) {
// Fail but can restart from the beginning. The UI should let the user to retry.
offlineItem.state = OfflineItemState.INTERRUPTED;
}
// TODO(xingliu): isDownloadPaused and isDownloadPending rely on isAutoResumable
// is set correctly in {@link DownloadSharedPreferenceEntry}. The states of
// notification UI and download home currently may not match. Also pending is
// related to Java side auto resumption on good network condition.
else if (DownloadUtils.isDownloadPaused(downloadItem)) {
offlineItem.state = OfflineItemState.PAUSED;
} else if (DownloadUtils.isDownloadPending(downloadItem)) {
offlineItem.state = OfflineItemState.PENDING;
} else if (downloadInfo.isResumable()) {
offlineItem.state = OfflineItemState.INTERRUPTED;
} else {
// Unknown failure state.
offlineItem.state = OfflineItemState.FAILED;
}
break;
......
......@@ -54,6 +54,7 @@ import org.chromium.chrome.browser.tabmodel.document.TabDelegate;
import org.chromium.chrome.browser.util.ConversionUtils;
import org.chromium.chrome.browser.util.IntentUtils;
import org.chromium.components.download.DownloadState;
import org.chromium.components.download.ResumeMode;
import org.chromium.components.feature_engagement.EventConstants;
import org.chromium.components.feature_engagement.Tracker;
import org.chromium.components.offline_items_collection.ContentId;
......@@ -946,6 +947,17 @@ public class DownloadUtils {
}
}
/**
* Get the resume mode based on the current fail state, to distinguish the case where download
* cannot be resumed at all or can be resumed in the middle, or should be restarted from the
* beginning.
* @param failState Why the download failed.
* @return The resume mode for the current fail state.
*/
public static @ResumeMode int getResumeMode(@FailState int failState) {
return nativeGetResumeMode(failState);
}
/**
* Query the Download backends about whether a download is paused.
*
......@@ -1174,4 +1186,5 @@ public class DownloadUtils {
}
private static native String nativeGetFailStateMessage(@FailState int failState);
private static native int nativeGetResumeMode(@FailState int failState);
}
......@@ -7,6 +7,7 @@
#include "base/android/jni_string.h"
#include "chrome/browser/download/offline_item_utils.h"
#include "chrome/grit/generated_resources.h"
#include "components/download/public/common/download_utils.h"
#include "jni/DownloadUtils_jni.h"
#include "ui/base/l10n/l10n_util.h"
......@@ -24,6 +25,16 @@ static ScopedJavaLocalRef<jstring> JNI_DownloadUtils_GetFailStateMessage(
return ConvertUTF16ToJavaString(env, message);
}
static jint JNI_DownloadUtils_GetResumeMode(
JNIEnv* env,
const base::android::JavaParamRef<jclass>& jcaller,
jint failState) {
auto reason = OfflineItemUtils::ConvertFailStateToDownloadInterruptReason(
static_cast<offline_items_collection::FailState>(failState));
return static_cast<jint>(download::GetDownloadResumeMode(
reason, false /* restart_required */, true /* user_action_required */));
}
// static
base::FilePath DownloadUtils::GetUriStringForPath(
const base::FilePath& file_path) {
......
......@@ -5,6 +5,7 @@
#include "chrome/browser/download/offline_item_utils.h"
#include "chrome/grit/generated_resources.h"
#include "components/download/public/common/download_utils.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"
......@@ -139,66 +140,32 @@ bool OfflineItemUtils::IsDownload(const ContentId& id) {
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;
return offline_items_collection::FailState::NO_FAILURE;
#define INTERRUPT_REASON(name, value) \
case download::DOWNLOAD_INTERRUPT_REASON_##name: \
return offline_items_collection::FailState::name;
#include "components/download/public/common/download_interrupt_reason_values.h"
#undef INTERRUPT_REASON
}
}
// static
download::DownloadInterruptReason
OfflineItemUtils::ConvertFailStateToDownloadInterruptReason(
offline_items_collection::FailState fail_state) {
switch (fail_state) {
case offline_items_collection::FailState::NO_FAILURE:
// These two enum values are not converted from download interrupted reason,
// maps them to none error.
case offline_items_collection::FailState::CANNOT_DOWNLOAD:
case offline_items_collection::FailState::NETWORK_INSTABILITY:
return download::DOWNLOAD_INTERRUPT_REASON_NONE;
#define INTERRUPT_REASON(name, value) \
case offline_items_collection::FailState::name: \
return download::DOWNLOAD_INTERRUPT_REASON_##name;
#include "components/download/public/common/download_interrupt_reason_values.h"
#undef INTERRUPT_REASON
}
}
......
......@@ -30,6 +30,11 @@ class OfflineItemUtils {
ConvertDownloadInterruptReasonToFailState(
download::DownloadInterruptReason reason);
// Converts offline_items_collection::FailState to DownloadInterruptReason.
static download::DownloadInterruptReason
ConvertFailStateToDownloadInterruptReason(
offline_items_collection::FailState fail_state);
// Gets the short text to display for a offline_items_collection::FailState.
static base::string16 GetFailStateMessage(
offline_items_collection::FailState fail_state);
......
......@@ -98,6 +98,7 @@ if (is_android) {
java_cpp_enum("jni_enums") {
sources = [
"download_item.h",
"resume_mode.h",
]
}
}
......
......@@ -9,6 +9,8 @@
// Used by DownloadItemImpl and UKM metrics.
namespace download {
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.download
enum class ResumeMode {
INVALID = 0,
IMMEDIATE_CONTINUE,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment