1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file. 4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/renderer/java/gin_java_bridge_dispatcher.h" 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/common/gin_java_bridge_messages.h" 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/renderer/render_frame.h" 11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/renderer/java/gin_java_bridge_object.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/WebKit/public/web/WebLocalFrame.h" 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h" 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)namespace content { 16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)GinJavaBridgeDispatcher::GinJavaBridgeDispatcher(RenderFrame* render_frame) 186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) : RenderFrameObserver(render_frame), 196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) inside_did_clear_window_object_(false) { 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)GinJavaBridgeDispatcher::~GinJavaBridgeDispatcher() { 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool GinJavaBridgeDispatcher::OnMessageReceived(const IPC::Message& msg) { 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool handled = true; 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(GinJavaBridgeDispatcher, msg) 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_MESSAGE_HANDLER(GinJavaBridgeMsg_AddNamedObject, OnAddNamedObject) 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_MESSAGE_HANDLER(GinJavaBridgeMsg_RemoveNamedObject, OnRemoveNamedObject) 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IPC_END_MESSAGE_MAP() 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return handled; 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)namespace { 366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)class ScopedFlag { 386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) public: 396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) ScopedFlag(bool* flag) : flag_(flag) { 406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DCHECK(!*flag_); 416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) *flag_ = true; 426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) ~ScopedFlag() { 446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DCHECK(*flag_); 456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) *flag_ = false; 466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) private: 486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) bool* flag_; 496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ScopedFlag); 516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}; 526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} // namespace 546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GinJavaBridgeDispatcher::DidClearWindowObject() { 566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Accessing window object when adding properties to it may trigger 576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // a nested call to DidClearWindowObject. 586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (inside_did_clear_window_object_) 596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return; 606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) ScopedFlag flag(&inside_did_clear_window_object_); 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (NamedObjectMap::const_iterator iter = named_objects_.begin(); 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) iter != named_objects_.end(); ++iter) { 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Always create a new GinJavaBridgeObject, so we don't pull any of the V8 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // wrapper's custom properties into the context of the page we have 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // navigated to. The old GinJavaBridgeObject will be automatically 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // deleted after its wrapper will be collected. 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // On the browser side, we ignore wrapper deletion events for named objects, 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // as they are only removed upon embedder's request (RemoveNamedObject). 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (objects_.Lookup(iter->second)) 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) objects_.Remove(iter->second); 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GinJavaBridgeObject* object = GinJavaBridgeObject::InjectNamed( 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) render_frame()->GetWebFrame(), AsWeakPtr(), iter->first, iter->second); 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (object) { 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) objects_.AddWithID(object, iter->second); 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Inform the host about wrapper creation failure. 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) render_frame()->Send(new GinJavaBridgeHostMsg_ObjectWrapperDeleted( 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) routing_id(), iter->second)); 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GinJavaBridgeDispatcher::OnAddNamedObject( 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& name, 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ObjectID object_id) { 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Added objects only become available after page reload, so here they 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // are only added into the internal map. 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) named_objects_.insert(std::make_pair(name, object_id)); 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GinJavaBridgeDispatcher::OnRemoveNamedObject(const std::string& name) { 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Removal becomes in effect on next reload. We simply removing the entry 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // from the map here. 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NamedObjectMap::iterator iter = named_objects_.find(name); 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(iter != named_objects_.end()); 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) named_objects_.erase(iter); 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GinJavaBridgeDispatcher::GetJavaMethods( 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ObjectID object_id, 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::set<std::string>* methods) { 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) render_frame()->Send(new GinJavaBridgeHostMsg_GetMethods( 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) routing_id(), object_id, methods)); 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool GinJavaBridgeDispatcher::HasJavaMethod(ObjectID object_id, 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& method_name) { 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool result; 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) render_frame()->Send(new GinJavaBridgeHostMsg_HasMethod( 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) routing_id(), object_id, method_name, &result)); 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return result; 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<base::Value> GinJavaBridgeDispatcher::InvokeJavaMethod( 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ObjectID object_id, 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& method_name, 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const base::ListValue& arguments, 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GinJavaBridgeError* error) { 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::ListValue result_wrapper; 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) render_frame()->Send( 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new GinJavaBridgeHostMsg_InvokeMethod(routing_id(), 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) object_id, 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) method_name, 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) arguments, 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &result_wrapper, 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch error)); 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Value* result; 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (result_wrapper.Get(0, &result)) { 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<base::Value>(result->DeepCopy()); 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<base::Value>(); 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)GinJavaBridgeObject* GinJavaBridgeDispatcher::GetObject(ObjectID object_id) { 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GinJavaBridgeObject* result = objects_.Lookup(object_id); 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!result) { 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) result = GinJavaBridgeObject::InjectAnonymous(AsWeakPtr(), object_id); 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (result) 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) objects_.AddWithID(result, object_id); 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return result; 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void GinJavaBridgeDispatcher::OnGinJavaBridgeObjectDeleted(ObjectID object_id) { 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!objects_.Lookup(object_id)) 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) objects_.Remove(object_id); 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) render_frame()->Send( 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new GinJavaBridgeHostMsg_ObjectWrapperDeleted(routing_id(), object_id)); 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} // namespace content 154