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

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: 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/float_util.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "content/common/android/gin_java_bridge_value.h"
11 #include "content/public/renderer/v8_value_converter.h"
12 #include "gin/function_template.h"
13 #include "third_party/WebKit/public/web/WebArrayBufferView.h"
14 #include "third_party/WebKit/public/web/WebFrame.h"
15 #include "third_party/WebKit/public/web/WebKit.h"
16
17 namespace content {
18
19 namespace {
20
21 const char kMethodInvocationErrorMessage[] =
22 "Java bridge method invocation error";
23
24 } // namespace
25
26
27 // static
28 GinJavaBridgeObject* GinJavaBridgeObject::Inject(
29 blink::WebFrame* frame,
30 const base::WeakPtr<GinJavaBridgeDispatcher>& dispatcher,
31 const std::string& object_name,
32 GinJavaBridgeDispatcher::ObjectID object_id) {
33 GinJavaBridgeObject* result = new GinJavaBridgeObject(
34 blink::mainThreadIsolate(), dispatcher, object_id);
35 if (InjectExisting(frame, result, object_name)) {
36 return result;
37 } else {
38 delete result;
39 return NULL;
40 }
41 }
42
43 // static
44 GinJavaBridgeObject* GinJavaBridgeObject::InjectAnonymous(
45 const base::WeakPtr<GinJavaBridgeDispatcher>& dispatcher,
46 GinJavaBridgeDispatcher::ObjectID object_id) {
47 return new GinJavaBridgeObject(
48 blink::mainThreadIsolate(), dispatcher, object_id);
49 }
50
51 // static
52 bool GinJavaBridgeObject::InjectExisting(blink::WebFrame* frame,
53 GinJavaBridgeObject* object,
54 const std::string& object_name) {
55 v8::Isolate* isolate = blink::mainThreadIsolate();
56 v8::HandleScope handle_scope(isolate);
57 v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
58 if (context.IsEmpty())
59 return false;
60
61 v8::Context::Scope context_scope(context);
62 v8::Handle<v8::Object> global = context->Global();
63 gin::Handle<GinJavaBridgeObject> controller =
64 gin::CreateHandle(isolate, object);
jochen (gone - plz use gerrit) 2014/04/29 13:50:16 return false here if controller.IsEmpty()
mnaganov (inactive) 2014/04/30 16:46:26 Done here and in line 164.
65 global->Set(gin::StringToV8(isolate, object_name), controller.ToV8());
66 return true;
67 }
68
69 GinJavaBridgeObject::GinJavaBridgeObject(
70 v8::Isolate* isolate,
71 const base::WeakPtr<GinJavaBridgeDispatcher>& dispatcher,
72 GinJavaBridgeDispatcher::ObjectID object_id)
73 : gin::NamedPropertyInterceptor(isolate, this),
74 dispatcher_(dispatcher),
75 object_id_(object_id),
76 converter_(V8ValueConverter::create()) {
77 converter_->SetDateAllowed(false);
78 converter_->SetRegExpAllowed(false);
79 converter_->SetFunctionAllowed(true);
80 converter_->SetStrategy(this);
81 }
82
83 GinJavaBridgeObject::~GinJavaBridgeObject() {
84 if (dispatcher_)
85 dispatcher_->OnGinJavaBridgeObjectDeleted(object_id_);
86 }
87
88 gin::ObjectTemplateBuilder GinJavaBridgeObject::GetObjectTemplateBuilder(
89 v8::Isolate* isolate) {
90 return gin::Wrappable<GinJavaBridgeObject>::GetObjectTemplateBuilder(isolate)
91 .AddNamedPropertyInterceptor();
92 }
93
94 v8::Local<v8::Value> GinJavaBridgeObject::GetNamedProperty(
95 v8::Isolate* isolate,
96 const std::string& property) {
97 if (dispatcher_ && dispatcher_->HasJavaMethod(object_id_, property)) {
98 return gin::CreateFunctionTemplate(
99 isolate,
100 base::Bind(&GinJavaBridgeObject::InvokeMethod,
101 base::Unretained(this),
102 property))->GetFunction();
103 } else {
104 return v8::Local<v8::Value>();
105 }
106 }
107
108 std::vector<std::string> GinJavaBridgeObject::EnumerateNamedProperties(
109 v8::Isolate* isolate) {
110 std::set<std::string> method_names;
111 if (dispatcher_) {
112 dispatcher_->GetJavaMethods(object_id_, &method_names);
113 }
114 return std::vector<std::string> (method_names.begin(), method_names.end());
115 }
116
117 v8::Handle<v8::Value> GinJavaBridgeObject::InvokeMethod(
118 const std::string& name,
119 gin::Arguments* args) {
120 if (!dispatcher_) {
121 args->isolate()->ThrowException(v8::Exception::Error(gin::StringToV8(
122 args->isolate(), kMethodInvocationErrorMessage)));
123 return v8::Undefined(args->isolate());
124 }
125
126 base::ListValue arguments;
127 {
128 v8::HandleScope handle_scope(args->isolate());
129 v8::Handle<v8::Context> context = args->isolate()->GetCurrentContext();
130 v8::Handle<v8::Value> val;
131 while (args->GetNext(&val)) {
132 scoped_ptr<base::Value> arg(converter_->FromV8Value(val, context));
133 if (arg.get()) {
134 arguments.Append(arg.release());
135 } else {
136 arguments.Append(base::Value::CreateNullValue());
137 }
138 }
139 }
140
141 scoped_ptr<base::Value> result =
142 dispatcher_->InvokeJavaMethod(object_id_, name, arguments);
143 if (!result.get()) {
144 args->isolate()->ThrowException(v8::Exception::Error(gin::StringToV8(
145 args->isolate(), kMethodInvocationErrorMessage)));
146 return v8::Undefined(args->isolate());
147 }
148 if (!result->IsType(base::Value::TYPE_BINARY)) {
149 return converter_->ToV8Value(result.get(),
150 args->isolate()->GetCurrentContext());
151 }
152
153 scoped_ptr<const GinJavaBridgeValue> gin_value =
154 GinJavaBridgeValue::FromValue(result.get());
155 if (gin_value->IsType(GinJavaBridgeValue::TYPE_OBJECT_ID)) {
156 GinJavaBridgeObject* result = NULL;
157 GinJavaBridgeDispatcher::ObjectID object_id;
158 if (gin_value->GetAsObjectID(&object_id)) {
159 result = dispatcher_->GetObject(object_id);
160 }
161 if (result) {
162 gin::Handle<GinJavaBridgeObject> controller =
163 gin::CreateHandle(args->isolate(), result);
164 return controller.ToV8();
165 }
166 } else if (gin_value->IsType(GinJavaBridgeValue::TYPE_NONFINITE)) {
167 float float_value;
168 gin_value->GetAsNonFinite(&float_value);
169 return v8::Number::New(args->isolate(), float_value);
170 }
171 return v8::Undefined(args->isolate());
172 }
173
174 bool GinJavaBridgeObject::FromV8Object(
175 v8::Handle<v8::Object> value,
176 base::Value** out,
177 v8::Isolate* isolate,
178 const FromV8ValueCallback& callback) const {
179 GinJavaBridgeObject* unwrapped;
180 if (!gin::ConvertFromV8(isolate, value, &unwrapped)) {
181 return false;
182 }
183 *out =
184 GinJavaBridgeValue::CreateObjectIDValue(unwrapped->object_id_).release();
185 return true;
186 }
187
188 namespace {
189
190 class TypedArraySerializer {
191 public:
192 virtual ~TypedArraySerializer() {}
193 static scoped_ptr<TypedArraySerializer> Create(
194 v8::Handle<v8::TypedArray> typed_array);
195 virtual void serializeTo(char* data,
196 size_t data_length,
197 base::ListValue* out) = 0;
198 protected:
199 TypedArraySerializer() {}
200 };
201
202 template <typename ElementType, typename ListType>
203 class TypedArraySerializerImpl : public TypedArraySerializer {
204 public:
205 static scoped_ptr<TypedArraySerializer> Create(
206 v8::Handle<v8::TypedArray> typed_array) {
207 scoped_ptr<TypedArraySerializerImpl<ElementType, ListType> > result(
208 new TypedArraySerializerImpl<ElementType, ListType>(typed_array));
209 return result.template PassAs<TypedArraySerializer>();
210 }
211
212 virtual void serializeTo(char* data,
213 size_t data_length,
214 base::ListValue* out) OVERRIDE {
215 DCHECK_EQ(data_length, typed_array_->Length() * sizeof(ElementType));
216 for (ElementType *element = reinterpret_cast<ElementType*>(data),
217 *end = element + typed_array_->Length();
218 element != end;
219 ++element) {
220 const ListType list_value = *element;
221 out->Append(new base::FundamentalValue(list_value));
222 }
223 }
224
225 private:
226 explicit TypedArraySerializerImpl(v8::Handle<v8::TypedArray> typed_array)
227 : typed_array_(typed_array) {}
228
229 v8::Handle<v8::TypedArray> typed_array_;
230 };
231
232 // static
233 scoped_ptr<TypedArraySerializer> TypedArraySerializer::Create(
234 v8::Handle<v8::TypedArray> typed_array) {
235 if (typed_array->IsInt8Array() ||
236 typed_array->IsUint8Array() ||
237 typed_array->IsUint8ClampedArray()) {
238 return TypedArraySerializerImpl<char, int>::Create(typed_array).Pass();
239 } else if (typed_array->IsInt16Array() || typed_array->IsUint16Array()) {
240 return TypedArraySerializerImpl<int16_t, int>::Create(typed_array).Pass();
241 } else if (typed_array->IsInt32Array() || typed_array->IsUint32Array()) {
242 return TypedArraySerializerImpl<int32_t, int>::Create(typed_array).Pass();
243 } else if (typed_array->IsFloat32Array()) {
244 return TypedArraySerializerImpl<float, double>::Create(typed_array).Pass();
245 } else if (typed_array->IsFloat64Array()) {
246 return TypedArraySerializerImpl<double, double>::Create(typed_array).Pass();
247 }
248 NOTREACHED();
249 return scoped_ptr<TypedArraySerializer>();
250 }
251
252 } // namespace
253
254 bool GinJavaBridgeObject::FromV8ArrayBuffer(v8::Handle<v8::Object> value,
255 base::Value** out) const {
256 if (!value->IsTypedArray()) {
257 *out = GinJavaBridgeValue::CreateUndefinedValue().release();
258 return true;
259 }
260
261 char* data = NULL;
262 size_t data_length = 0;
263 scoped_ptr<blink::WebArrayBufferView> view(
264 blink::WebArrayBufferView::createFromV8Value(value));
265 if (view) {
266 data = reinterpret_cast<char*>(view->baseAddress()) + view->byteOffset();
267 data_length = view->byteLength();
268 }
269 if (!data) {
270 *out = GinJavaBridgeValue::CreateUndefinedValue().release();
271 return true;
272 }
273
274 base::ListValue* result = new base::ListValue();
275 *out = result;
276 scoped_ptr<TypedArraySerializer> serializer(
277 TypedArraySerializer::Create(value.As<v8::TypedArray>()));
278 serializer->serializeTo(data, data_length, result);
279 return true;
280 }
281
282 bool GinJavaBridgeObject::FromV8Number(v8::Handle<v8::Number> value,
283 base::Value** out) const {
284 double double_value = value->Value();
285 if (base::IsFinite(double_value))
286 return false;
287 *out = GinJavaBridgeValue::CreateNonFiniteValue(double_value).release();
288 return true;
289 }
290
291 bool GinJavaBridgeObject::FromV8Undefined(base::Value** out) const {
292 *out = GinJavaBridgeValue::CreateUndefinedValue().release();
293 return true;
294 }
295
296 gin::WrapperInfo GinJavaBridgeObject::kWrapperInfo = {gin::kEmbedderNativeGin};
297
298 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698