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 "components/guest_view/common/guest_view_constants.h"
11 #include "components/guest_view/renderer/guest_view_request.h"
12 #include "content/public/child/v8_value_converter.h"
13 #include "content/public/renderer/render_view.h"
14 #include "extensions/common/extension.h"
15 #include "extensions/common/extension_messages.h"
16 #include "extensions/renderer/guest_view/extensions_guest_view_container.h"
17 #include "extensions/renderer/script_context.h"
18 #include "third_party/WebKit/public/web/WebFrame.h"
19 #include "third_party/WebKit/public/web/WebScopedUserGesture.h"
20 #include "third_party/WebKit/public/web/WebView.h"
21 #include "v8/include/v8.h"
23 using content::V8ValueConverter
;
25 namespace extensions
{
27 GuestViewInternalCustomBindings::GuestViewInternalCustomBindings(
28 ScriptContext
* context
)
29 : ObjectBackedNativeHandler(context
) {
30 RouteFunction("AttachGuest",
31 base::Bind(&GuestViewInternalCustomBindings::AttachGuest
,
32 base::Unretained(this)));
33 RouteFunction("DetachGuest",
34 base::Bind(&GuestViewInternalCustomBindings::DetachGuest
,
35 base::Unretained(this)));
36 RouteFunction("GetContentWindow",
37 base::Bind(&GuestViewInternalCustomBindings::GetContentWindow
,
38 base::Unretained(this)));
40 "RegisterDestructionCallback",
41 base::Bind(&GuestViewInternalCustomBindings::RegisterDestructionCallback
,
42 base::Unretained(this)));
44 "RegisterElementResizeCallback",
46 &GuestViewInternalCustomBindings::RegisterElementResizeCallback
,
47 base::Unretained(this)));
50 base::Bind(&GuestViewInternalCustomBindings::RunWithGesture
,
51 base::Unretained(this)));
54 void GuestViewInternalCustomBindings::AttachGuest(
55 const v8::FunctionCallbackInfo
<v8::Value
>& args
) {
56 // Allow for an optional callback parameter.
57 CHECK(args
.Length() >= 3 && args
.Length() <= 4);
58 // Element Instance ID.
59 CHECK(args
[0]->IsInt32());
61 CHECK(args
[1]->IsInt32());
63 CHECK(args
[2]->IsObject());
64 // Optional Callback Function.
65 CHECK(args
.Length() < 4 || args
[3]->IsFunction());
67 int element_instance_id
= args
[0]->Int32Value();
68 // An element instance ID uniquely identifies a GuestViewContainer.
69 auto guest_view_container
=
70 guest_view::GuestViewContainer::FromID(element_instance_id
);
72 // TODO(fsamuel): Should we be reporting an error if the element instance ID
74 if (!guest_view_container
)
77 int guest_instance_id
= args
[1]->Int32Value();
79 scoped_ptr
<base::DictionaryValue
> params
;
81 scoped_ptr
<V8ValueConverter
> converter(V8ValueConverter::create());
82 scoped_ptr
<base::Value
> params_as_value(
83 converter
->FromV8Value(args
[2], context()->v8_context()));
84 CHECK(params_as_value
->IsType(base::Value::TYPE_DICTIONARY
));
86 static_cast<base::DictionaryValue
*>(params_as_value
.release()));
89 // Add flag to |params| to indicate that the element size is specified in
91 params
->SetBoolean(guest_view::kElementSizeIsLogical
, true);
93 linked_ptr
<guest_view::GuestViewRequest
> request(
94 new guest_view::GuestViewAttachRequest(
95 guest_view_container
, guest_instance_id
, params
.Pass(),
96 args
.Length() == 4 ? args
[3].As
<v8::Function
>()
97 : v8::Local
<v8::Function
>(),
99 guest_view_container
->IssueRequest(request
);
101 args
.GetReturnValue().Set(v8::Boolean::New(context()->isolate(), true));
104 void GuestViewInternalCustomBindings::DetachGuest(
105 const v8::FunctionCallbackInfo
<v8::Value
>& args
) {
106 // Allow for an optional callback parameter.
107 CHECK(args
.Length() >= 1 && args
.Length() <= 2);
108 // Element Instance ID.
109 CHECK(args
[0]->IsInt32());
110 // Optional Callback Function.
111 CHECK(args
.Length() < 2 || args
[1]->IsFunction());
113 int element_instance_id
= args
[0]->Int32Value();
114 // An element instance ID uniquely identifies a GuestViewContainer.
115 auto guest_view_container
=
116 guest_view::GuestViewContainer::FromID(element_instance_id
);
118 // TODO(fsamuel): Should we be reporting an error if the element instance ID
120 if (!guest_view_container
)
123 linked_ptr
<guest_view::GuestViewRequest
> request(
124 new guest_view::GuestViewDetachRequest(
125 guest_view_container
, args
.Length() == 2 ? args
[1].As
<v8::Function
>()
126 : v8::Local
<v8::Function
>(),
128 guest_view_container
->IssueRequest(request
);
130 args
.GetReturnValue().Set(v8::Boolean::New(context()->isolate(), true));
133 void GuestViewInternalCustomBindings::GetContentWindow(
134 const v8::FunctionCallbackInfo
<v8::Value
>& args
) {
135 // Default to returning null.
136 args
.GetReturnValue().SetNull();
138 if (args
.Length() != 1)
141 // The routing ID for the RenderView.
142 if (!args
[0]->IsInt32())
145 int view_id
= args
[0]->Int32Value();
146 if (view_id
== MSG_ROUTING_NONE
)
149 content::RenderView
* view
= content::RenderView::FromRoutingID(view_id
);
153 blink::WebFrame
* frame
= view
->GetWebView()->mainFrame();
154 v8::Local
<v8::Value
> window
= frame
->mainWorldScriptContext()->Global();
155 args
.GetReturnValue().Set(window
);
158 void GuestViewInternalCustomBindings::RegisterDestructionCallback(
159 const v8::FunctionCallbackInfo
<v8::Value
>& args
) {
160 // There are two parameters.
161 CHECK(args
.Length() == 2);
162 // Element Instance ID.
163 CHECK(args
[0]->IsInt32());
164 // Callback function.
165 CHECK(args
[1]->IsFunction());
167 int element_instance_id
= args
[0]->Int32Value();
168 // An element instance ID uniquely identifies a ExtensionsGuestViewContainer
169 // within a RenderView.
170 auto guest_view_container
= static_cast<ExtensionsGuestViewContainer
*>(
171 guest_view::GuestViewContainer::FromID(element_instance_id
));
172 if (!guest_view_container
)
175 guest_view_container
->RegisterDestructionCallback(args
[1].As
<v8::Function
>(),
178 args
.GetReturnValue().Set(v8::Boolean::New(context()->isolate(), true));
181 void GuestViewInternalCustomBindings::RegisterElementResizeCallback(
182 const v8::FunctionCallbackInfo
<v8::Value
>& args
) {
183 // There are two parameters.
184 CHECK(args
.Length() == 2);
185 // Element Instance ID.
186 CHECK(args
[0]->IsInt32());
187 // Callback function.
188 CHECK(args
[1]->IsFunction());
190 int element_instance_id
= args
[0]->Int32Value();
191 // An element instance ID uniquely identifies a ExtensionsGuestViewContainer
192 // within a RenderView.
193 auto guest_view_container
= static_cast<ExtensionsGuestViewContainer
*>(
194 guest_view::GuestViewContainer::FromID(element_instance_id
));
195 if (!guest_view_container
)
198 guest_view_container
->RegisterElementResizeCallback(
199 args
[1].As
<v8::Function
>(), args
.GetIsolate());
201 args
.GetReturnValue().Set(v8::Boolean::New(context()->isolate(), true));
204 void GuestViewInternalCustomBindings::RunWithGesture(
205 const v8::FunctionCallbackInfo
<v8::Value
>& args
) {
206 // Gesture is required to request fullscreen.
207 blink::WebScopedUserGesture user_gesture
;
208 CHECK_EQ(args
.Length(), 1);
209 CHECK(args
[0]->IsFunction());
210 v8::Local
<v8::Value
> no_args
;
211 context()->CallFunction(v8::Local
<v8::Function
>::Cast(args
[0]), 0, &no_args
);
214 } // namespace extensions