Commit beaa7f7a authored by John Abd-El-Malek's avatar John Abd-El-Malek Committed by Chromium LUCI CQ

Add Navigation.disableNetworkErrorAutoReload so that embedders can disable...

Add Navigation.disableNetworkErrorAutoReload so that embedders can disable auto reload for user initiated navigations like back/forward.

Bug: 1163455
Change-Id: I9ff1b6199493d53457d9fc0be6e9200e60974567
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2613353Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: John Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#841246}
parent f3dd2d31
...@@ -661,11 +661,26 @@ ContentBrowserClientImpl::CreateThrottlesForNavigation( ...@@ -661,11 +661,26 @@ ContentBrowserClientImpl::CreateThrottlesForNavigation(
content::NavigationHandle* handle) { content::NavigationHandle* handle) {
std::vector<std::unique_ptr<content::NavigationThrottle>> throttles; std::vector<std::unique_ptr<content::NavigationThrottle>> throttles;
TabImpl* tab = TabImpl::FromWebContents(handle->GetWebContents());
NavigationControllerImpl* navigation_controller = nullptr;
if (tab) {
navigation_controller =
static_cast<NavigationControllerImpl*>(tab->GetNavigationController());
}
if (handle->IsInMainFrame()) { if (handle->IsInMainFrame()) {
NavigationUIDataImpl* navigation_ui_data = NavigationUIDataImpl* navigation_ui_data =
static_cast<NavigationUIDataImpl*>(handle->GetNavigationUIData()); static_cast<NavigationUIDataImpl*>(handle->GetNavigationUIData());
NavigationImpl* navigation_impl = nullptr;
if (navigation_controller) {
navigation_impl =
navigation_controller->GetNavigationImplFromHandle(handle);
}
if ((!navigation_ui_data || if ((!navigation_ui_data ||
!navigation_ui_data->disable_network_error_auto_reload()) && !navigation_ui_data->disable_network_error_auto_reload()) &&
(!navigation_impl ||
!navigation_impl->disable_network_error_auto_reload()) &&
IsNetworkErrorAutoReloadEnabled()) { IsNetworkErrorAutoReloadEnabled()) {
auto auto_reload_throttle = auto auto_reload_throttle =
error_page::NetErrorAutoReloader::MaybeCreateThrottleFor(handle); error_page::NetErrorAutoReloader::MaybeCreateThrottleFor(handle);
...@@ -688,11 +703,8 @@ ContentBrowserClientImpl::CreateThrottlesForNavigation( ...@@ -688,11 +703,8 @@ ContentBrowserClientImpl::CreateThrottlesForNavigation(
// The next highest priority throttle *must* be this as it's responsible for // The next highest priority throttle *must* be this as it's responsible for
// calling to NavigationController for certain events. // calling to NavigationController for certain events.
TabImpl* tab = TabImpl::FromWebContents(handle->GetWebContents());
if (tab) { if (tab) {
auto throttle = auto throttle = navigation_controller->CreateNavigationThrottle(handle);
static_cast<NavigationControllerImpl*>(tab->GetNavigationController())
->CreateNavigationThrottle(handle);
if (throttle) if (throttle)
throttles.push_back(std::move(throttle)); throttles.push_back(std::move(throttle));
} }
......
...@@ -72,9 +72,12 @@ class ErrorPageReloadBrowserTest : public ErrorPageBrowserTest { ...@@ -72,9 +72,12 @@ class ErrorPageReloadBrowserTest : public ErrorPageBrowserTest {
WARN_UNUSED_RESULT { WARN_UNUSED_RESULT {
content::TestNavigationManager navigation(web_contents(), url); content::TestNavigationManager navigation(web_contents(), url);
NavigationController::NavigateParams params; NavigationController::NavigateParams params;
params.disable_network_error_auto_reload = auto* navigation_controller = shell()->tab()->GetNavigationController();
disable_network_error_auto_reload; std::unique_ptr<DisableAutoReload> disable_auto_reload;
shell()->tab()->GetNavigationController()->Navigate(url, params); if (disable_network_error_auto_reload)
disable_auto_reload =
std::make_unique<DisableAutoReload>(navigation_controller);
navigation_controller->Navigate(url, params);
navigation.WaitForNavigationFinished(); navigation.WaitForNavigationFinished();
return navigation.was_successful(); return navigation.was_successful();
} }
...@@ -98,6 +101,23 @@ class ErrorPageReloadBrowserTest : public ErrorPageBrowserTest { ...@@ -98,6 +101,23 @@ class ErrorPageReloadBrowserTest : public ErrorPageBrowserTest {
} }
private: private:
class DisableAutoReload : public NavigationObserver {
public:
explicit DisableAutoReload(NavigationController* controller)
: controller_(controller) {
controller_->AddObserver(this);
}
~DisableAutoReload() override { controller_->RemoveObserver(this); }
// NavigationObserver implementation:
void NavigationStarted(Navigation* navigation) override {
navigation->DisableNetworkErrorAutoReload();
}
private:
NavigationController* controller_;
};
base::test::ScopedFeatureList feature_list_; base::test::ScopedFeatureList feature_list_;
}; };
......
...@@ -193,6 +193,13 @@ public final class NavigationImpl extends INavigation.Stub { ...@@ -193,6 +193,13 @@ public final class NavigationImpl extends INavigation.Stub {
return NavigationImplJni.get().isServedFromBackForwardCache(mNativeNavigationImpl); return NavigationImplJni.get().isServedFromBackForwardCache(mNativeNavigationImpl);
} }
@Override
public void disableNetworkErrorAutoReload() {
if (!NavigationImplJni.get().disableNetworkErrorAutoReload(mNativeNavigationImpl)) {
throw new IllegalStateException();
}
}
public void setIntentLaunched() { public void setIntentLaunched() {
mIntentLaunched = true; mIntentLaunched = true;
} }
...@@ -255,5 +262,6 @@ public final class NavigationImpl extends INavigation.Stub { ...@@ -255,5 +262,6 @@ public final class NavigationImpl extends INavigation.Stub {
boolean isPageInitiated(long nativeNavigationImpl); boolean isPageInitiated(long nativeNavigationImpl);
boolean isReload(long nativeNavigationImpl); boolean isReload(long nativeNavigationImpl);
boolean isServedFromBackForwardCache(long nativeNavigationImpl); boolean isServedFromBackForwardCache(long nativeNavigationImpl);
boolean disableNetworkErrorAutoReload(long nativeNavigationImpl);
} }
} }
...@@ -38,4 +38,5 @@ interface INavigation { ...@@ -38,4 +38,5 @@ interface INavigation {
boolean isUserDecidingIntentLaunch() = 14; boolean isUserDecidingIntentLaunch() = 14;
boolean isKnownProtocol() = 15; boolean isKnownProtocol() = 15;
boolean isServedFromBackForwardCache() = 16; boolean isServedFromBackForwardCache() = 16;
void disableNetworkErrorAutoReload() = 17;
} }
...@@ -302,11 +302,6 @@ void NavigationControllerImpl::Navigate( ...@@ -302,11 +302,6 @@ void NavigationControllerImpl::Navigate(
std::make_unique<content::NavigationController::LoadURLParams>(url); std::make_unique<content::NavigationController::LoadURLParams>(url);
load_params->should_replace_current_entry = load_params->should_replace_current_entry =
params.should_replace_current_entry; params.should_replace_current_entry;
if (params.disable_network_error_auto_reload) {
auto data = std::make_unique<NavigationUIDataImpl>();
data->set_disable_network_error_auto_reload(true);
load_params->navigation_ui_data = std::move(data);
}
if (params.enable_auto_play) if (params.enable_auto_play)
load_params->was_activated = content::mojom::WasActivatedOption::kYes; load_params->was_activated = content::mojom::WasActivatedOption::kYes;
...@@ -396,6 +391,7 @@ void NavigationControllerImpl::DidStartNavigation( ...@@ -396,6 +391,7 @@ void NavigationControllerImpl::DidStartNavigation(
base::AutoReset<NavigationImpl*> auto_reset(&navigation_starting_, base::AutoReset<NavigationImpl*> auto_reset(&navigation_starting_,
navigation); navigation);
navigation->set_safe_to_set_request_headers(true); navigation->set_safe_to_set_request_headers(true);
navigation->set_safe_to_disable_network_error_auto_reload(true);
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
// Desktop mode and per-navigation UA use the same mechanism and so don't // Desktop mode and per-navigation UA use the same mechanism and so don't
...@@ -434,6 +430,7 @@ void NavigationControllerImpl::DidStartNavigation( ...@@ -434,6 +430,7 @@ void NavigationControllerImpl::DidStartNavigation(
observer.NavigationStarted(navigation); observer.NavigationStarted(navigation);
navigation->set_safe_to_set_user_agent(false); navigation->set_safe_to_set_user_agent(false);
navigation->set_safe_to_set_request_headers(false); navigation->set_safe_to_set_request_headers(false);
navigation->set_safe_to_disable_network_error_auto_reload(false);
} }
void NavigationControllerImpl::DidRedirectNavigation( void NavigationControllerImpl::DidRedirectNavigation(
......
...@@ -94,6 +94,13 @@ jboolean NavigationImpl::SetUserAgentString( ...@@ -94,6 +94,13 @@ jboolean NavigationImpl::SetUserAgentString(
return true; return true;
} }
jboolean NavigationImpl::DisableNetworkErrorAutoReload(JNIEnv* env) {
if (!safe_to_disable_network_error_auto_reload_)
return false;
DisableNetworkErrorAutoReload();
return true;
}
void NavigationImpl::SetResponse( void NavigationImpl::SetResponse(
std::unique_ptr<embedder_support::WebResourceResponse> response) { std::unique_ptr<embedder_support::WebResourceResponse> response) {
response_ = std::move(response); response_ = std::move(response);
...@@ -218,6 +225,11 @@ void NavigationImpl::SetUserAgentString(const std::string& value) { ...@@ -218,6 +225,11 @@ void NavigationImpl::SetUserAgentString(const std::string& value) {
set_user_agent_string_called_ = true; set_user_agent_string_called_ = true;
} }
void NavigationImpl::DisableNetworkErrorAutoReload() {
DCHECK(safe_to_disable_network_error_auto_reload_);
disable_network_error_auto_reload_ = true;
}
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
static jboolean JNI_NavigationImpl_IsValidRequestHeaderName( static jboolean JNI_NavigationImpl_IsValidRequestHeaderName(
JNIEnv* env, JNIEnv* env,
......
...@@ -49,10 +49,18 @@ class NavigationImpl : public Navigation { ...@@ -49,10 +49,18 @@ class NavigationImpl : public Navigation {
safe_to_set_user_agent_ = value; safe_to_set_user_agent_ = value;
} }
void set_safe_to_disable_network_error_auto_reload(bool value) {
safe_to_disable_network_error_auto_reload_ = value;
}
void set_was_stopped() { was_stopped_ = true; } void set_was_stopped() { was_stopped_ = true; }
bool set_user_agent_string_called() { return set_user_agent_string_called_; } bool set_user_agent_string_called() { return set_user_agent_string_called_; }
bool disable_network_error_auto_reload() {
return disable_network_error_auto_reload_;
}
void SetParamsToLoadWhenSafe( void SetParamsToLoadWhenSafe(
std::unique_ptr<content::NavigationController::LoadURLParams> params); std::unique_ptr<content::NavigationController::LoadURLParams> params);
std::unique_ptr<content::NavigationController::LoadURLParams> std::unique_ptr<content::NavigationController::LoadURLParams>
...@@ -83,6 +91,7 @@ class NavigationImpl : public Navigation { ...@@ -83,6 +91,7 @@ class NavigationImpl : public Navigation {
jboolean IsServedFromBackForwardCache(JNIEnv* env) { jboolean IsServedFromBackForwardCache(JNIEnv* env) {
return IsServedFromBackForwardCache(); return IsServedFromBackForwardCache();
} }
jboolean DisableNetworkErrorAutoReload(JNIEnv* env);
void SetResponse( void SetResponse(
std::unique_ptr<embedder_support::WebResourceResponse> response); std::unique_ptr<embedder_support::WebResourceResponse> response);
...@@ -107,6 +116,7 @@ class NavigationImpl : public Navigation { ...@@ -107,6 +116,7 @@ class NavigationImpl : public Navigation {
void SetRequestHeader(const std::string& name, void SetRequestHeader(const std::string& name,
const std::string& value) override; const std::string& value) override;
void SetUserAgentString(const std::string& value) override; void SetUserAgentString(const std::string& value) override;
void DisableNetworkErrorAutoReload() override;
bool IsPageInitiated() override; bool IsPageInitiated() override;
bool IsReload() override; bool IsReload() override;
bool IsServedFromBackForwardCache() override; bool IsServedFromBackForwardCache() override;
...@@ -134,6 +144,11 @@ class NavigationImpl : public Navigation { ...@@ -134,6 +144,11 @@ class NavigationImpl : public Navigation {
// Whether SetUserAgentString was called. // Whether SetUserAgentString was called.
bool set_user_agent_string_called_ = false; bool set_user_agent_string_called_ = false;
// Whether DisableNetworkErrorAutoReload is allowed at this time.
bool safe_to_disable_network_error_auto_reload_ = false;
bool disable_network_error_auto_reload_ = false;
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
base::android::ScopedJavaGlobalRef<jobject> java_navigation_; base::android::ScopedJavaGlobalRef<jobject> java_navigation_;
std::unique_ptr<embedder_support::WebResourceResponse> response_; std::unique_ptr<embedder_support::WebResourceResponse> response_;
......
...@@ -64,7 +64,10 @@ public class NavigateParams { ...@@ -64,7 +64,10 @@ public class NavigateParams {
/** /**
* Disables auto-reload for this navigation if the network is down and comes back later. * Disables auto-reload for this navigation if the network is down and comes back later.
* Auto-reload is enabled by default. * Auto-reload is enabled by default. This is deprecated as of 89, instead use
* {@link Navigation#disableNetworkErrorAutoReload} which works for both embedder-initiated
* navigations and also user-initiated navigations (such as back or forward). Auto-reload
* is disabled if either method is called.
*/ */
@NonNull @NonNull
public Builder disableNetworkErrorAutoReload() { public Builder disableNetworkErrorAutoReload() {
......
...@@ -254,6 +254,28 @@ public class Navigation extends IClientNavigation.Stub { ...@@ -254,6 +254,28 @@ public class Navigation extends IClientNavigation.Stub {
} }
} }
/**
* Disables auto-reload for this navigation if the network is down and comes back later.
* Auto-reload is enabled by default. This method may only be called from
* {@link NavigationCallback.onNavigationStarted}.
*
* @throws IllegalStateException If not called during start.
*
* @since 89
*/
public void disableNetworkErrorAutoReload() {
ThreadCheck.ensureOnUiThread();
if (WebLayer.shouldPerformVersionChecks()
&& WebLayer.getSupportedMajorVersionInternal() < 89) {
throw new UnsupportedOperationException();
}
try {
mNavigationImpl.disableNetworkErrorAutoReload();
} catch (RemoteException e) {
throw new APICallException(e);
}
}
/** /**
* Sets the user-agent string that applies to the current navigation. This user-agent is not * Sets the user-agent string that applies to the current navigation. This user-agent is not
* sticky, it applies to this navigation only (and any redirects or resources that are loaded). * sticky, it applies to this navigation only (and any redirects or resources that are loaded).
......
...@@ -119,6 +119,11 @@ class Navigation { ...@@ -119,6 +119,11 @@ class Navigation {
// SetRequestHeader(). // SetRequestHeader().
virtual void SetUserAgentString(const std::string& value) = 0; virtual void SetUserAgentString(const std::string& value) = 0;
// Disables auto-reload for this navigation if the network is down and comes
// back later. Auto-reload is enabled by default. This function may only be
// called from NavigationObserver::NavigationStarted().
virtual void DisableNetworkErrorAutoReload() = 0;
// Whether the navigation was initiated by the page. Examples of // Whether the navigation was initiated by the page. Examples of
// page-initiated navigations include: // page-initiated navigations include:
// * <a> link click // * <a> link click
......
...@@ -19,7 +19,6 @@ class NavigationController { ...@@ -19,7 +19,6 @@ class NavigationController {
// |NavigationController::LoadURLParams|. // |NavigationController::LoadURLParams|.
struct NavigateParams { struct NavigateParams {
bool should_replace_current_entry = false; bool should_replace_current_entry = false;
bool disable_network_error_auto_reload = false;
bool enable_auto_play = false; bool enable_auto_play = false;
}; };
......
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