1 // Copyright 2017 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 
5 #include "content/browser/android/javascript_injector.h"
6 
7 #include "base/android/jni_string.h"
8 #include "base/memory/ptr_util.h"
9 #include "content/browser/android/java/gin_java_bridge_dispatcher_host.h"
10 #include "content/public/android/content_jni_headers/JavascriptInjectorImpl_jni.h"
11 
12 using base::android::AttachCurrentThread;
13 using base::android::ConvertJavaStringToUTF8;
14 using base::android::JavaParamRef;
15 using base::android::ScopedJavaLocalRef;
16 
17 namespace content {
18 
JavascriptInjector(JNIEnv * env,const base::android::JavaParamRef<jobject> & obj,const base::android::JavaParamRef<jobject> & retained_objects,WebContents * web_contents)19 JavascriptInjector::JavascriptInjector(
20     JNIEnv* env,
21     const base::android::JavaParamRef<jobject>& obj,
22     const base::android::JavaParamRef<jobject>& retained_objects,
23     WebContents* web_contents)
24     : java_ref_(env, obj) {
25   java_bridge_dispatcher_host_ =
26       new GinJavaBridgeDispatcherHost(web_contents, retained_objects);
27   web_contents->SetUserData(UserDataKey(), base::WrapUnique(this));
28 }
29 
~JavascriptInjector()30 JavascriptInjector::~JavascriptInjector() {
31   JNIEnv* env = AttachCurrentThread();
32   ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env);
33   if (j_obj.is_null())
34     return;
35   Java_JavascriptInjectorImpl_onDestroy(env, j_obj);
36 }
37 
SetAllowInspection(JNIEnv * env,const JavaParamRef<jobject> & obj,jboolean allow)38 void JavascriptInjector::SetAllowInspection(JNIEnv* env,
39                                             const JavaParamRef<jobject>& obj,
40                                             jboolean allow) {
41   DCHECK(java_bridge_dispatcher_host_);
42   java_bridge_dispatcher_host_->SetAllowObjectContentsInspection(allow);
43 }
44 
AddInterface(JNIEnv * env,const JavaParamRef<jobject> &,const JavaParamRef<jobject> & object,const JavaParamRef<jstring> & name,const JavaParamRef<jclass> & safe_annotation_clazz)45 void JavascriptInjector::AddInterface(
46     JNIEnv* env,
47     const JavaParamRef<jobject>& /* obj */,
48     const JavaParamRef<jobject>& object,
49     const JavaParamRef<jstring>& name,
50     const JavaParamRef<jclass>& safe_annotation_clazz) {
51   DCHECK(java_bridge_dispatcher_host_);
52   java_bridge_dispatcher_host_->AddNamedObject(
53       ConvertJavaStringToUTF8(env, name), object, safe_annotation_clazz);
54 }
55 
RemoveInterface(JNIEnv * env,const JavaParamRef<jobject> &,const JavaParamRef<jstring> & name)56 void JavascriptInjector::RemoveInterface(JNIEnv* env,
57                                          const JavaParamRef<jobject>& /* obj */,
58                                          const JavaParamRef<jstring>& name) {
59   DCHECK(java_bridge_dispatcher_host_);
60   java_bridge_dispatcher_host_->RemoveNamedObject(
61       ConvertJavaStringToUTF8(env, name));
62 }
63 
JNI_JavascriptInjectorImpl_Init(JNIEnv * env,const JavaParamRef<jobject> & obj,const JavaParamRef<jobject> & jweb_contents,const JavaParamRef<jobject> & retained_objects)64 jlong JNI_JavascriptInjectorImpl_Init(
65     JNIEnv* env,
66     const JavaParamRef<jobject>& obj,
67     const JavaParamRef<jobject>& jweb_contents,
68     const JavaParamRef<jobject>& retained_objects) {
69   auto* web_contents = WebContents::FromJavaWebContents(jweb_contents);
70   CHECK(web_contents) << "Should be created with a valid WebContents.";
71   DCHECK(!JavascriptInjector::FromWebContents(web_contents));
72 
73   // Owned by |web_contents|.
74   auto* injector =
75       new JavascriptInjector(env, obj, retained_objects, web_contents);
76   return reinterpret_cast<intptr_t>(injector);
77 }
78 
79 WEB_CONTENTS_USER_DATA_KEY_IMPL(JavascriptInjector)
80 
81 }  // namespace content
82