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.
5 #include "extensions/renderer/guest_view/guest_view_internal_custom_bindings.h"
10 #include "content/public/child/v8_value_converter.h"
11 #include "content/public/renderer/render_view.h"
12 #include "extensions/common/extension.h"
13 #include "extensions/common/extension_messages.h"
14 #include "extensions/common/guest_view/guest_view_constants.h"
15 #include "extensions/renderer/guest_view/extensions_guest_view_container.h"
16 #include "extensions/renderer/script_context.h"
17 #include "third_party/WebKit/public/web/WebFrame.h"
18 #include "third_party/WebKit/public/web/WebScopedUserGesture.h"
19 #include "third_party/WebKit/public/web/WebView.h"
20 #include "v8/include/v8.h"
22 using content::V8ValueConverter
;
24 namespace extensions
{
26 GuestViewInternalCustomBindings::GuestViewInternalCustomBindings(
27 ScriptContext
* context
)
28 : ObjectBackedNativeHandler(context
) {
29 RouteFunction("AttachGuest",
30 base::Bind(&GuestViewInternalCustomBindings::AttachGuest
,
31 base::Unretained(this)));
32 RouteFunction("DetachGuest",
33 base::Bind(&GuestViewInternalCustomBindings::DetachGuest
,
34 base::Unretained(this)));
35 RouteFunction("GetContentWindow",
36 base::Bind(&GuestViewInternalCustomBindings::GetContentWindow
,
37 base::Unretained(this)));
39 "RegisterDestructionCallback",
40 base::Bind(&GuestViewInternalCustomBindings::RegisterDestructionCallback
,
41 base::Unretained(this)));
43 "RegisterElementResizeCallback",
45 &GuestViewInternalCustomBindings::RegisterElementResizeCallback
,
46 base::Unretained(this)));
49 base::Bind(&GuestViewInternalCustomBindings::RunWithGesture
,
50 base::Unretained(this)));
53 void GuestViewInternalCustomBindings::AttachGuest(
54 const v8::FunctionCallbackInfo
<v8::Value
>& args
) {
55 // Allow for an optional callback parameter.
56 CHECK(args
.Length() >= 3 && args
.Length() <= 4);
57 // Element Instance ID.
58 CHECK(args
[0]->IsInt32());
60 CHECK(args
[1]->IsInt32());
62 CHECK(args
[2]->IsObject());
63 // Optional Callback Function.
64 CHECK(args
.Length() < 4 || args
[3]->IsFunction());
66 int element_instance_id
= args
[0]->Int32Value();
67 // An element instance ID uniquely identifies a ExtensionsGuestViewContainer.
68 ExtensionsGuestViewContainer
* guest_view_container
=
69 ExtensionsGuestViewContainer::FromID(element_instance_id
);
71 // TODO(fsamuel): Should we be reporting an error if the element instance ID
73 if (!guest_view_container
)
76 int guest_instance_id
= args
[1]->Int32Value();
78 scoped_ptr
<base::DictionaryValue
> params
;
80 scoped_ptr
<V8ValueConverter
> converter(V8ValueConverter::create());
81 scoped_ptr
<base::Value
> params_as_value(
82 converter
->FromV8Value(args
[2], context()->v8_context()));
83 CHECK(params_as_value
->IsType(base::Value::TYPE_DICTIONARY
));
85 static_cast<base::DictionaryValue
*>(params_as_value
.release()));
88 // Add flag to |params| to indicate that the element size is specified in
90 params
->SetBoolean(guestview::kElementSizeIsLogical
, true);
92 linked_ptr
<ExtensionsGuestViewContainer::Request
> request(
93 new ExtensionsGuestViewContainer::AttachRequest(
94 guest_view_container
, guest_instance_id
, params
.Pass(),
95 args
.Length() == 4 ? args
[3].As
<v8::Function
>()
96 : v8::Local
<v8::Function
>(),
98 guest_view_container
->IssueRequest(request
);
100 args
.GetReturnValue().Set(v8::Boolean::New(context()->isolate(), true));
103 void GuestViewInternalCustomBindings::DetachGuest(
104 const v8::FunctionCallbackInfo
<v8::Value
>& args
) {
105 // Allow for an optional callback parameter.
106 CHECK(args
.Length() >= 1 && args
.Length() <= 2);
107 // Element Instance ID.
108 CHECK(args
[0]->IsInt32());
109 // Optional Callback Function.
110 CHECK(args
.Length() < 2 || args
[1]->IsFunction());
112 int element_instance_id
= args
[0]->Int32Value();
113 // An element instance ID uniquely identifies a ExtensionsGuestViewContainer.
114 ExtensionsGuestViewContainer
* guest_view_container
=
115 ExtensionsGuestViewContainer::FromID(element_instance_id
);
117 // TODO(fsamuel): Should we be reporting an error if the element instance ID
119 if (!guest_view_container
)
122 linked_ptr
<ExtensionsGuestViewContainer::Request
> request(
123 new ExtensionsGuestViewContainer::DetachRequest(
124 guest_view_container
, args
.Length() == 2 ? args
[1].As
<v8::Function
>()
125 : v8::Local
<v8::Function
>(),
127 guest_view_container
->IssueRequest(request
);
129 args
.GetReturnValue().Set(v8::Boolean::New(context()->isolate(), true));
132 void GuestViewInternalCustomBindings::GetContentWindow(
133 const v8::FunctionCallbackInfo
<v8::Value
>& args
) {
134 // Default to returning null.
135 args
.GetReturnValue().SetNull();
137 if (args
.Length() != 1)
140 // The routing ID for the RenderView.
141 if (!args
[0]->IsInt32())
144 int view_id
= args
[0]->Int32Value();
145 if (view_id
== MSG_ROUTING_NONE
)
148 content::RenderView
* view
= content::RenderView::FromRoutingID(view_id
);
152 blink::WebFrame
* frame
= view
->GetWebView()->mainFrame();
153 v8::Local
<v8::Value
> window
= frame
->mainWorldScriptContext()->Global();
154 args
.GetReturnValue().Set(window
);
157 void GuestViewInternalCustomBindings::RegisterDestructionCallback(
158 const v8::FunctionCallbackInfo
<v8::Value
>& args
) {
159 // There are two parameters.
160 CHECK(args
.Length() == 2);
161 // Element Instance ID.
162 CHECK(args
[0]->IsInt32());
163 // Callback function.
164 CHECK(args
[1]->IsFunction());
166 int element_instance_id
= args
[0]->Int32Value();
167 // An element instance ID uniquely identifies a ExtensionsGuestViewContainer
168 // within a RenderView.
169 ExtensionsGuestViewContainer
* guest_view_container
=
170 ExtensionsGuestViewContainer::FromID(element_instance_id
);
171 if (!guest_view_container
)
174 guest_view_container
->RegisterDestructionCallback(args
[1].As
<v8::Function
>(),
177 args
.GetReturnValue().Set(v8::Boolean::New(context()->isolate(), true));
180 void GuestViewInternalCustomBindings::RegisterElementResizeCallback(
181 const v8::FunctionCallbackInfo
<v8::Value
>& args
) {
182 // There are two parameters.
183 CHECK(args
.Length() == 2);
184 // Element Instance ID.
185 CHECK(args
[0]->IsInt32());
186 // Callback function.
187 CHECK(args
[1]->IsFunction());
189 int element_instance_id
= args
[0]->Int32Value();
190 // An element instance ID uniquely identifies a ExtensionsGuestViewContainer
191 // within a RenderView.
192 ExtensionsGuestViewContainer
* guest_view_container
=
193 ExtensionsGuestViewContainer::FromID(element_instance_id
);
194 if (!guest_view_container
)
197 guest_view_container
->RegisterElementResizeCallback(
198 args
[1].As
<v8::Function
>(), args
.GetIsolate());
200 args
.GetReturnValue().Set(v8::Boolean::New(context()->isolate(), true));
203 void GuestViewInternalCustomBindings::RunWithGesture(
204 const v8::FunctionCallbackInfo
<v8::Value
>& args
) {
205 // Gesture is required to request fullscreen.
206 blink::WebScopedUserGesture user_gesture
;
207 CHECK_EQ(args
.Length(), 1);
208 CHECK(args
[0]->IsFunction());
209 v8::Local
<v8::Value
> no_args
;
210 context()->CallFunction(v8::Local
<v8::Function
>::Cast(args
[0]), 0, &no_args
);
213 } // namespace extensions