• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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