Commit b0fe12b9 authored by jianli's avatar jianli Committed by Commit bot

Enable download page action for error page

If error page shows "DOWNLOAD PAGE LATER" button, we should also
enable download page action.

BUG=675225

Patch

Review-Url: https://codereview.chromium.org/2588253002
Cr-Commit-Position: refs/heads/master@{#443104}
parent 998d2477
......@@ -38,6 +38,8 @@ import org.chromium.chrome.browser.download.ui.BackendProvider;
import org.chromium.chrome.browser.download.ui.BackendProvider.DownloadDelegate;
import org.chromium.chrome.browser.download.ui.DownloadFilter;
import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper;
import org.chromium.chrome.browser.offlinepages.ClientId;
import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBridge;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
......@@ -187,10 +189,21 @@ public class DownloadUtils {
* @param context Context to pull resources from.
*/
public static void downloadOfflinePage(Context context, Tab tab) {
final OfflinePageDownloadBridge bridge = new OfflinePageDownloadBridge(tab.getProfile());
bridge.startDownload(tab);
bridge.destroy();
DownloadUtils.recordDownloadPageMetrics(tab);
if (tab.isShowingErrorPage()) {
// The download needs to be scheduled to happen at later time due to current network
// error.
ClientId clientId = ClientId.createGuidClientIdForNamespace(
OfflinePageBridge.ASYNC_NAMESPACE);
final OfflinePageBridge bridge = OfflinePageBridge.getForProfile(tab.getProfile());
bridge.savePageLater(tab.getUrl(), clientId, true /* userRequested */);
} else {
// Otherwise, the download can be started immediately.
final OfflinePageDownloadBridge bridge =
new OfflinePageDownloadBridge(tab.getProfile());
bridge.startDownload(tab);
bridge.destroy();
DownloadUtils.recordDownloadPageMetrics(tab);
}
}
/**
......@@ -201,13 +214,15 @@ public class DownloadUtils {
public static boolean isAllowedToDownloadPage(Tab tab) {
if (tab == null) return false;
// Only allow HTTP and HTTPS pages, as that is these are the only scenarios supported by the
// background/offline page saving.
if (!tab.getUrl().startsWith(UrlConstants.HTTP_SCHEME)
&& !tab.getUrl().startsWith(UrlConstants.HTTPS_SCHEME)) {
return false;
// Check if the page url is supported for saving. Only HTTP and HTTPS pages are allowed.
if (!OfflinePageBridge.canSavePage(tab.getUrl())) return false;
// Download will only be allowed for the error page if download button is shown in the page.
if (tab.isShowingErrorPage()) {
final OfflinePageBridge bridge = OfflinePageBridge.getForProfile(tab.getProfile());
return bridge.isShowingDownloadButtonInErrorPage(tab.getWebContents());
}
if (tab.isShowingErrorPage()) return false;
if (tab.isShowingInterstitialPage()) return false;
// Don't allow re-downloading the currently displayed offline page.
......
......@@ -24,6 +24,7 @@ import java.util.Set;
*/
@JNINamespace("offline_pages::android")
public class OfflinePageBridge {
public static final String ASYNC_NAMESPACE = "async_loading";
public static final String BOOKMARK_NAMESPACE = "bookmark";
public static final String SHARE_NAMESPACE = "share";
......@@ -398,6 +399,14 @@ public class OfflinePageBridge {
return nativeIsShowingOfflinePreview(mNativeOfflinePageBridge, webContents);
}
/**
* @return True if download button is being shown in the error page.
* @param webContents Contents of the page to check.
*/
public boolean isShowingDownloadButtonInErrorPage(WebContents webContents) {
return nativeIsShowingDownloadButtonInErrorPage(mNativeOfflinePageBridge, webContents);
}
private static class CheckPagesExistOfflineCallbackInternal {
private Callback<Set<String>> mCallback;
......@@ -525,4 +534,6 @@ public class OfflinePageBridge {
long nativeOfflinePageBridge, WebContents webContents);
private native boolean nativeIsShowingOfflinePreview(
long nativeOfflinePageBridge, WebContents webContents);
private native boolean nativeIsShowingDownloadButtonInErrorPage(
long nativeOfflinePageBridge, WebContents webContents);
}
......@@ -510,6 +510,18 @@ jboolean OfflinePageBridge::IsShowingOfflinePreview(
return offline_pages::OfflinePageUtils::IsShowingOfflinePreview(web_contents);
}
jboolean OfflinePageBridge::IsShowingDownloadButtonInErrorPage(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
const JavaParamRef<jobject>& j_web_contents) {
content::WebContents* web_contents =
content::WebContents::FromJavaWebContents(j_web_contents);
if (!web_contents)
return false;
return offline_pages::OfflinePageUtils::IsShowingDownloadButtonInErrorPage(
web_contents);
}
void OfflinePageBridge::GetRequestsInQueue(
JNIEnv* env,
const JavaParamRef<jobject>& obj,
......
......@@ -104,6 +104,11 @@ class OfflinePageBridge : public OfflinePageModel::Observer,
const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jobject>& j_web_contents);
jboolean IsShowingDownloadButtonInErrorPage(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jobject>& j_web_contents);
base::android::ScopedJavaLocalRef<jstring> GetOfflinePageHeaderForReload(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
......
......@@ -18,6 +18,7 @@
#include "chrome/browser/android/offline_pages/offline_page_tab_helper.h"
#include "chrome/browser/android/offline_pages/request_coordinator_factory.h"
#include "chrome/browser/android/tab_android.h"
#include "chrome/browser/net/net_error_tab_helper.h"
#include "components/offline_pages/core/background/request_coordinator.h"
#include "components/offline_pages/core/background/save_page_request.h"
#include "components/offline_pages/core/client_namespace_constants.h"
......@@ -138,6 +139,14 @@ bool OfflinePageUtils::IsShowingOfflinePreview(
return tab_helper && tab_helper->IsShowingOfflinePreview();
}
// static
bool OfflinePageUtils::IsShowingDownloadButtonInErrorPage(
content::WebContents* web_contents) {
chrome_browser_net::NetErrorTabHelper* tab_helper =
chrome_browser_net::NetErrorTabHelper::FromWebContents(web_contents);
return tab_helper && tab_helper->is_showing_download_button_in_error_page();
}
// static
bool OfflinePageUtils::GetTabId(content::WebContents* web_contents,
int* tab_id) {
......
......@@ -60,6 +60,10 @@ class OfflinePageUtils {
// Returns true if the offline page is shown for previewing purpose.
static bool IsShowingOfflinePreview(content::WebContents* web_contents);
// Returns true if download button is shown in the error page.
static bool IsShowingDownloadButtonInErrorPage(
content::WebContents* web_contents);
// Gets an Android Tab ID from a tab containing |web_contents|. Returns false,
// when tab is not available. Returns true otherwise and sets |tab_id| to the
// ID of the tab.
......
......@@ -130,6 +130,9 @@ void NetErrorTabHelper::DidFinishNavigation(
!navigation_handle->IsErrorPage()) {
dns_error_active_ = false;
dns_error_page_committed_ = false;
#if defined(OS_ANDROID)
is_showing_download_button_in_error_page_ = false;
#endif // defined(OS_ANDROID)
}
}
......@@ -141,7 +144,10 @@ bool NetErrorTabHelper::OnMessageReceived(
#if defined(OS_ANDROID)
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(NetErrorTabHelper, message)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DownloadPageLater, DownloadPageLater)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DownloadPageLater,
OnDownloadPageLater)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_SetIsShowingDownloadButtonInErrorPage,
OnSetIsShowingDownloadButtonInErrorPage)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
......@@ -157,6 +163,9 @@ NetErrorTabHelper::NetErrorTabHelper(WebContents* contents)
is_error_page_(false),
dns_error_active_(false),
dns_error_page_committed_(false),
#if defined(OS_ANDROID)
is_showing_download_button_in_error_page_(false),
#endif // defined(OS_ANDROID)
dns_probe_status_(error_page::DNS_PROBE_POSSIBLE),
weak_factory_(this) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
......@@ -209,7 +218,7 @@ void NetErrorTabHelper::OnDnsProbeFinished(DnsProbeStatus result) {
}
#if defined(OS_ANDROID)
void NetErrorTabHelper::DownloadPageLater() {
void NetErrorTabHelper::OnDownloadPageLater() {
// Makes sure that this is coming from an error page.
content::NavigationEntry* entry =
web_contents()->GetController().GetLastCommittedEntry();
......@@ -223,6 +232,11 @@ void NetErrorTabHelper::DownloadPageLater() {
DownloadPageLaterHelper(url);
}
void NetErrorTabHelper::OnSetIsShowingDownloadButtonInErrorPage(
bool is_showing_download_button) {
is_showing_download_button_in_error_page_ = is_showing_download_button;
}
#endif // defined(OS_ANDROID)
void NetErrorTabHelper::InitializePref(WebContents* contents) {
......
......@@ -51,6 +51,12 @@ class NetErrorTabHelper
dns_probe_status_snoop_callback_ = dns_probe_status_snoop_callback;
}
#if defined(OS_ANDROID)
bool is_showing_download_button_in_error_page() const {
return is_showing_download_button_in_error_page_;
}
#endif // defined(OS_ANDROID)
// content::WebContentsObserver implementation.
void RenderFrameCreated(content::RenderFrameHost* render_frame_host) override;
void DidStartNavigation(
......@@ -78,7 +84,8 @@ class NetErrorTabHelper
}
#if defined(OS_ANDROID)
void DownloadPageLater();
void OnDownloadPageLater();
void OnSetIsShowingDownloadButtonInErrorPage(bool is_showing_download_button);
#endif // defined(OS_ANDROID)
private:
......@@ -115,6 +122,11 @@ class NetErrorTabHelper
// is true. (This should never be true if |dns_error_active_| is false.)
bool dns_error_page_committed_;
#if defined(OS_ANDROID)
// True if download button is being shown when the error page commits.
bool is_showing_download_button_in_error_page_;
#endif // defined(OS_ANDROID)
// The status of a DNS probe that may or may not have started or finished.
// Since the renderer can change out from under the helper (in cross-process
// navigations), it re-sends the status whenever an error page commits.
......
......@@ -44,7 +44,7 @@ class TestNetErrorTabHelper : public NetErrorTabHelper {
int mock_sent_count() const { return mock_sent_count_; }
#if defined(OS_ANDROID)
using NetErrorTabHelper::DownloadPageLater;
using NetErrorTabHelper::OnDownloadPageLater;
const GURL& download_page_later_url() const {
return download_page_later_url_;
......@@ -175,7 +175,7 @@ class NetErrorTabHelperTest : public ChromeRenderViewHostTestHarness {
bool succeeded) {
GURL url(url_string);
LoadURL(url, succeeded);
tab_helper()->DownloadPageLater();
tab_helper()->OnDownloadPageLater();
EXPECT_EQ(0, tab_helper()->times_download_page_later_invoked());
}
#endif
......@@ -376,7 +376,7 @@ TEST_F(NetErrorTabHelperTest, NoDiagnosticsForNonHttpSchemes) {
TEST_F(NetErrorTabHelperTest, DownloadPageLater) {
GURL url("http://somewhere:123/");
LoadURL(url, false /*succeeded*/);
tab_helper()->DownloadPageLater();
tab_helper()->OnDownloadPageLater();
EXPECT_EQ(url, tab_helper()->download_page_later_url());
EXPECT_EQ(1, tab_helper()->times_download_page_later_invoked());
}
......@@ -384,7 +384,7 @@ TEST_F(NetErrorTabHelperTest, DownloadPageLater) {
TEST_F(NetErrorTabHelperTest, NoDownloadPageLaterOnNonErrorPage) {
GURL url("http://somewhere:123/");
LoadURL(url, true /*succeeded*/);
tab_helper()->DownloadPageLater();
tab_helper()->OnDownloadPageLater();
EXPECT_EQ(0, tab_helper()->times_download_page_later_invoked());
}
......
......@@ -341,6 +341,11 @@ IPC_MESSAGE_ROUTED5(ChromeViewMsg_SetNavigationCorrectionInfo,
// Message sent from the renderer to the browser to schedule to download the
// page at a later time.
IPC_MESSAGE_ROUTED0(ChromeViewHostMsg_DownloadPageLater)
// Message sent from the renderer to the browser to indicate if download button
// is being shown in error page.
IPC_MESSAGE_ROUTED1(ChromeViewHostMsg_SetIsShowingDownloadButtonInErrorPage,
bool /* showing download button */)
#endif // defined(OS_ANDROID)
//-----------------------------------------------------------------------------
......
......@@ -340,6 +340,14 @@ void NetErrorHelper::DownloadPageLater() {
#endif // defined(OS_ANDROID)
}
void NetErrorHelper::SetIsShowingDownloadButton(bool show) {
#if defined(OS_ANDROID)
render_frame()->Send(
new ChromeViewHostMsg_SetIsShowingDownloadButtonInErrorPage(
render_frame()->GetRoutingID(), show));
#endif // defined(OS_ANDROID)
}
void NetErrorHelper::OnNetErrorInfo(int status_num) {
DCHECK(status_num >= 0 && status_num < error_page::DNS_PROBE_MAX);
......
......@@ -112,6 +112,7 @@ class NetErrorHelper
void LoadPageFromCache(const GURL& page_url) override;
void DiagnoseError(const GURL& page_url) override;
void DownloadPageLater() override;
void SetIsShowingDownloadButton(bool show) override;
void OnNetErrorInfo(int status);
void OnSetNavigationCorrectionInfo(const GURL& navigation_correction_url,
......
......@@ -658,6 +658,9 @@ void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) {
RecordEvent(NETWORK_ERROR_PAGE_CACHED_COPY_BUTTON_SHOWN);
}
delegate_->SetIsShowingDownloadButton(
committed_error_page_info_->download_button_in_page);
delegate_->EnablePageHelperFunctions();
if (committed_error_page_info_->needs_load_navigation_corrections) {
......
......@@ -110,6 +110,9 @@ class NetErrorHelperCore {
// Schedule to download the page at a later time.
virtual void DownloadPageLater() = 0;
// Inform that download button is being shown in the error page.
virtual void SetIsShowingDownloadButton(bool show) = 0;
protected:
virtual ~Delegate() {}
};
......
......@@ -435,6 +435,8 @@ class NetErrorHelperCoreTest : public testing::Test,
download_count_++;
}
void SetIsShowingDownloadButton(bool show) override {}
void SendTrackingRequest(const GURL& tracking_url,
const std::string& tracking_request_body) override {
last_tracking_url_ = tracking_url;
......
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