[go: nahoru, domu]

blob: aa14be21eac1c8848efbbc22dd1b09952472787a [file] [log] [blame]
mkosiba@chromium.org4360ae72012-10-09 22:10:461// Copyright (c) 2012 The Chromium Authors. 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
kaiwang@chromium.org62885ab2013-01-23 03:55:165#include "components/navigation_interception/intercept_navigation_delegate.h"
mkosiba@chromium.org4360ae72012-10-09 22:10:466
Gyuyoung Kimcb7965e2018-01-25 00:39:017#include <memory>
8
mkosiba@chromium.org4360ae72012-10-09 22:10:469#include "base/android/jni_android.h"
10#include "base/android/jni_string.h"
Sebastien Marchand53801a32019-01-25 16:26:1111#include "base/bind.h"
mkosiba@chromium.org4360ae72012-10-09 22:10:4612#include "base/callback.h"
Ryan Hamilton7f3bd3d2022-04-23 00:07:3913#include "base/strings/escape.h"
Mohamed Heikalbd641312019-06-22 00:14:3714#include "components/navigation_interception/jni_headers/InterceptNavigationDelegate_jni.h"
mkosiba@chromium.org4360ae72012-10-09 22:10:4615#include "content/public/browser/browser_thread.h"
David Bokan2a48f7bb2021-07-09 13:21:3616#include "content/public/browser/navigation_handle.h"
clamy40c9e142015-09-29 11:18:4717#include "content/public/browser/navigation_throttle.h"
jaekyun038903192015-03-31 14:15:5918#include "content/public/browser/render_frame_host.h"
mkosiba@chromium.org4360ae72012-10-09 22:10:4619#include "content/public/browser/render_view_host.h"
20#include "content/public/browser/web_contents.h"
Michael Thiessenca245a382022-02-21 16:11:1721#include "url/android/gurl_android.h"
tfarina@chromium.orge3b599e2013-07-05 07:15:1722#include "url/gurl.h"
mkosiba@chromium.org4360ae72012-10-09 22:10:4623
24using base::android::ConvertUTF8ToJavaString;
25using base::android::ScopedJavaLocalRef;
26using content::BrowserThread;
27using content::RenderViewHost;
28using content::WebContents;
Michael Thiessenca245a382022-02-21 16:11:1729using ui::PageTransition;
mkosiba@chromium.org4360ae72012-10-09 22:10:4630
tfarina@chromium.org8812e3d02013-05-22 12:38:5331namespace navigation_interception {
mkosiba@chromium.org4360ae72012-10-09 22:10:4632
33namespace {
34
thestig3b6a2f12015-09-25 08:17:2035const void* const kInterceptNavigationDelegateUserDataKey =
mkosiba@chromium.org4360ae72012-10-09 22:10:4636 &kInterceptNavigationDelegateUserDataKey;
37
Michael Thiessenca245a382022-02-21 16:11:1738bool CheckIfShouldIgnoreNavigationOnUIThread(
39 content::NavigationHandle* navigation_handle) {
mostynbad1e8c962015-03-25 21:51:1240 DCHECK_CURRENTLY_ON(BrowserThread::UI);
Michael Thiessenca245a382022-02-21 16:11:1741 DCHECK(navigation_handle);
mkosiba@chromium.org4360ae72012-10-09 22:10:4642
mkosiba@chromium.org4360ae72012-10-09 22:10:4643 InterceptNavigationDelegate* intercept_navigation_delegate =
Michael Thiessenca245a382022-02-21 16:11:1744 InterceptNavigationDelegate::Get(navigation_handle->GetWebContents());
mkosiba@chromium.org4360ae72012-10-09 22:10:4645 if (!intercept_navigation_delegate)
46 return false;
47
Michael Thiessenca245a382022-02-21 16:11:1748 return intercept_navigation_delegate->ShouldIgnoreNavigation(
49 navigation_handle);
mkosiba@chromium.org4360ae72012-10-09 22:10:4650}
51
thestig@chromium.orga8e69a742013-10-15 10:58:5552} // namespace
mkosiba@chromium.org4360ae72012-10-09 22:10:4653
54// static
55void InterceptNavigationDelegate::Associate(
56 WebContents* web_contents,
dcheng84c358e2016-04-26 07:05:5357 std::unique_ptr<InterceptNavigationDelegate> delegate) {
mkosiba@chromium.org4360ae72012-10-09 22:10:4658 web_contents->SetUserData(kInterceptNavigationDelegateUserDataKey,
avi8945fc92017-05-02 16:03:2359 std::move(delegate));
mkosiba@chromium.org4360ae72012-10-09 22:10:4660}
61
62// static
63InterceptNavigationDelegate* InterceptNavigationDelegate::Get(
64 WebContents* web_contents) {
dtrainor037df0d2014-10-08 18:05:2465 return static_cast<InterceptNavigationDelegate*>(
mkosiba@chromium.org4360ae72012-10-09 22:10:4666 web_contents->GetUserData(kInterceptNavigationDelegateUserDataKey));
67}
68
69// static
dcheng84c358e2016-04-26 07:05:5370std::unique_ptr<content::NavigationThrottle>
David Bokan2a48f7bb2021-07-09 13:21:3671InterceptNavigationDelegate::MaybeCreateThrottleFor(
Charlie Harrison3286ab72019-02-13 20:13:3072 content::NavigationHandle* handle,
73 navigation_interception::SynchronyMode mode) {
David Bokan2a48f7bb2021-07-09 13:21:3674 // Navigations in a subframe or non-primary frame tree should not be
75 // intercepted. As examples of a non-primary frame tree, a navigation
76 // occurring in a Portal element or an unactivated prerendering page should
77 // not launch an app.
78 // TODO(bokan): This is a bit of a stopgap approach since we won't run
79 // throttles again when the prerender is activated which means links that are
80 // prerendered will avoid launching an app intent that a regular navigation
81 // would have. Longer term we'll want prerender activation to check for app
82 // intents, or have this throttle cancel the prerender if an intent would
83 // have been launched (without launching the intent). It's also not clear
84 // what the right behavior for <portal> elements is.
85 // https://crbug.com/1227659.
86 if (!handle->IsInPrimaryMainFrame())
87 return nullptr;
88
Gyuyoung Kimcb7965e2018-01-25 00:39:0189 return std::make_unique<InterceptNavigationThrottle>(
Ken Rockotae24ce92019-12-19 20:00:2590 handle, base::BindRepeating(&CheckIfShouldIgnoreNavigationOnUIThread),
91 mode);
mkosiba@chromium.org4360ae72012-10-09 22:10:4692}
93
94InterceptNavigationDelegate::InterceptNavigationDelegate(
Colin Blundell4695e8142020-03-16 11:13:1295 JNIEnv* env,
96 jobject jdelegate,
97 bool escape_external_handler_value)
98 : weak_jdelegate_(env, jdelegate),
99 escape_external_handler_value_(escape_external_handler_value) {}
mkosiba@chromium.org4360ae72012-10-09 22:10:46100
101InterceptNavigationDelegate::~InterceptNavigationDelegate() {
102}
103
104bool InterceptNavigationDelegate::ShouldIgnoreNavigation(
Michael Thiessenca245a382022-02-21 16:11:17105 content::NavigationHandle* navigation_handle) {
106 GURL escaped_url = escape_external_handler_value_
Ryan Hamilton7f3bd3d2022-04-23 00:07:39107 ? GURL(base::EscapeExternalHandlerValue(
Michael Thiessenca245a382022-02-21 16:11:17108 navigation_handle->GetURL().spec()))
109 : navigation_handle->GetURL();
Colin Blundell4695e8142020-03-16 11:13:12110
Michael Thiessenca245a382022-02-21 16:11:17111 if (!escaped_url.is_valid())
mkosiba@chromium.org4360ae72012-10-09 22:10:46112 return false;
113
114 JNIEnv* env = base::android::AttachCurrentThread();
115 ScopedJavaLocalRef<jobject> jdelegate = weak_jdelegate_.get(env);
116
117 if (jdelegate.is_null())
118 return false;
119
mkosiba@chromium.org4360ae72012-10-09 22:10:46120 return Java_InterceptNavigationDelegate_shouldIgnoreNavigation(
Michael Thiessenca245a382022-02-21 16:11:17121 env, jdelegate, navigation_handle->GetJavaNavigationHandle(),
122 url::GURLAndroid::FromNativeGURL(env, escaped_url));
123}
124
125void InterceptNavigationDelegate::HandleExternalProtocolDialog(
126 const GURL& url,
127 ui::PageTransition page_transition,
128 bool has_user_gesture,
129 const absl::optional<url::Origin>& initiating_origin) {
130 GURL escaped_url = escape_external_handler_value_
Ryan Hamilton7f3bd3d2022-04-23 00:07:39131 ? GURL(base::EscapeExternalHandlerValue(url.spec()))
Michael Thiessenca245a382022-02-21 16:11:17132 : url;
133 if (!escaped_url.is_valid())
134 return;
135
136 JNIEnv* env = base::android::AttachCurrentThread();
137 ScopedJavaLocalRef<jobject> jdelegate = weak_jdelegate_.get(env);
138
139 if (jdelegate.is_null())
140 return;
141 Java_InterceptNavigationDelegate_handleExternalProtocolDialog(
142 env, jdelegate, url::GURLAndroid::FromNativeGURL(env, escaped_url),
143 page_transition, has_user_gesture,
144 initiating_origin ? initiating_origin->CreateJavaObject() : nullptr);
mkosiba@chromium.org4360ae72012-10-09 22:10:46145}
146
tfarina@chromium.org8812e3d02013-05-22 12:38:53147} // namespace navigation_interception