OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/java/java_bridge_dispatcher_host_manager .h" | 5 #include "content/browser/renderer_host/java/java_bridge_dispatcher_host_manager .h" |
6 | 6 |
7 #include "base/android/jni_android.h" | 7 #include "base/android/jni_android.h" |
8 #include "base/android/jni_weak_ref.h" | 8 #include "base/android/jni_weak_ref.h" |
9 #include "base/android/scoped_java_ref.h" | 9 #include "base/android/scoped_java_ref.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
13 #include "content/browser/renderer_host/java/java_bound_object.h" | 13 #include "content/browser/renderer_host/java/java_bound_object.h" |
14 #include "content/browser/renderer_host/java/java_bridge_dispatcher_host.h" | 14 #include "content/browser/renderer_host/java/java_bridge_dispatcher_host.h" |
15 #include "content/common/android/hash_set.h" | 15 #include "content/common/android/hash_set.h" |
16 #include "content/common/java_bridge_messages.h" | |
16 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
17 #include "content/public/browser/render_frame_host.h" | 18 #include "content/public/browser/render_frame_host.h" |
18 #include "third_party/WebKit/public/web/WebBindings.h" | 19 #include "third_party/WebKit/public/web/WebBindings.h" |
19 | 20 |
20 namespace content { | 21 namespace content { |
21 | 22 |
22 JavaBridgeDispatcherHostManager::JavaBridgeDispatcherHostManager( | 23 JavaBridgeDispatcherHostManager::JavaBridgeDispatcherHostManager( |
23 WebContents* web_contents) | 24 WebContents* web_contents, |
25 jobject retained_object_set) | |
24 : WebContentsObserver(web_contents), | 26 : WebContentsObserver(web_contents), |
25 allow_object_contents_inspection_(true) { | 27 retained_object_set_(base::android::AttachCurrentThread(), |
28 retained_object_set), | |
29 allow_object_contents_inspection_(true), | |
30 render_frame_host_message_source_(NULL) { | |
31 DCHECK(retained_object_set); | |
26 } | 32 } |
27 | 33 |
28 JavaBridgeDispatcherHostManager::~JavaBridgeDispatcherHostManager() { | 34 JavaBridgeDispatcherHostManager::~JavaBridgeDispatcherHostManager() { |
29 for (ObjectMap::iterator iter = objects_.begin(); iter != objects_.end(); | 35 for (ObjectMap::iterator iter = objects_.begin(); iter != objects_.end(); |
30 ++iter) { | 36 ++iter) { |
31 blink::WebBindings::releaseObject(iter->second); | 37 blink::WebBindings::releaseObject(iter->second); |
32 } | 38 } |
33 DCHECK_EQ(0U, instances_.size()); | 39 DCHECK_EQ(0U, instances_.size()); |
34 } | 40 } |
35 | 41 |
36 void JavaBridgeDispatcherHostManager::AddNamedObject(const base::string16& name, | 42 void JavaBridgeDispatcherHostManager::AddNamedObject(const base::string16& name, |
37 NPObject* object) { | 43 NPObject* object) { |
38 // Record this object in a map so that we can add it into RenderViewHosts | 44 // Record this object in a map so that we can add it into RenderViewHosts |
39 // created later. The JavaBridgeDispatcherHost instances will take a | 45 // created later. The JavaBridgeDispatcherHost instances will take a |
40 // reference to the object, but we take one too, because this method can be | 46 // reference to the object, but we take one too, because this method can be |
41 // called before there are any such instances. | 47 // called before there are any such instances. |
42 blink::WebBindings::retainObject(object); | 48 blink::WebBindings::retainObject(object); |
43 objects_[name] = object; | 49 objects_[name] = object; |
44 | 50 |
45 for (InstanceMap::iterator iter = instances_.begin(); | 51 for (InstanceMap::iterator iter = instances_.begin(); |
46 iter != instances_.end(); ++iter) { | 52 iter != instances_.end(); ++iter) { |
47 iter->second->AddNamedObject(name, object); | 53 iter->second->AddNamedObject(name, object); |
48 } | 54 } |
49 } | 55 } |
50 | 56 |
51 void JavaBridgeDispatcherHostManager::SetRetainedObjectSet( | |
52 const JavaObjectWeakGlobalRef& retained_object_set) { | |
53 // It's an error to replace the retained_object_set_ after it's been set, | |
54 // so we check that it hasn't already been here. | |
55 // TODO(benm): It'd be better to pass the set in the constructor to avoid | |
56 // the chance of this happening; but that's tricky as this get's constructed | |
57 // before ContentViewCore (which owns the set). Best solution may be to move | |
58 // ownership of the JavaBridgerDispatchHostManager from WebContents to | |
59 // ContentViewCore? | |
60 JNIEnv* env = base::android::AttachCurrentThread(); | |
61 base::android::ScopedJavaLocalRef<jobject> new_retained_object_set = | |
62 retained_object_set.get(env); | |
63 base::android::ScopedJavaLocalRef<jobject> current_retained_object_set = | |
64 retained_object_set_.get(env); | |
65 if (!env->IsSameObject(new_retained_object_set.obj(), | |
66 current_retained_object_set.obj())) { | |
67 DCHECK(current_retained_object_set.is_null()); | |
68 retained_object_set_ = retained_object_set; | |
69 } | |
70 } | |
71 | |
72 void JavaBridgeDispatcherHostManager::RemoveNamedObject( | 57 void JavaBridgeDispatcherHostManager::RemoveNamedObject( |
73 const base::string16& name) { | 58 const base::string16& name) { |
74 ObjectMap::iterator iter = objects_.find(name); | 59 ObjectMap::iterator iter = objects_.find(name); |
75 if (iter == objects_.end()) { | 60 if (iter == objects_.end()) { |
76 return; | 61 return; |
77 } | 62 } |
78 | 63 |
79 blink::WebBindings::releaseObject(iter->second); | 64 blink::WebBindings::releaseObject(iter->second); |
80 objects_.erase(iter); | 65 objects_.erase(iter); |
81 | 66 |
82 for (InstanceMap::iterator iter = instances_.begin(); | 67 for (InstanceMap::iterator iter = instances_.begin(); |
83 iter != instances_.end(); ++iter) { | 68 iter != instances_.end(); ++iter) { |
84 iter->second->RemoveNamedObject(name); | 69 iter->second->RemoveNamedObject(name); |
85 } | 70 } |
86 } | 71 } |
87 | 72 |
88 void JavaBridgeDispatcherHostManager::OnGetChannelHandle( | 73 void JavaBridgeDispatcherHostManager::OnGetChannelHandle( |
89 RenderFrameHost* render_frame_host, IPC::Message* reply_msg) { | 74 IPC::Message* reply_msg) { |
90 instances_[render_frame_host]->OnGetChannelHandle(reply_msg); | 75 DCHECK(render_frame_host_message_source_); |
76 instances_[render_frame_host_message_source_]->OnGetChannelHandle(reply_msg); | |
91 } | 77 } |
92 | 78 |
93 void JavaBridgeDispatcherHostManager::RenderFrameCreated( | 79 void JavaBridgeDispatcherHostManager::RenderFrameCreated( |
94 RenderFrameHost* render_frame_host) { | 80 RenderFrameHost* render_frame_host) { |
95 // Creates a JavaBridgeDispatcherHost for the specified RenderViewHost and | 81 // Creates a JavaBridgeDispatcherHost for the specified RenderViewHost and |
96 // adds all currently registered named objects to the new instance. | 82 // adds all currently registered named objects to the new instance. |
97 scoped_refptr<JavaBridgeDispatcherHost> instance = | 83 scoped_refptr<JavaBridgeDispatcherHost> instance = |
98 new JavaBridgeDispatcherHost(render_frame_host); | 84 new JavaBridgeDispatcherHost(render_frame_host); |
99 | 85 |
100 for (ObjectMap::const_iterator iter = objects_.begin(); | 86 for (ObjectMap::const_iterator iter = objects_.begin(); |
(...skipping 24 matching lines...) Expand all Loading... | |
125 // We also need to add back the named objects we have so far as they | 111 // We also need to add back the named objects we have so far as they |
126 // should survive navigations. | 112 // should survive navigations. |
127 ObjectMap::iterator it = objects_.begin(); | 113 ObjectMap::iterator it = objects_.begin(); |
128 for (; it != objects_.end(); ++it) { | 114 for (; it != objects_.end(); ++it) { |
129 JNI_Java_HashSet_add(env, retained_object_set, | 115 JNI_Java_HashSet_add(env, retained_object_set, |
130 JavaBoundObject::GetJavaObject(it->second)); | 116 JavaBoundObject::GetJavaObject(it->second)); |
131 } | 117 } |
132 } | 118 } |
133 } | 119 } |
134 | 120 |
121 bool JavaBridgeDispatcherHostManager::OnMessageReceived( | |
122 RenderFrameHost* render_frame_host, | |
123 const IPC::Message& message) { | |
124 render_frame_host_message_source_ = render_frame_host; | |
ncarter (slow)
2014/04/29 20:50:45
Here's an idea that might mean we don't need to re
mnaganov (inactive)
2014/05/01 13:57:38
Thanks for the suggestion, Nick!
| |
125 bool handled = true; | |
126 IPC_BEGIN_MESSAGE_MAP(JavaBridgeDispatcherHostManager, message) | |
127 IPC_MESSAGE_HANDLER_DELAY_REPLY(JavaBridgeHostMsg_GetChannelHandle, | |
128 OnGetChannelHandle) | |
129 IPC_MESSAGE_UNHANDLED(handled = false) | |
130 IPC_END_MESSAGE_MAP() | |
131 render_frame_host_message_source_ = NULL; | |
132 return handled; | |
133 } | |
134 | |
135 void JavaBridgeDispatcherHostManager::JavaBoundObjectCreated( | 135 void JavaBridgeDispatcherHostManager::JavaBoundObjectCreated( |
136 const base::android::JavaRef<jobject>& object) { | 136 const base::android::JavaRef<jobject>& object) { |
137 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 137 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
138 | 138 |
139 JNIEnv* env = base::android::AttachCurrentThread(); | 139 JNIEnv* env = base::android::AttachCurrentThread(); |
140 base::android::ScopedJavaLocalRef<jobject> retained_object_set = | 140 base::android::ScopedJavaLocalRef<jobject> retained_object_set = |
141 retained_object_set_.get(env); | 141 retained_object_set_.get(env); |
142 if (!retained_object_set.is_null()) { | 142 if (!retained_object_set.is_null()) { |
143 JNI_Java_HashSet_add(env, retained_object_set, object); | 143 JNI_Java_HashSet_add(env, retained_object_set, object); |
144 } | 144 } |
(...skipping 10 matching lines...) Expand all Loading... | |
155 JNI_Java_HashSet_remove(env, retained_object_set, object); | 155 JNI_Java_HashSet_remove(env, retained_object_set, object); |
156 } | 156 } |
157 } | 157 } |
158 | 158 |
159 void JavaBridgeDispatcherHostManager::SetAllowObjectContentsInspection( | 159 void JavaBridgeDispatcherHostManager::SetAllowObjectContentsInspection( |
160 bool allow) { | 160 bool allow) { |
161 allow_object_contents_inspection_ = allow; | 161 allow_object_contents_inspection_ = allow; |
162 } | 162 } |
163 | 163 |
164 } // namespace content | 164 } // namespace content |
OLD | NEW |