[email protected] | b8b67081 | 2014-05-27 18:10:06 | [diff] [blame] | 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 | #include "content/renderer/java/gin_java_bridge_object.h" |
| 6 | |
Sebastien Marchand | f8cbfab | 2019-01-25 16:02:30 | [diff] [blame] | 7 | #include "base/bind.h" |
mnaganov | ae5f674 | 2015-07-15 00:48:14 | [diff] [blame] | 8 | #include "content/common/gin_java_bridge_messages.h" |
| 9 | #include "content/public/renderer/render_thread.h" |
mnaganov | 9e4422e | 2015-03-20 14:27:02 | [diff] [blame] | 10 | #include "content/renderer/java/gin_java_function_invocation_helper.h" |
[email protected] | b8b67081 | 2014-05-27 18:10:06 | [diff] [blame] | 11 | #include "gin/function_template.h" |
Blink Reformat | a30d423 | 2018-04-07 15:31:06 | [diff] [blame] | 12 | #include "third_party/blink/public/web/blink.h" |
| 13 | #include "third_party/blink/public/web/web_local_frame.h" |
[email protected] | b8b67081 | 2014-05-27 18:10:06 | [diff] [blame] | 14 | |
| 15 | namespace content { |
| 16 | |
[email protected] | b8b67081 | 2014-05-27 18:10:06 | [diff] [blame] | 17 | // static |
| 18 | GinJavaBridgeObject* GinJavaBridgeObject::InjectNamed( |
lukasza | df18ba76 | 2017-06-09 22:24:30 | [diff] [blame] | 19 | blink::WebLocalFrame* frame, |
[email protected] | b8b67081 | 2014-05-27 18:10:06 | [diff] [blame] | 20 | const base::WeakPtr<GinJavaBridgeDispatcher>& dispatcher, |
| 21 | const std::string& object_name, |
| 22 | GinJavaBridgeDispatcher::ObjectID object_id) { |
Blink Reformat | 1c4d759e | 2017-04-09 16:34:54 | [diff] [blame] | 23 | v8::Isolate* isolate = blink::MainThreadIsolate(); |
[email protected] | b8b67081 | 2014-05-27 18:10:06 | [diff] [blame] | 24 | v8::HandleScope handle_scope(isolate); |
Blink Reformat | 1c4d759e | 2017-04-09 16:34:54 | [diff] [blame] | 25 | v8::Local<v8::Context> context = frame->MainWorldScriptContext(); |
[email protected] | b8b67081 | 2014-05-27 18:10:06 | [diff] [blame] | 26 | if (context.IsEmpty()) |
| 27 | return NULL; |
| 28 | |
| 29 | GinJavaBridgeObject* object = |
| 30 | new GinJavaBridgeObject(isolate, dispatcher, object_id); |
| 31 | |
| 32 | v8::Context::Scope context_scope(context); |
deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 33 | v8::Local<v8::Object> global = context->Global(); |
[email protected] | b8b67081 | 2014-05-27 18:10:06 | [diff] [blame] | 34 | gin::Handle<GinJavaBridgeObject> controller = |
| 35 | gin::CreateHandle(isolate, object); |
| 36 | // WrappableBase instance deletes itself in case of a wrapper |
| 37 | // creation failure, thus there is no need to delete |object|. |
| 38 | if (controller.IsEmpty()) |
| 39 | return NULL; |
| 40 | |
| 41 | global->Set(gin::StringToV8(isolate, object_name), controller.ToV8()); |
| 42 | return object; |
| 43 | } |
| 44 | |
| 45 | // static |
| 46 | GinJavaBridgeObject* GinJavaBridgeObject::InjectAnonymous( |
| 47 | const base::WeakPtr<GinJavaBridgeDispatcher>& dispatcher, |
| 48 | GinJavaBridgeDispatcher::ObjectID object_id) { |
Blink Reformat | 1c4d759e | 2017-04-09 16:34:54 | [diff] [blame] | 49 | return new GinJavaBridgeObject(blink::MainThreadIsolate(), dispatcher, |
| 50 | object_id); |
[email protected] | b8b67081 | 2014-05-27 18:10:06 | [diff] [blame] | 51 | } |
| 52 | |
| 53 | GinJavaBridgeObject::GinJavaBridgeObject( |
| 54 | v8::Isolate* isolate, |
| 55 | const base::WeakPtr<GinJavaBridgeDispatcher>& dispatcher, |
| 56 | GinJavaBridgeDispatcher::ObjectID object_id) |
| 57 | : gin::NamedPropertyInterceptor(isolate, this), |
| 58 | dispatcher_(dispatcher), |
| 59 | object_id_(object_id), |
mnaganov | ae5f674 | 2015-07-15 00:48:14 | [diff] [blame] | 60 | frame_routing_id_(dispatcher_->routing_id()), |
mnaganov | 8f8de9cf6 | 2015-03-03 16:35:41 | [diff] [blame] | 61 | template_cache_(isolate) { |
[email protected] | b8b67081 | 2014-05-27 18:10:06 | [diff] [blame] | 62 | } |
| 63 | |
| 64 | GinJavaBridgeObject::~GinJavaBridgeObject() { |
mnaganov | ae5f674 | 2015-07-15 00:48:14 | [diff] [blame] | 65 | if (dispatcher_) { |
mnaganov | 9e4422e | 2015-03-20 14:27:02 | [diff] [blame] | 66 | dispatcher_->OnGinJavaBridgeObjectDeleted(this); |
mnaganov | ae5f674 | 2015-07-15 00:48:14 | [diff] [blame] | 67 | } else { |
| 68 | // A wrapper can outlive a render frame, and thus the dispatcher. |
| 69 | // Note that we intercept GinJavaBridgeHostMsg messages in a browser filter |
| 70 | // thus it's OK to send the message with a routing id of a ceased frame. |
| 71 | RenderThread::Get()->Send(new GinJavaBridgeHostMsg_ObjectWrapperDeleted( |
| 72 | frame_routing_id_, object_id_)); |
| 73 | } |
[email protected] | b8b67081 | 2014-05-27 18:10:06 | [diff] [blame] | 74 | } |
| 75 | |
| 76 | gin::ObjectTemplateBuilder GinJavaBridgeObject::GetObjectTemplateBuilder( |
| 77 | v8::Isolate* isolate) { |
| 78 | return gin::Wrappable<GinJavaBridgeObject>::GetObjectTemplateBuilder(isolate) |
| 79 | .AddNamedPropertyInterceptor(); |
| 80 | } |
| 81 | |
| 82 | v8::Local<v8::Value> GinJavaBridgeObject::GetNamedProperty( |
| 83 | v8::Isolate* isolate, |
| 84 | const std::string& property) { |
[email protected] | ab3be5a11 | 2014-07-10 16:22:08 | [diff] [blame] | 85 | std::map<std::string, bool>::iterator method_pos = |
| 86 | known_methods_.find(property); |
| 87 | if (method_pos == known_methods_.end()) { |
| 88 | if (!dispatcher_) { |
| 89 | return v8::Local<v8::Value>(); |
| 90 | } |
| 91 | known_methods_[property] = dispatcher_->HasJavaMethod(object_id_, property); |
| 92 | } |
Dan Elphick | 9c321a9 | 2018-11-26 17:27:33 | [diff] [blame] | 93 | if (known_methods_[property]) { |
| 94 | return GetFunctionTemplate(isolate, property) |
| 95 | ->GetFunction(isolate->GetCurrentContext()) |
| 96 | .FromMaybe(v8::Local<v8::Value>()); |
| 97 | } else { |
[email protected] | b8b67081 | 2014-05-27 18:10:06 | [diff] [blame] | 98 | return v8::Local<v8::Value>(); |
Dan Elphick | 9c321a9 | 2018-11-26 17:27:33 | [diff] [blame] | 99 | } |
[email protected] | b8b67081 | 2014-05-27 18:10:06 | [diff] [blame] | 100 | } |
| 101 | |
| 102 | std::vector<std::string> GinJavaBridgeObject::EnumerateNamedProperties( |
| 103 | v8::Isolate* isolate) { |
| 104 | std::set<std::string> method_names; |
| 105 | if (dispatcher_) |
| 106 | dispatcher_->GetJavaMethods(object_id_, &method_names); |
| 107 | return std::vector<std::string> (method_names.begin(), method_names.end()); |
| 108 | } |
| 109 | |
mnaganov | 8f8de9cf6 | 2015-03-03 16:35:41 | [diff] [blame] | 110 | v8::Local<v8::FunctionTemplate> GinJavaBridgeObject::GetFunctionTemplate( |
| 111 | v8::Isolate* isolate, |
| 112 | const std::string& name) { |
| 113 | v8::Local<v8::FunctionTemplate> function_template = template_cache_.Get(name); |
| 114 | if (!function_template.IsEmpty()) |
| 115 | return function_template; |
| 116 | function_template = gin::CreateFunctionTemplate( |
mnaganov | 9e4422e | 2015-03-20 14:27:02 | [diff] [blame] | 117 | isolate, base::Bind(&GinJavaFunctionInvocationHelper::Invoke, |
| 118 | base::Owned(new GinJavaFunctionInvocationHelper( |
| 119 | name, dispatcher_)))); |
mnaganov | 8f8de9cf6 | 2015-03-03 16:35:41 | [diff] [blame] | 120 | template_cache_.Set(name, function_template); |
| 121 | return function_template; |
| 122 | } |
| 123 | |
[email protected] | b8b67081 | 2014-05-27 18:10:06 | [diff] [blame] | 124 | gin::WrapperInfo GinJavaBridgeObject::kWrapperInfo = {gin::kEmbedderNativeGin}; |
| 125 | |
| 126 | } // namespace content |