blob: 03af04d1f4f8d5644981c7e82919aae436f7a1a1 [file] [log] [blame]
[email protected]b8b670812014-05-27 18:10:061// 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 Marchandf8cbfab2019-01-25 16:02:307#include "base/bind.h"
mnaganovae5f6742015-07-15 00:48:148#include "content/common/gin_java_bridge_messages.h"
9#include "content/public/renderer/render_thread.h"
mnaganov9e4422e2015-03-20 14:27:0210#include "content/renderer/java/gin_java_function_invocation_helper.h"
[email protected]b8b670812014-05-27 18:10:0611#include "gin/function_template.h"
Blink Reformata30d4232018-04-07 15:31:0612#include "third_party/blink/public/web/blink.h"
13#include "third_party/blink/public/web/web_local_frame.h"
[email protected]b8b670812014-05-27 18:10:0614
15namespace content {
16
[email protected]b8b670812014-05-27 18:10:0617// static
18GinJavaBridgeObject* GinJavaBridgeObject::InjectNamed(
lukaszadf18ba762017-06-09 22:24:3019 blink::WebLocalFrame* frame,
[email protected]b8b670812014-05-27 18:10:0620 const base::WeakPtr<GinJavaBridgeDispatcher>& dispatcher,
21 const std::string& object_name,
22 GinJavaBridgeDispatcher::ObjectID object_id) {
Blink Reformat1c4d759e2017-04-09 16:34:5423 v8::Isolate* isolate = blink::MainThreadIsolate();
[email protected]b8b670812014-05-27 18:10:0624 v8::HandleScope handle_scope(isolate);
Blink Reformat1c4d759e2017-04-09 16:34:5425 v8::Local<v8::Context> context = frame->MainWorldScriptContext();
[email protected]b8b670812014-05-27 18:10:0626 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.s750d68f2015-04-30 07:32:4133 v8::Local<v8::Object> global = context->Global();
[email protected]b8b670812014-05-27 18:10:0634 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
46GinJavaBridgeObject* GinJavaBridgeObject::InjectAnonymous(
47 const base::WeakPtr<GinJavaBridgeDispatcher>& dispatcher,
48 GinJavaBridgeDispatcher::ObjectID object_id) {
Blink Reformat1c4d759e2017-04-09 16:34:5449 return new GinJavaBridgeObject(blink::MainThreadIsolate(), dispatcher,
50 object_id);
[email protected]b8b670812014-05-27 18:10:0651}
52
53GinJavaBridgeObject::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),
mnaganovae5f6742015-07-15 00:48:1460 frame_routing_id_(dispatcher_->routing_id()),
mnaganov8f8de9cf62015-03-03 16:35:4161 template_cache_(isolate) {
[email protected]b8b670812014-05-27 18:10:0662}
63
64GinJavaBridgeObject::~GinJavaBridgeObject() {
mnaganovae5f6742015-07-15 00:48:1465 if (dispatcher_) {
mnaganov9e4422e2015-03-20 14:27:0266 dispatcher_->OnGinJavaBridgeObjectDeleted(this);
mnaganovae5f6742015-07-15 00:48:1467 } 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]b8b670812014-05-27 18:10:0674}
75
76gin::ObjectTemplateBuilder GinJavaBridgeObject::GetObjectTemplateBuilder(
77 v8::Isolate* isolate) {
78 return gin::Wrappable<GinJavaBridgeObject>::GetObjectTemplateBuilder(isolate)
79 .AddNamedPropertyInterceptor();
80}
81
82v8::Local<v8::Value> GinJavaBridgeObject::GetNamedProperty(
83 v8::Isolate* isolate,
84 const std::string& property) {
[email protected]ab3be5a112014-07-10 16:22:0885 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 Elphick9c321a92018-11-26 17:27:3393 if (known_methods_[property]) {
94 return GetFunctionTemplate(isolate, property)
95 ->GetFunction(isolate->GetCurrentContext())
96 .FromMaybe(v8::Local<v8::Value>());
97 } else {
[email protected]b8b670812014-05-27 18:10:0698 return v8::Local<v8::Value>();
Dan Elphick9c321a92018-11-26 17:27:3399 }
[email protected]b8b670812014-05-27 18:10:06100}
101
102std::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
mnaganov8f8de9cf62015-03-03 16:35:41110v8::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(
mnaganov9e4422e2015-03-20 14:27:02117 isolate, base::Bind(&GinJavaFunctionInvocationHelper::Invoke,
118 base::Owned(new GinJavaFunctionInvocationHelper(
119 name, dispatcher_))));
mnaganov8f8de9cf62015-03-03 16:35:41120 template_cache_.Set(name, function_template);
121 return function_template;
122}
123
[email protected]b8b670812014-05-27 18:10:06124gin::WrapperInfo GinJavaBridgeObject::kWrapperInfo = {gin::kEmbedderNativeGin};
125
126} // namespace content