Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: content/renderer/java/gin_java_bridge_object.cc

Issue 259033002: [Android] Implement renderer side of Gin Java Bridge (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments addressed, test added Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
7 #include "base/strings/utf_string_conversions.h"
8 #include "content/common/android/gin_java_bridge_value.h"
9 #include "content/public/renderer/v8_value_converter.h"
10 #include "content/renderer/java/gin_java_bridge_value_converter.h"
11 #include "gin/function_template.h"
12 #include "third_party/WebKit/public/web/WebFrame.h"
13 #include "third_party/WebKit/public/web/WebKit.h"
14
15 namespace content {
16
17 namespace {
18
19 const char kMethodInvocationErrorMessage[] =
20 "Java bridge method invocation error";
21
22 } // namespace
23
24
25 // static
26 GinJavaBridgeObject* GinJavaBridgeObject::Inject(
27 blink::WebFrame* frame,
28 const base::WeakPtr<GinJavaBridgeDispatcher>& dispatcher,
29 const std::string& object_name,
30 GinJavaBridgeDispatcher::ObjectID object_id) {
31 GinJavaBridgeObject* result = new GinJavaBridgeObject(
32 blink::mainThreadIsolate(), dispatcher, object_id);
33 if (InjectExisting(frame, result, object_name)) {
34 return result;
35 } else {
36 delete result;
37 return NULL;
38 }
39 }
40
41 // static
42 GinJavaBridgeObject* GinJavaBridgeObject::InjectAnonymous(
43 const base::WeakPtr<GinJavaBridgeDispatcher>& dispatcher,
44 GinJavaBridgeDispatcher::ObjectID object_id) {
45 return new GinJavaBridgeObject(
46 blink::mainThreadIsolate(), dispatcher, object_id);
47 }
48
49 // static
50 bool GinJavaBridgeObject::InjectExisting(blink::WebFrame* frame,
51 GinJavaBridgeObject* object,
52 const std::string& object_name) {
53 v8::Isolate* isolate = blink::mainThreadIsolate();
54 v8::HandleScope handle_scope(isolate);
55 v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
56 if (context.IsEmpty())
57 return false;
58
59 v8::Context::Scope context_scope(context);
60 v8::Handle<v8::Object> global = context->Global();
61 gin::Handle<GinJavaBridgeObject> controller =
62 gin::CreateHandle(isolate, object);
jochen (gone - plz use gerrit) 2014/05/05 10:55:49 CreateHandle will delete object if it fails to cre
mnaganov (inactive) 2014/05/06 10:54:15 Thanks for pointing this out! I missed that fact t
63 if (controller.IsEmpty())
64 return false;
65
66 global->Set(gin::StringToV8(isolate, object_name), controller.ToV8());
67 return true;
68 }
69
70 GinJavaBridgeObject::GinJavaBridgeObject(
71 v8::Isolate* isolate,
72 const base::WeakPtr<GinJavaBridgeDispatcher>& dispatcher,
73 GinJavaBridgeDispatcher::ObjectID object_id)
74 : gin::NamedPropertyInterceptor(isolate, this),
75 dispatcher_(dispatcher),
76 object_id_(object_id),
77 converter_(new GinJavaBridgeValueConverter()) {
78 }
79
80 GinJavaBridgeObject::~GinJavaBridgeObject() {
81 if (dispatcher_)
82 dispatcher_->OnGinJavaBridgeObjectDeleted(object_id_);
83 }
84
85 gin::ObjectTemplateBuilder GinJavaBridgeObject::GetObjectTemplateBuilder(
86 v8::Isolate* isolate) {
87 return gin::Wrappable<GinJavaBridgeObject>::GetObjectTemplateBuilder(isolate)
88 .AddNamedPropertyInterceptor();
89 }
90
91 v8::Local<v8::Value> GinJavaBridgeObject::GetNamedProperty(
92 v8::Isolate* isolate,
93 const std::string& property) {
94 if (dispatcher_ && dispatcher_->HasJavaMethod(object_id_, property)) {
95 return gin::CreateFunctionTemplate(
96 isolate,
97 base::Bind(&GinJavaBridgeObject::InvokeMethod,
98 base::Unretained(this),
99 property))->GetFunction();
100 } else {
101 return v8::Local<v8::Value>();
102 }
103 }
104
105 std::vector<std::string> GinJavaBridgeObject::EnumerateNamedProperties(
106 v8::Isolate* isolate) {
107 std::set<std::string> method_names;
108 if (dispatcher_) {
109 dispatcher_->GetJavaMethods(object_id_, &method_names);
jochen (gone - plz use gerrit) 2014/05/05 10:55:49 nit. no { }
mnaganov (inactive) 2014/05/06 10:54:15 Done.
110 }
111 return std::vector<std::string> (method_names.begin(), method_names.end());
112 }
113
114 v8::Handle<v8::Value> GinJavaBridgeObject::InvokeMethod(
115 const std::string& name,
116 gin::Arguments* args) {
117 if (!dispatcher_) {
118 args->isolate()->ThrowException(v8::Exception::Error(gin::StringToV8(
119 args->isolate(), kMethodInvocationErrorMessage)));
120 return v8::Undefined(args->isolate());
121 }
122
123 base::ListValue arguments;
124 {
125 v8::HandleScope handle_scope(args->isolate());
126 v8::Handle<v8::Context> context = args->isolate()->GetCurrentContext();
127 v8::Handle<v8::Value> val;
128 while (args->GetNext(&val)) {
129 scoped_ptr<base::Value> arg(converter_->FromV8Value(val, context));
130 if (arg.get()) {
131 arguments.Append(arg.release());
132 } else {
133 arguments.Append(base::Value::CreateNullValue());
134 }
135 }
136 }
137
138 scoped_ptr<base::Value> result =
139 dispatcher_->InvokeJavaMethod(object_id_, name, arguments);
140 if (!result.get()) {
141 args->isolate()->ThrowException(v8::Exception::Error(gin::StringToV8(
142 args->isolate(), kMethodInvocationErrorMessage)));
143 return v8::Undefined(args->isolate());
144 }
145 if (!result->IsType(base::Value::TYPE_BINARY)) {
146 return converter_->ToV8Value(result.get(),
147 args->isolate()->GetCurrentContext());
148 }
149
150 scoped_ptr<const GinJavaBridgeValue> gin_value =
151 GinJavaBridgeValue::FromValue(result.get());
152 if (gin_value->IsType(GinJavaBridgeValue::TYPE_OBJECT_ID)) {
153 GinJavaBridgeObject* result = NULL;
154 GinJavaBridgeDispatcher::ObjectID object_id;
155 if (gin_value->GetAsObjectID(&object_id)) {
156 result = dispatcher_->GetObject(object_id);
157 }
158 if (result) {
159 gin::Handle<GinJavaBridgeObject> controller =
160 gin::CreateHandle(args->isolate(), result);
161 if (controller.IsEmpty())
162 return v8::Undefined(args->isolate());
163 return controller.ToV8();
164 }
165 } else if (gin_value->IsType(GinJavaBridgeValue::TYPE_NONFINITE)) {
166 float float_value;
167 gin_value->GetAsNonFinite(&float_value);
168 return v8::Number::New(args->isolate(), float_value);
169 }
170 return v8::Undefined(args->isolate());
171 }
172
173 gin::WrapperInfo GinJavaBridgeObject::kWrapperInfo = {gin::kEmbedderNativeGin};
174
175 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698