1 // Copyright 2015 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.
5 #include "content/renderer/java/gin_java_function_invocation_helper.h"
7 #include "content/common/android/gin_java_bridge_errors.h"
8 #include "content/common/android/gin_java_bridge_value.h"
9 #include "content/public/child/v8_value_converter.h"
10 #include "content/renderer/java/gin_java_bridge_object.h"
11 #include "content/renderer/java/gin_java_bridge_value_converter.h"
17 const char kMethodInvocationAsConstructorDisallowed
[] =
18 "Java bridge method can't be invoked as a constructor";
19 const char kMethodInvocationOnNonInjectedObjectDisallowed
[] =
20 "Java bridge method can't be invoked on a non-injected object";
21 const char kMethodInvocationErrorMessage
[] =
22 "Java bridge method invocation error";
26 GinJavaFunctionInvocationHelper::GinJavaFunctionInvocationHelper(
27 const std::string
& method_name
,
28 const base::WeakPtr
<GinJavaBridgeDispatcher
>& dispatcher
)
29 : method_name_(method_name
),
30 dispatcher_(dispatcher
),
31 converter_(new GinJavaBridgeValueConverter()) {
34 GinJavaFunctionInvocationHelper::~GinJavaFunctionInvocationHelper() {
37 v8::Local
<v8::Value
> GinJavaFunctionInvocationHelper::Invoke(
38 gin::Arguments
* args
) {
40 args
->isolate()->ThrowException(v8::Exception::Error(gin::StringToV8(
41 args
->isolate(), kMethodInvocationErrorMessage
)));
42 return v8::Undefined(args
->isolate());
45 if (args
->IsConstructCall()) {
46 args
->isolate()->ThrowException(v8::Exception::Error(gin::StringToV8(
47 args
->isolate(), kMethodInvocationAsConstructorDisallowed
)));
48 return v8::Undefined(args
->isolate());
51 content::GinJavaBridgeObject
* object
= NULL
;
52 if (!args
->GetHolder(&object
) || !object
) {
53 args
->isolate()->ThrowException(v8::Exception::Error(gin::StringToV8(
54 args
->isolate(), kMethodInvocationOnNonInjectedObjectDisallowed
)));
55 return v8::Undefined(args
->isolate());
58 base::ListValue arguments
;
60 v8::HandleScope
handle_scope(args
->isolate());
61 v8::Local
<v8::Context
> context
= args
->isolate()->GetCurrentContext();
62 v8::Local
<v8::Value
> val
;
63 while (args
->GetNext(&val
)) {
64 scoped_ptr
<base::Value
> arg(converter_
->FromV8Value(val
, context
));
66 arguments
.Append(arg
.release());
68 arguments
.Append(base::Value::CreateNullValue());
73 GinJavaBridgeError error
;
74 scoped_ptr
<base::Value
> result
= dispatcher_
->InvokeJavaMethod(
75 object
->object_id(), method_name_
, arguments
, &error
);
77 args
->isolate()->ThrowException(v8::Exception::Error(gin::StringToV8(
78 args
->isolate(), GinJavaBridgeErrorToString(error
))));
79 return v8::Undefined(args
->isolate());
81 if (!result
->IsType(base::Value::TYPE_BINARY
)) {
82 return converter_
->ToV8Value(result
.get(),
83 args
->isolate()->GetCurrentContext());
86 scoped_ptr
<const GinJavaBridgeValue
> gin_value
=
87 GinJavaBridgeValue::FromValue(result
.get());
88 if (gin_value
->IsType(GinJavaBridgeValue::TYPE_OBJECT_ID
)) {
89 GinJavaBridgeObject
* result
= NULL
;
90 GinJavaBridgeDispatcher::ObjectID object_id
;
91 if (gin_value
->GetAsObjectID(&object_id
)) {
92 result
= dispatcher_
->GetObject(object_id
);
95 gin::Handle
<GinJavaBridgeObject
> controller
=
96 gin::CreateHandle(args
->isolate(), result
);
97 if (controller
.IsEmpty())
98 return v8::Undefined(args
->isolate());
99 return controller
.ToV8();
101 } else if (gin_value
->IsType(GinJavaBridgeValue::TYPE_NONFINITE
)) {
103 gin_value
->GetAsNonFinite(&float_value
);
104 return v8::Number::New(args
->isolate(), float_value
);
106 return v8::Undefined(args
->isolate());
109 } // namespace content