| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/navigation_interception/intercept_navigation_delegate.h" |
| |
| #include <memory> |
| |
| #include "base/android/jni_android.h" |
| #include "base/android/jni_string.h" |
| #include "base/callback.h" |
| #include "components/navigation_interception/intercept_navigation_throttle.h" |
| #include "components/navigation_interception/navigation_params_android.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/navigation_throttle.h" |
| #include "content/public/browser/render_frame_host.h" |
| #include "content/public/browser/render_view_host.h" |
| #include "content/public/browser/resource_request_info.h" |
| #include "content/public/browser/web_contents.h" |
| #include "jni/InterceptNavigationDelegate_jni.h" |
| #include "url/gurl.h" |
| |
| using base::android::ConvertUTF8ToJavaString; |
| using base::android::ScopedJavaLocalRef; |
| using content::BrowserThread; |
| using ui::PageTransition; |
| using content::RenderViewHost; |
| using content::WebContents; |
| |
| namespace navigation_interception { |
| |
| namespace { |
| |
| const int kMaxValidityOfUserGestureCarryoverInSeconds = 10; |
| |
| const void* const kInterceptNavigationDelegateUserDataKey = |
| &kInterceptNavigationDelegateUserDataKey; |
| |
| bool CheckIfShouldIgnoreNavigationOnUIThread(WebContents* source, |
| const NavigationParams& params) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| DCHECK(source); |
| |
| InterceptNavigationDelegate* intercept_navigation_delegate = |
| InterceptNavigationDelegate::Get(source); |
| if (!intercept_navigation_delegate) |
| return false; |
| |
| return intercept_navigation_delegate->ShouldIgnoreNavigation(params); |
| } |
| |
| } // namespace |
| |
| // static |
| void InterceptNavigationDelegate::Associate( |
| WebContents* web_contents, |
| std::unique_ptr<InterceptNavigationDelegate> delegate) { |
| web_contents->SetUserData(kInterceptNavigationDelegateUserDataKey, |
| std::move(delegate)); |
| } |
| |
| // static |
| InterceptNavigationDelegate* InterceptNavigationDelegate::Get( |
| WebContents* web_contents) { |
| return static_cast<InterceptNavigationDelegate*>( |
| web_contents->GetUserData(kInterceptNavigationDelegateUserDataKey)); |
| } |
| |
| // static |
| std::unique_ptr<content::NavigationThrottle> |
| InterceptNavigationDelegate::CreateThrottleFor( |
| content::NavigationHandle* handle) { |
| return std::make_unique<InterceptNavigationThrottle>( |
| handle, base::Bind(&CheckIfShouldIgnoreNavigationOnUIThread)); |
| } |
| |
| InterceptNavigationDelegate::InterceptNavigationDelegate( |
| JNIEnv* env, jobject jdelegate) |
| : weak_jdelegate_(env, jdelegate) { |
| } |
| |
| InterceptNavigationDelegate::~InterceptNavigationDelegate() { |
| } |
| |
| bool InterceptNavigationDelegate::ShouldIgnoreNavigation( |
| const NavigationParams& navigation_params) { |
| if (!navigation_params.url().is_valid()) |
| return false; |
| |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| ScopedJavaLocalRef<jobject> jdelegate = weak_jdelegate_.get(env); |
| |
| if (jdelegate.is_null()) |
| return false; |
| |
| bool has_user_gesture_carryover = |
| !navigation_params.has_user_gesture() && |
| base::TimeTicks::Now() - last_user_gesture_carryover_timestamp_ <= |
| base::TimeDelta::FromSeconds( |
| kMaxValidityOfUserGestureCarryoverInSeconds); |
| |
| ScopedJavaLocalRef<jobject> jobject_params = CreateJavaNavigationParams( |
| env, navigation_params, has_user_gesture_carryover); |
| |
| return Java_InterceptNavigationDelegate_shouldIgnoreNavigation( |
| env, jdelegate, jobject_params); |
| } |
| |
| void InterceptNavigationDelegate::UpdateLastUserGestureCarryoverTimestamp() { |
| last_user_gesture_carryover_timestamp_ = base::TimeTicks::Now(); |
| } |
| |
| } // namespace navigation_interception |