1 // Copyright 2014 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 #ifndef CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BRIDGE_DISPATCHER_HOST_H_ 6 #define CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BRIDGE_DISPATCHER_HOST_H_ 7 8 #include <map> 9 #include <set> 10 11 #include "base/android/jni_weak_ref.h" 12 #include "base/android/scoped_java_ref.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/memory/weak_ptr.h" 15 #include "base/synchronization/lock.h" 16 #include "content/browser/android/java/gin_java_bound_object.h" 17 #include "content/browser/android/java/gin_java_method_invocation_helper.h" 18 #include "content/public/browser/browser_message_filter.h" 19 #include "content/public/browser/web_contents_observer.h" 20 21 namespace base { 22 class ListValue; 23 } 24 25 namespace IPC { 26 class Message; 27 } 28 29 namespace content { 30 31 // This class handles injecting Java objects into a single RenderView. The Java 32 // object itself lives in the browser process on a background thread, while a 33 // proxy object is created in the renderer. An instance of this class exists 34 // for each RenderFrameHost. 35 class GinJavaBridgeDispatcherHost 36 : public WebContentsObserver, 37 public BrowserMessageFilter, 38 public GinJavaMethodInvocationHelper::DispatcherDelegate { 39 public: 40 41 GinJavaBridgeDispatcherHost(WebContents* web_contents, 42 jobject retained_object_set); 43 44 void AddNamedObject( 45 const std::string& name, 46 const base::android::JavaRef<jobject>& object, 47 const base::android::JavaRef<jclass>& safe_annotation_clazz); 48 void RemoveNamedObject(const std::string& name); 49 void SetAllowObjectContentsInspection(bool allow); 50 51 // WebContentsObserver 52 virtual void RenderFrameCreated(RenderFrameHost* render_frame_host) OVERRIDE; 53 virtual void RenderFrameDeleted(RenderFrameHost* render_frame_host) OVERRIDE; 54 virtual void DocumentAvailableInMainFrame() OVERRIDE; 55 56 // BrowserMessageFilter 57 using BrowserMessageFilter::Send; 58 virtual void OnDestruct() const OVERRIDE; 59 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 60 virtual base::TaskRunner* OverrideTaskRunnerForMessage( 61 const IPC::Message& message) OVERRIDE; 62 63 // GinJavaMethodInvocationHelper::DispatcherDelegate 64 virtual JavaObjectWeakGlobalRef GetObjectWeakRef( 65 GinJavaBoundObject::ObjectID object_id) OVERRIDE; 66 67 private: 68 friend class BrowserThread; 69 friend class base::DeleteHelper<GinJavaBridgeDispatcherHost>; 70 71 typedef std::map<GinJavaBoundObject::ObjectID, 72 scoped_refptr<GinJavaBoundObject>> ObjectMap; 73 74 virtual ~GinJavaBridgeDispatcherHost() OVERRIDE; 75 76 void AddBrowserFilterIfNeeded(); 77 78 // Run on any thread. 79 GinJavaBoundObject::ObjectID AddObject( 80 const base::android::JavaRef<jobject>& object, 81 const base::android::JavaRef<jclass>& safe_annotation_clazz, 82 bool is_named, 83 int32 holder); 84 scoped_refptr<GinJavaBoundObject> FindObject( 85 GinJavaBoundObject::ObjectID object_id); 86 bool FindObjectId(const base::android::JavaRef<jobject>& object, 87 GinJavaBoundObject::ObjectID* object_id); 88 void RemoveFromRetainedObjectSetLocked(const JavaObjectWeakGlobalRef& ref); 89 JavaObjectWeakGlobalRef RemoveHolderAndAdvanceLocked( 90 int32 holder, 91 ObjectMap::iterator* iter_ptr); 92 93 // Run on the background thread. 94 void OnGetMethods(GinJavaBoundObject::ObjectID object_id, 95 std::set<std::string>* returned_method_names); 96 void OnHasMethod(GinJavaBoundObject::ObjectID object_id, 97 const std::string& method_name, 98 bool* result); 99 void OnInvokeMethod(GinJavaBoundObject::ObjectID object_id, 100 const std::string& method_name, 101 const base::ListValue& arguments, 102 base::ListValue* result, 103 content::GinJavaBridgeError* error_code); 104 void OnObjectWrapperDeleted(GinJavaBoundObject::ObjectID object_id); 105 int GetCurrentRoutingID() const; 106 void SetCurrentRoutingID(int routing_id); 107 108 bool browser_filter_added_; 109 110 typedef std::map<std::string, GinJavaBoundObject::ObjectID> NamedObjectMap; 111 NamedObjectMap named_objects_; 112 113 // The following objects are used on both threads, so locking must be used. 114 115 // Every time a GinJavaBoundObject backed by a real Java object is 116 // created/destroyed, we insert/remove a strong ref to that Java object into 117 // this set so that it doesn't get garbage collected while it's still 118 // potentially in use. Although the set is managed native side, it's owned 119 // and defined in Java so that pushing refs into it does not create new GC 120 // roots that would prevent ContentViewCore from being garbage collected. 121 JavaObjectWeakGlobalRef retained_object_set_; 122 // Note that retained_object_set_ does not need to be consistent 123 // with objects_. 124 ObjectMap objects_; 125 base::Lock objects_lock_; 126 127 // The following objects are only used on the background thread. 128 bool allow_object_contents_inspection_; 129 // The routing id of the RenderFrameHost whose request we are processing. 130 int32 current_routing_id_; 131 132 DISALLOW_COPY_AND_ASSIGN(GinJavaBridgeDispatcherHost); 133 }; 134 135 } // namespace content 136 137 #endif // CONTENT_BROWSER_ANDROID_JAVA_GIN_JAVA_BRIDGE_DISPATCHER_HOST_H_ 138