blob: a4e4d292312fdbb88baa6989794612a3c1bc5df5 [file] [log] [blame]
[email protected]4360ae72012-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
[email protected]62885ab2013-01-23 03:55:165#include "components/navigation_interception/intercept_navigation_delegate.h"
[email protected]4360ae72012-10-09 22:10:466
Gyuyoung Kimcb7965e2018-01-25 00:39:017#include <memory>
8
[email protected]4360ae72012-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"
[email protected]4360ae72012-10-09 22:10:4612#include "base/callback.h"
Mohamed Heikalbd641312019-06-22 00:14:3713#include "components/navigation_interception/jni_headers/InterceptNavigationDelegate_jni.h"
[email protected]c0d243a2013-01-31 21:20:1614#include "components/navigation_interception/navigation_params_android.h"
[email protected]4360ae72012-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"
[email protected]4360ae72012-10-09 22:10:4619#include "content/public/browser/render_view_host.h"
[email protected]4360ae72012-10-09 22:10:4620#include "content/public/browser/web_contents.h"
Colin Blundell4695e8142020-03-16 11:13:1221#include "net/base/escape.h"
[email protected]e3b599e2013-07-05 07:15:1722#include "url/gurl.h"
[email protected]4360ae72012-10-09 22:10:4623
24using base::android::ConvertUTF8ToJavaString;
25using base::android::ScopedJavaLocalRef;
26using content::BrowserThread;
Sylvain Defresnec6ccc77d2014-09-19 10:19:3527using ui::PageTransition;
[email protected]4360ae72012-10-09 22:10:4628using content::RenderViewHost;
29using content::WebContents;
30
[email protected]8812e3d02013-05-22 12:38:5331namespace navigation_interception {
[email protected]4360ae72012-10-09 22:10:4632
33namespace {
34
jaekyun038903192015-03-31 14:15:5935const int kMaxValidityOfUserGestureCarryoverInSeconds = 10;
36
thestig3b6a2f12015-09-25 08:17:2037const void* const kInterceptNavigationDelegateUserDataKey =
[email protected]4360ae72012-10-09 22:10:4638 &kInterceptNavigationDelegateUserDataKey;
39
[email protected]5dcaf8e2013-12-28 01:31:4240bool CheckIfShouldIgnoreNavigationOnUIThread(WebContents* source,
[email protected]c0d243a2013-01-31 21:20:1641 const NavigationParams& params) {
mostynbad1e8c962015-03-25 21:51:1242 DCHECK_CURRENTLY_ON(BrowserThread::UI);
[email protected]4360ae72012-10-09 22:10:4643 DCHECK(source);
44
[email protected]4360ae72012-10-09 22:10:4645 InterceptNavigationDelegate* intercept_navigation_delegate =
[email protected]5dcaf8e2013-12-28 01:31:4246 InterceptNavigationDelegate::Get(source);
[email protected]4360ae72012-10-09 22:10:4647 if (!intercept_navigation_delegate)
48 return false;
49
[email protected]c0d243a2013-01-31 21:20:1650 return intercept_navigation_delegate->ShouldIgnoreNavigation(params);
[email protected]4360ae72012-10-09 22:10:4651}
52
[email protected]a8e69a742013-10-15 10:58:5553} // namespace
[email protected]4360ae72012-10-09 22:10:4654
55// static
56void InterceptNavigationDelegate::Associate(
57 WebContents* web_contents,
dcheng84c358e2016-04-26 07:05:5358 std::unique_ptr<InterceptNavigationDelegate> delegate) {
[email protected]4360ae72012-10-09 22:10:4659 web_contents->SetUserData(kInterceptNavigationDelegateUserDataKey,
avi8945fc92017-05-02 16:03:2360 std::move(delegate));
[email protected]4360ae72012-10-09 22:10:4661}
62
63// static
64InterceptNavigationDelegate* InterceptNavigationDelegate::Get(
65 WebContents* web_contents) {
dtrainor037df0d2014-10-08 18:05:2466 return static_cast<InterceptNavigationDelegate*>(
[email protected]4360ae72012-10-09 22:10:4667 web_contents->GetUserData(kInterceptNavigationDelegateUserDataKey));
68}
69
70// static
dcheng84c358e2016-04-26 07:05:5371std::unique_ptr<content::NavigationThrottle>
David Bokan2a48f7bb2021-07-09 13:21:3672InterceptNavigationDelegate::MaybeCreateThrottleFor(
Charlie Harrison3286ab72019-02-13 20:13:3073 content::NavigationHandle* handle,
74 navigation_interception::SynchronyMode mode) {
David Bokan2a48f7bb2021-07-09 13:21:3675 // Navigations in a subframe or non-primary frame tree should not be
76 // intercepted. As examples of a non-primary frame tree, a navigation
77 // occurring in a Portal element or an unactivated prerendering page should
78 // not launch an app.
79 // TODO(bokan): This is a bit of a stopgap approach since we won't run
80 // throttles again when the prerender is activated which means links that are
81 // prerendered will avoid launching an app intent that a regular navigation
82 // would have. Longer term we'll want prerender activation to check for app
83 // intents, or have this throttle cancel the prerender if an intent would
84 // have been launched (without launching the intent). It's also not clear
85 // what the right behavior for <portal> elements is.
86 // https://crbug.com/1227659.
87 if (!handle->IsInPrimaryMainFrame())
88 return nullptr;
89
Gyuyoung Kimcb7965e2018-01-25 00:39:0190 return std::make_unique<InterceptNavigationThrottle>(
Ken Rockotae24ce92019-12-19 20:00:2591 handle, base::BindRepeating(&CheckIfShouldIgnoreNavigationOnUIThread),
92 mode);
[email protected]4360ae72012-10-09 22:10:4693}
94
[email protected]4360ae72012-10-09 22:10:4695InterceptNavigationDelegate::InterceptNavigationDelegate(
Colin Blundell4695e8142020-03-16 11:13:1296 JNIEnv* env,
97 jobject jdelegate,
98 bool escape_external_handler_value)
99 : weak_jdelegate_(env, jdelegate),
100 escape_external_handler_value_(escape_external_handler_value) {}
[email protected]4360ae72012-10-09 22:10:46101
102InterceptNavigationDelegate::~InterceptNavigationDelegate() {
103}
104
105bool InterceptNavigationDelegate::ShouldIgnoreNavigation(
[email protected]c0d243a2013-01-31 21:20:16106 const NavigationParams& navigation_params) {
Colin Blundell4695e8142020-03-16 11:13:12107 NavigationParams navigation_params_to_use(navigation_params);
108 if (escape_external_handler_value_) {
109 navigation_params_to_use.url() =
110 GURL(net::EscapeExternalHandlerValue(navigation_params.url().spec()));
111 }
112
113 if (!navigation_params_to_use.url().is_valid())
[email protected]4360ae72012-10-09 22:10:46114 return false;
115
116 JNIEnv* env = base::android::AttachCurrentThread();
117 ScopedJavaLocalRef<jobject> jdelegate = weak_jdelegate_.get(env);
118
119 if (jdelegate.is_null())
120 return false;
121
jaekyun038903192015-03-31 14:15:59122 bool has_user_gesture_carryover =
Colin Blundell4695e8142020-03-16 11:13:12123 !navigation_params_to_use.has_user_gesture() &&
jaekyun038903192015-03-31 14:15:59124 base::TimeTicks::Now() - last_user_gesture_carryover_timestamp_ <=
125 base::TimeDelta::FromSeconds(
126 kMaxValidityOfUserGestureCarryoverInSeconds);
127
128 ScopedJavaLocalRef<jobject> jobject_params = CreateJavaNavigationParams(
Colin Blundell4695e8142020-03-16 11:13:12129 env, navigation_params_to_use, has_user_gesture_carryover);
[email protected]c0d243a2013-01-31 21:20:16130
[email protected]4360ae72012-10-09 22:10:46131 return Java_InterceptNavigationDelegate_shouldIgnoreNavigation(
torne948f3662016-08-16 15:10:44132 env, jdelegate, jobject_params);
[email protected]4360ae72012-10-09 22:10:46133}
134
jaekyun038903192015-03-31 14:15:59135void InterceptNavigationDelegate::UpdateLastUserGestureCarryoverTimestamp() {
136 last_user_gesture_carryover_timestamp_ = base::TimeTicks::Now();
137}
138
[email protected]8812e3d02013-05-22 12:38:53139} // namespace navigation_interception