gin_java_bridge_dispatcher_host.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file.
4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/android/java/gin_java_bridge_dispatcher_host.h"
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/android/java_handler_thread.h"
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/android/jni_android.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/android/scoped_java_ref.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/lazy_instance.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/strings/string_number_conversions.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/strings/utf_string_conversions.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/task_runner_util.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/android/java/gin_java_bound_object_delegate.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/android/java/jni_helper.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/common/android/gin_java_bridge_value.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/common/android/hash_set.h"
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/common/gin_java_bridge_messages.h"
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/browser_thread.h"
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/render_frame_host.h"
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/web_contents.h"
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ipc/ipc_message_utils.h"
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if !defined(OS_ANDROID)
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#error "JavaBridge only supports OS_ANDROID"
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace content {
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace {
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// The JavaBridge needs to use a Java thread so the callback
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// will happen on a thread with a prepared Looper.
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass JavaBridgeThread : public base::android::JavaHandlerThread {
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  JavaBridgeThread() : base::android::JavaHandlerThread("JavaBridge") {
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    Start();
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~JavaBridgeThread() {
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    Stop();
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbase::LazyInstance<JavaBridgeThread> g_background_thread =
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    LAZY_INSTANCE_INITIALIZER;
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
48116680a4aac90f2aa7413d9095a592090648e557Ben MurdochGinJavaBridgeDispatcherHost::GinJavaBridgeDispatcherHost(
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    WebContents* web_contents,
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    jobject retained_object_set)
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : WebContentsObserver(web_contents),
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      retained_object_set_(base::android::AttachCurrentThread(),
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           retained_object_set),
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      allow_object_contents_inspection_(true) {
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(retained_object_set);
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
58116680a4aac90f2aa7413d9095a592090648e557Ben MurdochGinJavaBridgeDispatcherHost::~GinJavaBridgeDispatcherHost() {
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::RenderFrameCreated(
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* render_frame_host) {
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (NamedObjectMap::const_iterator iter = named_objects_.begin();
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       iter != named_objects_.end();
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ++iter) {
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    render_frame_host->Send(new GinJavaBridgeMsg_AddNamedObject(
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        render_frame_host->GetRoutingID(), iter->first, iter->second));
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::RenderFrameDeleted(
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* render_frame_host) {
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RemoveHolder(render_frame_host,
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               GinJavaBoundObject::ObjectMap::iterator(&objects_),
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch               objects_.size());
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
78116680a4aac90f2aa7413d9095a592090648e557Ben MurdochGinJavaBoundObject::ObjectID GinJavaBridgeDispatcherHost::AddObject(
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const base::android::JavaRef<jobject>& object,
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const base::android::JavaRef<jclass>& safe_annotation_clazz,
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool is_named,
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* holder) {
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(is_named || holder);
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GinJavaBoundObject::ObjectID object_id;
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  JNIEnv* env = base::android::AttachCurrentThread();
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  JavaObjectWeakGlobalRef ref(env, object.obj());
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (is_named) {
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    object_id = objects_.Add(new scoped_refptr<GinJavaBoundObject>(
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        GinJavaBoundObject::CreateNamed(ref, safe_annotation_clazz)));
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    object_id = objects_.Add(new scoped_refptr<GinJavaBoundObject>(
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        GinJavaBoundObject::CreateTransient(
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            ref, safe_annotation_clazz, holder)));
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if DCHECK_IS_ON
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  {
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GinJavaBoundObject::ObjectID added_object_id;
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK(FindObjectId(object, &added_object_id));
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK_EQ(object_id, added_object_id);
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif  // DCHECK_IS_ON
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::android::ScopedJavaLocalRef<jobject> retained_object_set =
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        retained_object_set_.get(env);
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!retained_object_set.is_null()) {
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    JNI_Java_HashSet_add(env, retained_object_set, object);
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return object_id;
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool GinJavaBridgeDispatcherHost::FindObjectId(
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const base::android::JavaRef<jobject>& object,
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GinJavaBoundObject::ObjectID* object_id) {
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  JNIEnv* env = base::android::AttachCurrentThread();
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (GinJavaBoundObject::ObjectMap::iterator it(&objects_); !it.IsAtEnd();
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       it.Advance()) {
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (env->IsSameObject(
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            object.obj(),
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            it.GetCurrentValue()->get()->GetLocalRef(env).obj())) {
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      *object_id = it.GetCurrentKey();
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return true;
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return false;
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
126116680a4aac90f2aa7413d9095a592090648e557Ben MurdochJavaObjectWeakGlobalRef GinJavaBridgeDispatcherHost::GetObjectWeakRef(
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GinJavaBoundObject::ObjectID object_id) {
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<GinJavaBoundObject>* result = objects_.Lookup(object_id);
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<GinJavaBoundObject> object(result ? *result : NULL);
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (object.get())
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return object->GetWeakRef();
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  else
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return JavaObjectWeakGlobalRef();
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
136116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::RemoveHolder(
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* holder,
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GinJavaBoundObject::ObjectMap::iterator& from,
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    size_t count) {
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  JNIEnv* env = base::android::AttachCurrentThread();
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::android::ScopedJavaLocalRef<jobject> retained_object_set =
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      retained_object_set_.get(env);
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  size_t i = 0;
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (GinJavaBoundObject::ObjectMap::iterator it(from);
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       !it.IsAtEnd() && i < count;
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       it.Advance(), ++i) {
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_refptr<GinJavaBoundObject> object(*it.GetCurrentValue());
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (object->IsNamed())
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      continue;
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    object->RemoveHolder(holder);
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!object->HasHolders()) {
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (!retained_object_set.is_null()) {
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        JNI_Java_HashSet_remove(
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            env, retained_object_set, object->GetLocalRef(env));
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      }
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      objects_.Remove(it.GetCurrentKey());
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::AddNamedObject(
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& name,
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const base::android::JavaRef<jobject>& object,
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const base::android::JavaRef<jclass>& safe_annotation_clazz) {
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GinJavaBoundObject::ObjectID object_id;
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  NamedObjectMap::iterator iter = named_objects_.find(name);
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool existing_object = FindObjectId(object, &object_id);
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (existing_object && iter != named_objects_.end() &&
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      iter->second == object_id) {
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Nothing to do.
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (iter != named_objects_.end()) {
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RemoveNamedObject(iter->first);
176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (existing_object) {
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    (*objects_.Lookup(object_id))->AddName();
179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    object_id = AddObject(object, safe_annotation_clazz, true, NULL);
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  named_objects_[name] = object_id;
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  web_contents()->SendToAllFrames(
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new GinJavaBridgeMsg_AddNamedObject(MSG_ROUTING_NONE, name, object_id));
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
188116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::RemoveNamedObject(
189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& name) {
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  NamedObjectMap::iterator iter = named_objects_.find(name);
192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (iter == named_objects_.end())
193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // |name| may come from |named_objects_|. Make a copy of name so that if
1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // |name| is from |named_objects_| it'll be valid after the remove below.
1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const std::string copied_name(name);
1986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(iter->second));
200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  named_objects_.erase(iter);
201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  object->RemoveName();
202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Not erasing from the objects map, as we can still receive method
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // invocation requests for this object, and they should work until the
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // java object is gone.
206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!object->IsNamed()) {
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    JNIEnv* env = base::android::AttachCurrentThread();
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::android::ScopedJavaLocalRef<jobject> retained_object_set =
209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        retained_object_set_.get(env);
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!retained_object_set.is_null()) {
211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      JNI_Java_HashSet_remove(
212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          env, retained_object_set, object->GetLocalRef(env));
213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  web_contents()->SendToAllFrames(
2176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      new GinJavaBridgeMsg_RemoveNamedObject(MSG_ROUTING_NONE, copied_name));
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
220116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::SetAllowObjectContentsInspection(bool allow) {
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  allow_object_contents_inspection_ = allow;
222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
224116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::DocumentAvailableInMainFrame() {
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Called when the window object has been cleared in the main frame.
227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // That means, all sub-frames have also been cleared, so only named
228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // objects survived.
229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  JNIEnv* env = base::android::AttachCurrentThread();
230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::android::ScopedJavaLocalRef<jobject> retained_object_set =
231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      retained_object_set_.get(env);
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!retained_object_set.is_null()) {
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    JNI_Java_HashSet_clear(env, retained_object_set);
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // We also need to add back the named objects we have so far as they
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // should survive navigations.
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (GinJavaBoundObject::ObjectMap::iterator it(&objects_); !it.IsAtEnd();
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       it.Advance()) {
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_refptr<GinJavaBoundObject> object(*it.GetCurrentValue());
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (object->IsNamed()) {
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (!retained_object_set.is_null()) {
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        JNI_Java_HashSet_add(
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            env, retained_object_set, object->GetLocalRef(env));
245116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      }
246116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    } else {
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      objects_.Remove(it.GetCurrentKey());
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
251116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
252116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace {
253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
254116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// TODO(mnaganov): Implement passing of a parameter into sync message handlers.
255116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass MessageForwarder : public IPC::Sender {
256116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
257116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MessageForwarder(GinJavaBridgeDispatcherHost* gjbdh,
258116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   RenderFrameHost* render_frame_host)
259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      : gjbdh_(gjbdh), render_frame_host_(render_frame_host) {}
260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnGetMethods(GinJavaBoundObject::ObjectID object_id,
261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    IPC::Message* reply_msg) {
262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    gjbdh_->OnGetMethods(render_frame_host_,
263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                         object_id,
264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                         reply_msg);
265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnHasMethod(GinJavaBoundObject::ObjectID object_id,
267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   const std::string& method_name,
268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   IPC::Message* reply_msg) {
269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    gjbdh_->OnHasMethod(render_frame_host_,
270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        object_id,
271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        method_name,
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        reply_msg);
273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
274116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnInvokeMethod(GinJavaBoundObject::ObjectID object_id,
275116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      const std::string& method_name,
276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      const base::ListValue& arguments,
277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      IPC::Message* reply_msg) {
278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    gjbdh_->OnInvokeMethod(render_frame_host_,
279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           object_id,
280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           method_name,
281116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           arguments,
282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           reply_msg);
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual bool Send(IPC::Message* msg) OVERRIDE {
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    NOTREACHED();
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GinJavaBridgeDispatcherHost* gjbdh_;
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RenderFrameHost* render_frame_host_;
291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
293116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool GinJavaBridgeDispatcherHost::OnMessageReceived(
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const IPC::Message& message,
297116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* render_frame_host) {
298116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(render_frame_host);
299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool handled = true;
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  MessageForwarder forwarder(this, render_frame_host);
301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(GinJavaBridgeDispatcherHost, message,
302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   render_frame_host)
303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC_MESSAGE_FORWARD_DELAY_REPLY(GinJavaBridgeHostMsg_GetMethods,
304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                    &forwarder,
305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                    MessageForwarder::OnGetMethods)
306116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC_MESSAGE_FORWARD_DELAY_REPLY(GinJavaBridgeHostMsg_HasMethod,
307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                    &forwarder,
308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                    MessageForwarder::OnHasMethod)
309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC_MESSAGE_FORWARD_DELAY_REPLY(GinJavaBridgeHostMsg_InvokeMethod,
310116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                    &forwarder,
311116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                    MessageForwarder::OnInvokeMethod)
312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC_MESSAGE_HANDLER(GinJavaBridgeHostMsg_ObjectWrapperDeleted,
313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        OnObjectWrapperDeleted)
314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC_MESSAGE_UNHANDLED(handled = false)
315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  IPC_END_MESSAGE_MAP()
316116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return handled;
317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
319116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace {
320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
321116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass IsValidRenderFrameHostHelper
322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : public base::RefCounted<IsValidRenderFrameHostHelper> {
323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  explicit IsValidRenderFrameHostHelper(RenderFrameHost* rfh_to_match)
325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      : rfh_to_match_(rfh_to_match), rfh_found_(false) {}
326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool rfh_found() { return rfh_found_; }
328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnFrame(RenderFrameHost* rfh) {
330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (rfh_to_match_ == rfh) rfh_found_ = true;
331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  friend class base::RefCounted<IsValidRenderFrameHostHelper>;
335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
336116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ~IsValidRenderFrameHostHelper() {}
337116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
338116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RenderFrameHost* rfh_to_match_;
339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool rfh_found_;
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(IsValidRenderFrameHostHelper);
342116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
344116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace
345116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
346116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool GinJavaBridgeDispatcherHost::IsValidRenderFrameHost(
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* render_frame_host) {
348116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<IsValidRenderFrameHostHelper> helper =
349116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new IsValidRenderFrameHostHelper(render_frame_host);
350116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  web_contents()->ForEachFrame(
351116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&IsValidRenderFrameHostHelper::OnFrame, helper));
352116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return helper->rfh_found();
353116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
354116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
355116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::SendReply(
356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* render_frame_host,
357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::Message* reply_msg) {
358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
359116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (IsValidRenderFrameHost(render_frame_host)) {
360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    render_frame_host->Send(reply_msg);
361116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
362116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    delete reply_msg;
363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
365116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
366116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::OnGetMethods(
367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* render_frame_host,
368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GinJavaBoundObject::ObjectID object_id,
369116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::Message* reply_msg) {
370116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(render_frame_host);
372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!allow_object_contents_inspection_) {
373116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::WriteParam(reply_msg, std::set<std::string>());
374116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    render_frame_host->Send(reply_msg);
375116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id));
378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!object) {
379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    LOG(ERROR) << "WebView: Unknown object: " << object_id;
380116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::WriteParam(reply_msg, std::set<std::string>());
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    render_frame_host->Send(reply_msg);
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::PostTaskAndReplyWithResult(
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      g_background_thread.Get().message_loop()->message_loop_proxy(),
386116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
387116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&GinJavaBoundObject::GetMethodNames, object),
388116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&GinJavaBridgeDispatcherHost::SendMethods,
389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 AsWeakPtr(),
390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 render_frame_host,
391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 reply_msg));
392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
394116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::SendMethods(
395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* render_frame_host,
396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::Message* reply_msg,
397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::set<std::string>& method_names) {
398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  IPC::WriteParam(reply_msg, method_names);
399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SendReply(render_frame_host, reply_msg);
400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
401116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
402116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::OnHasMethod(
403116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* render_frame_host,
404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GinJavaBoundObject::ObjectID object_id,
405116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& method_name,
406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::Message* reply_msg) {
407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(render_frame_host);
409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id));
410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!object) {
411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    LOG(ERROR) << "WebView: Unknown object: " << object_id;
412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::WriteParam(reply_msg, false);
413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    render_frame_host->Send(reply_msg);
414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::PostTaskAndReplyWithResult(
417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      g_background_thread.Get().message_loop()->message_loop_proxy(),
418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FROM_HERE,
419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&GinJavaBoundObject::HasMethod, object, method_name),
420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&GinJavaBridgeDispatcherHost::SendHasMethodReply,
421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 AsWeakPtr(),
422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 render_frame_host,
423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 reply_msg));
424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
426116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::SendHasMethodReply(
427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* render_frame_host,
428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::Message* reply_msg,
429116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bool result) {
430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  IPC::WriteParam(reply_msg, result);
431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SendReply(render_frame_host, reply_msg);
432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
434116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::OnInvokeMethod(
435116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* render_frame_host,
436116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GinJavaBoundObject::ObjectID object_id,
437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& method_name,
438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const base::ListValue& arguments,
439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::Message* reply_msg) {
440116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(render_frame_host);
442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id));
443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!object) {
444116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    LOG(ERROR) << "WebView: Unknown object: " << object_id;
445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::ListValue result;
446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    result.Append(base::Value::CreateNullValue());
447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::WriteParam(reply_msg, result);
448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::WriteParam(reply_msg, kGinJavaBridgeUnknownObjectId);
449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    render_frame_host->Send(reply_msg);
450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_refptr<GinJavaMethodInvocationHelper> result =
453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      new GinJavaMethodInvocationHelper(
454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          make_scoped_ptr(new GinJavaBoundObjectDelegate(object))
455116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              .PassAs<GinJavaMethodInvocationHelper::ObjectDelegate>(),
456116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          method_name,
457116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          arguments);
458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  result->Init(this);
459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  g_background_thread.Get()
460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      .message_loop()
461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ->message_loop_proxy()
462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ->PostTaskAndReply(
463116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          FROM_HERE,
464116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          base::Bind(&GinJavaMethodInvocationHelper::Invoke, result),
465116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          base::Bind(
466116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              &GinJavaBridgeDispatcherHost::ProcessMethodInvocationResult,
467116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              AsWeakPtr(),
468116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              render_frame_host,
469116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              reply_msg,
470116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              result));
471116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
472116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
473116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::ProcessMethodInvocationResult(
474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* render_frame_host,
475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::Message* reply_msg,
476116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_refptr<GinJavaMethodInvocationHelper> result) {
477116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (result->HoldsPrimitiveResult()) {
478116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::WriteParam(reply_msg, result->GetPrimitiveResult());
479116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::WriteParam(reply_msg, result->GetInvocationError());
480116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SendReply(render_frame_host, reply_msg);
481116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
482116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ProcessMethodInvocationObjectResult(render_frame_host, reply_msg, result);
483116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
484116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
485116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
486116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::ProcessMethodInvocationObjectResult(
487116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* render_frame_host,
488116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::Message* reply_msg,
489116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_refptr<GinJavaMethodInvocationHelper> result) {
490116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
491116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!IsValidRenderFrameHost(render_frame_host)) {
492116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    delete reply_msg;
493116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
494116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
495116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::ListValue wrapped_result;
496116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!result->GetObjectResult().is_null()) {
497116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GinJavaBoundObject::ObjectID returned_object_id;
498116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (FindObjectId(result->GetObjectResult(), &returned_object_id)) {
499116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      (*objects_.Lookup(returned_object_id))->AddHolder(render_frame_host);
500116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    } else {
501116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      returned_object_id = AddObject(result->GetObjectResult(),
502116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                     result->GetSafeAnnotationClass(),
503116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                     false,
504116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                     render_frame_host);
505116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
506116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    wrapped_result.Append(
507116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        GinJavaBridgeValue::CreateObjectIDValue(returned_object_id).release());
508116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
509116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    wrapped_result.Append(base::Value::CreateNullValue());
510116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
511116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  IPC::WriteParam(reply_msg, wrapped_result);
512116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  IPC::WriteParam(reply_msg, result->GetInvocationError());
513116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  render_frame_host->Send(reply_msg);
514116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
515116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
516116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid GinJavaBridgeDispatcherHost::OnObjectWrapperDeleted(
517116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RenderFrameHost* render_frame_host,
518116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GinJavaBoundObject::ObjectID object_id) {
519116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
520116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(render_frame_host);
521116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (objects_.Lookup(object_id)) {
522116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GinJavaBoundObject::ObjectMap::iterator iter(&objects_);
523116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    while (!iter.IsAtEnd() && iter.GetCurrentKey() != object_id)
524116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      iter.Advance();
525116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK(!iter.IsAtEnd());
526116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RemoveHolder(render_frame_host, iter, 1);
527116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
528116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
529116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace content
531