blob: e907b16ce10992dcfa7a4b1b76d13a1a97e1b0f0 [file] [log] [blame]
// Copyright 2017 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 "content/browser/renderer_host/render_frame_host_android.h"
#include <utility>
#include "base/android/callback_android.h"
#include "base/android/jni_string.h"
#include "base/android/unguessable_token_android.h"
#include "base/bind.h"
#include "base/check_op.h"
#include "content/browser/bad_message.h"
#include "content/browser/renderer_host/modal_close_listener_host.h"
#include "content/browser/renderer_host/render_frame_host_delegate.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/android/content_jni_headers/RenderFrameHostImpl_jni.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/site_instance.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/mojom/frame/user_activation_notification_type.mojom.h"
#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-shared.h"
#include "url/android/gurl_android.h"
#include "url/origin.h"
using base::android::AttachCurrentThread;
using base::android::ConvertUTF8ToJavaString;
using base::android::JavaParamRef;
using base::android::JavaRef;
using base::android::ScopedJavaLocalRef;
namespace content {
namespace {
void OnGetCanonicalUrlForSharing(
const base::android::JavaRef<jobject>& jcallback,
const base::Optional<GURL>& url) {
JNIEnv* env = base::android::AttachCurrentThread();
if (!url) {
base::android::RunObjectCallbackAndroid(jcallback,
url::GURLAndroid::EmptyGURL(env));
return;
}
base::android::RunObjectCallbackAndroid(
jcallback, url::GURLAndroid::FromNativeGURL(env, url.value()));
}
} // namespace
// static
RenderFrameHost* RenderFrameHost::FromJavaRenderFrameHost(
const JavaRef<jobject>& jrender_frame_host_android) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (jrender_frame_host_android.is_null())
return nullptr;
RenderFrameHostAndroid* render_frame_host_android =
reinterpret_cast<RenderFrameHostAndroid*>(
Java_RenderFrameHostImpl_getNativePointer(
AttachCurrentThread(), jrender_frame_host_android));
if (!render_frame_host_android)
return nullptr;
return render_frame_host_android->render_frame_host();
}
RenderFrameHostAndroid::RenderFrameHostAndroid(
RenderFrameHostImpl* render_frame_host)
: render_frame_host_(render_frame_host) {}
RenderFrameHostAndroid::~RenderFrameHostAndroid() {
// Avoid unnecessarily creating the java object from the destructor.
if (obj_.is_uninitialized())
return;
ScopedJavaLocalRef<jobject> jobj = GetJavaObject();
if (!jobj.is_null()) {
Java_RenderFrameHostImpl_clearNativePtr(AttachCurrentThread(), jobj);
obj_.reset();
}
}
base::android::ScopedJavaLocalRef<jobject>
RenderFrameHostAndroid::GetJavaObject() {
JNIEnv* env = base::android::AttachCurrentThread();
if (obj_.is_uninitialized()) {
const bool is_incognito = render_frame_host_->GetSiteInstance()
->GetBrowserContext()
->IsOffTheRecord();
const GlobalFrameRoutingId rfh_id =
render_frame_host_->GetGlobalFrameRoutingId();
ScopedJavaLocalRef<jobject> local_ref = Java_RenderFrameHostImpl_create(
env, reinterpret_cast<intptr_t>(this),
render_frame_host_->delegate()->GetJavaRenderFrameHostDelegate(),
is_incognito, rfh_id.child_id, rfh_id.frame_routing_id);
obj_ = JavaObjectWeakGlobalRef(env, local_ref);
return local_ref;
}
return obj_.get(env);
}
ScopedJavaLocalRef<jobject> RenderFrameHostAndroid::GetLastCommittedURL(
JNIEnv* env,
const JavaParamRef<jobject>& obj) const {
return url::GURLAndroid::FromNativeGURL(
env, render_frame_host_->GetLastCommittedURL());
}
ScopedJavaLocalRef<jobject> RenderFrameHostAndroid::GetLastCommittedOrigin(
JNIEnv* env,
const JavaParamRef<jobject>& obj) {
return render_frame_host_->GetLastCommittedOrigin().CreateJavaObject();
}
void RenderFrameHostAndroid::GetCanonicalUrlForSharing(
JNIEnv* env,
const base::android::JavaParamRef<jobject>&,
const base::android::JavaParamRef<jobject>& jcallback) const {
render_frame_host_->GetCanonicalUrlForSharing(base::BindOnce(
&OnGetCanonicalUrlForSharing,
base::android::ScopedJavaGlobalRef<jobject>(env, jcallback)));
}
bool RenderFrameHostAndroid::IsFeatureEnabled(
JNIEnv* env,
const base::android::JavaParamRef<jobject>&,
jint feature) const {
return render_frame_host_->IsFeatureEnabled(
static_cast<blink::mojom::PermissionsPolicyFeature>(feature));
}
ScopedJavaLocalRef<jobject>
RenderFrameHostAndroid::GetAndroidOverlayRoutingToken(
JNIEnv* env,
const JavaParamRef<jobject>& obj) const {
return base::android::UnguessableTokenAndroid::Create(
env, render_frame_host_->GetOverlayRoutingToken());
}
void RenderFrameHostAndroid::NotifyUserActivation(
JNIEnv* env,
const base::android::JavaParamRef<jobject>&) {
render_frame_host_->GetAssociatedLocalFrame()->NotifyUserActivation(
blink::mojom::UserActivationNotificationType::kVoiceSearch);
}
jboolean RenderFrameHostAndroid::SignalModalCloseWatcherIfActive(
JNIEnv* env,
const base::android::JavaParamRef<jobject>&) const {
auto* modal_close_listener_host =
ModalCloseListenerHost::GetOrCreateForCurrentDocument(render_frame_host_);
return modal_close_listener_host->SignalIfActive();
}
jboolean RenderFrameHostAndroid::IsRenderFrameCreated(
JNIEnv* env,
const base::android::JavaParamRef<jobject>&) const {
return render_frame_host_->IsRenderFrameCreated();
}
void RenderFrameHostAndroid::GetInterfaceToRendererFrame(
JNIEnv* env,
const base::android::JavaParamRef<jobject>&,
const base::android::JavaParamRef<jstring>& interface_name,
jint message_pipe_raw_handle) const {
DCHECK(render_frame_host_->IsRenderFrameCreated());
render_frame_host_->GetRemoteInterfaces()->GetInterfaceByName(
ConvertJavaStringToUTF8(env, interface_name),
mojo::ScopedMessagePipeHandle(
mojo::MessagePipeHandle(message_pipe_raw_handle)));
}
void RenderFrameHostAndroid::TerminateRendererDueToBadMessage(
JNIEnv* env,
const base::android::JavaParamRef<jobject>&,
jint reason) const {
DCHECK_LT(reason, bad_message::BAD_MESSAGE_MAX);
ReceivedBadMessage(render_frame_host_->GetProcess(),
static_cast<bad_message::BadMessageReason>(reason));
}
jboolean RenderFrameHostAndroid::IsProcessBlocked(
JNIEnv* env,
const base::android::JavaParamRef<jobject>&) const {
return render_frame_host_->GetProcess()->IsBlocked();
}
jint RenderFrameHostAndroid::PerformGetAssertionWebAuthSecurityChecks(
JNIEnv* env,
const base::android::JavaParamRef<jobject>&,
const base::android::JavaParamRef<jstring>& relying_party_id,
const base::android::JavaParamRef<jobject>& effective_origin) const {
url::Origin origin = url::Origin::FromJavaObject(effective_origin);
return static_cast<int32_t>(
render_frame_host_->PerformGetAssertionWebAuthSecurityChecks(
ConvertJavaStringToUTF8(env, relying_party_id), origin));
}
jint RenderFrameHostAndroid::PerformMakeCredentialWebAuthSecurityChecks(
JNIEnv* env,
const base::android::JavaParamRef<jobject>&,
const base::android::JavaParamRef<jstring>& relying_party_id,
const base::android::JavaParamRef<jobject>& effective_origin) const {
url::Origin origin = url::Origin::FromJavaObject(effective_origin);
return static_cast<int32_t>(
render_frame_host_->PerformMakeCredentialWebAuthSecurityChecks(
ConvertJavaStringToUTF8(env, relying_party_id), origin));
}
} // namespace content