1 // Copyright 2019 Samsung Electronics. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "browser/navigation_throttle_efl.h"
7 #include "base/functional/bind.h"
8 #include "common/navigation_policy_params.h"
9 #include "common/web_contents_utils.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/navigation_handle.h"
12 #include "eweb_view.h"
13 #include "third_party/blink/public/platform/web_string.h"
14 #include "third_party/blink/public/web/web_navigation_type.h"
16 #if BUILDFLAG(IS_TIZEN_TV)
17 #include "common/application_type.h"
22 static blink::WebNavigationType GetNavigationTypeFromPageTransition(
23 const ui::PageTransition& transition,
25 switch (ui::PageTransitionStripQualifier(transition)) {
26 case ui::PAGE_TRANSITION_LINK:
27 if (transition & ui::PAGE_TRANSITION_FORWARD_BACK)
28 return blink::kWebNavigationTypeBackForward;
29 if (transition & ui::PAGE_TRANSITION_FROM_API)
30 return blink::kWebNavigationTypeOther;
31 return blink::kWebNavigationTypeLinkClicked;
32 case ui::PAGE_TRANSITION_FORM_SUBMIT:
33 return ((transition & ui::PAGE_TRANSITION_FORWARD_BACK) || is_reload)
34 ? blink::kWebNavigationTypeFormResubmittedBackForward
35 : blink::kWebNavigationTypeFormSubmitted;
36 case ui::PAGE_TRANSITION_RELOAD:
37 return blink::kWebNavigationTypeReload;
39 return blink::kWebNavigationTypeOther;
42 return blink::kWebNavigationTypeOther;
45 NavigationThrottleEfl::NavigationThrottleEfl(
46 NavigationHandle* navigation_handle)
47 : NavigationThrottle(navigation_handle), weak_factory_(this) {}
49 NavigationThrottleEfl::~NavigationThrottleEfl() = default;
51 NavigationThrottle::ThrottleCheckResult
52 NavigationThrottleEfl::WillStartRequest() {
53 return HandleNavigation(false /* is_redirect */);
56 NavigationThrottle::ThrottleCheckResult
57 NavigationThrottleEfl::WillRedirectRequest() {
58 return HandleNavigation(true /* is_redirect */);
61 NavigationThrottle::ThrottleCheckResult
62 NavigationThrottleEfl::WillFailRequest() {
63 auto* handle = navigation_handle();
65 web_contents_utils::WebViewFromWebContents(handle->GetWebContents());
66 if (handle->IsInMainFrame() && web_view) {
67 int error_code = handle->GetNetErrorCode();
68 web_view->InvokeLoadError(handle->GetURL(), error_code,
69 error_code == net::ERR_ABORTED);
70 // If app invoke load error page callback, means app want to display error
71 // page by itself. Provide detail error info and get customer error page
73 if (web_view->IsLoadErrorPageCallbackSet()) {
74 const char* error_page = web_view->InvokeViewLoadErrorPageCallback(
75 handle->GetURL(), error_code, error_code == net::ERR_ABORTED);
77 LOG(ERROR) << "Already get customer error page";
78 // Currently return result with action NavigationThrottle::CANCEL, error
79 // code and error_page.
80 // TODO: Consider NavigationThrottle::CANCEL is suitable in here or not.
81 return content::NavigationThrottle::ThrottleCheckResult(
82 content::NavigationThrottle::CANCEL, handle->GetNetErrorCode(),
83 absl::make_optional(error_page));
86 #if BUILDFLAG(IS_TIZEN_TV)
87 // In VD tizen, WebBrowser will load error page by itself.
89 return NavigationThrottle::CANCEL_AND_IGNORE;
92 return NavigationThrottle::PROCEED;
95 const char* NavigationThrottleEfl::GetNameForLogging() {
96 return "NavigationThrottleEfl";
99 NavigationThrottle::ThrottleCheckResult NavigationThrottleEfl::HandleNavigation(
101 #if BUILDFLAG(IS_TIZEN_TV)
102 if ((IsTIZENWRT() && navigation_handle()->GetURL().SchemeIsFileSystem()) ||
103 navigation_handle()->GetURL().SchemeIs(url::kDataScheme))
104 return NavigationThrottle::PROCEED;
106 if (ShouldHandleAsyncronously()) {
107 GetUIThreadTaskRunner({})->PostTask(
108 FROM_HERE, base::BindOnce(&NavigationThrottleEfl::HandleNavigationAsync,
109 weak_factory_.GetWeakPtr(),
110 GetNavigationPolicyParams(is_redirect)));
111 return NavigationThrottle::DEFER;
113 return HandleNavigationImpl(GetNavigationPolicyParams(is_redirect))
114 ? NavigationThrottle::CANCEL_AND_IGNORE
115 : NavigationThrottle::PROCEED;
118 void NavigationThrottleEfl::HandleNavigationAsync(
119 const NavigationPolicyParams& params) {
120 if (HandleNavigationImpl(params))
121 CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
126 bool NavigationThrottleEfl::HandleNavigationImpl(
127 const NavigationPolicyParams& params) {
128 auto* web_view = web_contents_utils::WebViewFromWebContents(
129 navigation_handle()->GetWebContents());
133 bool handled = false;
134 web_view->InvokePolicyNavigationCallback(params, &handled);
138 bool NavigationThrottleEfl::ShouldHandleAsyncronously() const {
139 // Ported from InterceptNavigationThrottle::ShouldCheckAsynchronously,
140 // see components/navigation_interception/intercept_navigation_throttle.cc
142 // Do not apply the async optimization for:
143 // - POST navigations, to ensure we aren't violating idempotency.
144 // - Subframe navigations, which aren't observed on Android, and should be
145 // fast on other platforms.
146 // - non-http/s URLs, which are more likely to be intercepted.
147 return navigation_handle()->IsInMainFrame() &&
148 !navigation_handle()->IsPost() &&
149 navigation_handle()->GetURL().SchemeIsHTTPOrHTTPS();
152 NavigationPolicyParams NavigationThrottleEfl::GetNavigationPolicyParams(
153 bool is_redirect) const {
154 auto* handle = navigation_handle();
155 NavigationPolicyParams params;
157 params.url = handle->GetURL();
158 params.httpMethod = handle->IsPost() ? "POST" : "GET";
159 params.type = GetNavigationTypeFromPageTransition(
160 handle->GetPageTransition(), handle->GetReloadType() != ReloadType::NONE);
162 handle->GetRequestHeaders().GetHeader(net::HttpRequestHeaders::kAuthorization,
164 params.auth = blink::WebString::FromUTF8(auth);
166 handle->GetRequestHeaders().GetHeader(net::HttpRequestHeaders::kCookie,
168 params.cookie = cookie;
169 params.should_replace_current_entry = handle->DidReplaceEntry();
170 params.is_main_frame = handle->IsInMainFrame();
171 params.is_redirect = is_redirect;
176 } // namespace content