[M108 Migration] Migrate navigation related fixup patches
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / efl_integration / browser / navigation_throttle_efl.cc
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.
4
5 #include "browser/navigation_throttle_efl.h"
6
7 #include "base/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"
15
16 #if BUILDFLAG(IS_TIZEN_TV)
17 #include "common/application_type.h"
18 #endif
19
20 namespace content {
21
22 static blink::WebNavigationType GetNavigationTypeFromPageTransition(
23     const ui::PageTransition& transition,
24     bool is_reload) {
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;
38     default:
39       return blink::kWebNavigationTypeOther;
40   }
41   NOTREACHED();
42   return blink::kWebNavigationTypeOther;
43 }
44
45 NavigationThrottleEfl::NavigationThrottleEfl(
46     NavigationHandle* navigation_handle)
47     : NavigationThrottle(navigation_handle), weak_factory_(this) {}
48
49 NavigationThrottleEfl::~NavigationThrottleEfl() = default;
50
51 NavigationThrottle::ThrottleCheckResult
52 NavigationThrottleEfl::WillStartRequest() {
53   return HandleNavigation(false /* is_redirect */);
54 }
55
56 NavigationThrottle::ThrottleCheckResult
57 NavigationThrottleEfl::WillRedirectRequest() {
58   return HandleNavigation(true /* is_redirect */);
59 }
60
61 NavigationThrottle::ThrottleCheckResult
62 NavigationThrottleEfl::WillFailRequest() {
63   auto* handle = navigation_handle();
64   auto* web_view =
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 BUILDFLAG(IS_TIZEN_TV)
71     // In VD tizen, WebBrowser will load error page by itself.
72     if (IsWebBrowser())
73       return NavigationThrottle::CANCEL_AND_IGNORE;
74 #endif
75   }
76   return NavigationThrottle::PROCEED;
77 }
78
79 const char* NavigationThrottleEfl::GetNameForLogging() {
80   return "NavigationThrottleEfl";
81 }
82
83 NavigationThrottle::ThrottleCheckResult NavigationThrottleEfl::HandleNavigation(
84     bool is_redirect) {
85 #if BUILDFLAG(IS_TIZEN_TV)
86   if ((IsTIZENWRT() && navigation_handle()->GetURL().SchemeIsFileSystem()) ||
87       navigation_handle()->GetURL().SchemeIs(url::kDataScheme))
88     return NavigationThrottle::PROCEED;
89 #endif
90   if (ShouldHandleAsyncronously()) {
91     GetUIThreadTaskRunner({})->PostTask(
92         FROM_HERE, base::BindOnce(&NavigationThrottleEfl::HandleNavigationAsync,
93                                   weak_factory_.GetWeakPtr(),
94                                   GetNavigationPolicyParams(is_redirect)));
95     return NavigationThrottle::DEFER;
96   }
97   return HandleNavigationImpl(GetNavigationPolicyParams(is_redirect))
98              ? NavigationThrottle::CANCEL_AND_IGNORE
99              : NavigationThrottle::PROCEED;
100 }
101
102 void NavigationThrottleEfl::HandleNavigationAsync(
103     const NavigationPolicyParams& params) {
104   if (HandleNavigationImpl(params))
105     CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE);
106   else
107     Resume();
108 }
109
110 bool NavigationThrottleEfl::HandleNavigationImpl(
111     const NavigationPolicyParams& params) {
112   auto* web_view = web_contents_utils::WebViewFromWebContents(
113       navigation_handle()->GetWebContents());
114   if (!web_view)
115     return false;
116
117   bool handled = false;
118   web_view->InvokePolicyNavigationCallback(params, &handled);
119   return handled;
120 }
121
122 bool NavigationThrottleEfl::ShouldHandleAsyncronously() const {
123   // Ported from InterceptNavigationThrottle::ShouldCheckAsynchronously,
124   // see components/navigation_interception/intercept_navigation_throttle.cc
125   //
126   // Do not apply the async optimization for:
127   // - POST navigations, to ensure we aren't violating idempotency.
128   // - Subframe navigations, which aren't observed on Android, and should be
129   //   fast on other platforms.
130   // - non-http/s URLs, which are more likely to be intercepted.
131   return navigation_handle()->IsInMainFrame() &&
132          !navigation_handle()->IsPost() &&
133          navigation_handle()->GetURL().SchemeIsHTTPOrHTTPS();
134 }
135
136 NavigationPolicyParams NavigationThrottleEfl::GetNavigationPolicyParams(
137     bool is_redirect) const {
138   auto* handle = navigation_handle();
139   NavigationPolicyParams params;
140
141   params.url = handle->GetURL();
142   params.httpMethod = handle->IsPost() ? "POST" : "GET";
143   params.type = GetNavigationTypeFromPageTransition(
144       handle->GetPageTransition(), handle->GetReloadType() != ReloadType::NONE);
145   std::string auth;
146   handle->GetRequestHeaders().GetHeader(net::HttpRequestHeaders::kAuthorization,
147                                         &auth);
148   params.auth = blink::WebString::FromUTF8(auth);
149   std::string cookie;
150   handle->GetRequestHeaders().GetHeader(net::HttpRequestHeaders::kCookie,
151                                         &cookie);
152   params.cookie = cookie;
153   params.should_replace_current_entry = handle->DidReplaceEntry();
154   params.is_main_frame = handle->IsInMainFrame();
155   params.is_redirect = is_redirect;
156
157   return params;
158 }
159
160 }  // namespace content