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 "extensions/renderer/guest_view/guest_view_internal_custom_bindings.h"
6
7#include <string>
8
9#include "base/bind.h"
10#include "content/public/renderer/render_view.h"
11#include "content/public/renderer/v8_value_converter.h"
12#include "extensions/common/extension.h"
13#include "extensions/common/extension_messages.h"
14#include "extensions/renderer/guest_view/guest_view_container.h"
15#include "extensions/renderer/script_context.h"
16#include "v8/include/v8.h"
17
18using content::V8ValueConverter;
19
20namespace extensions {
21
22GuestViewInternalCustomBindings::GuestViewInternalCustomBindings(
23    ScriptContext* context)
24    : ObjectBackedNativeHandler(context) {
25  RouteFunction("AttachGuest",
26                base::Bind(&GuestViewInternalCustomBindings::AttachGuest,
27                           base::Unretained(this)));
28}
29
30void GuestViewInternalCustomBindings::AttachGuest(
31    const v8::FunctionCallbackInfo<v8::Value>& args) {
32  // Allow for an optional callback parameter.
33  CHECK(args.Length() >= 3 && args.Length() <= 4);
34  // Element Instance ID.
35  CHECK(args[0]->IsInt32());
36  // Guest Instance ID.
37  CHECK(args[1]->IsInt32());
38  // Attach Parameters.
39  CHECK(args[2]->IsObject());
40  // Optional Callback Function.
41  CHECK(args.Length() < 4 || args[3]->IsFunction());
42
43  int element_instance_id = args[0]->Int32Value();
44  // An element instance ID uniquely identifies a GuestViewContainer within
45  // a RenderView.
46  GuestViewContainer* guest_view_container =
47      GuestViewContainer::FromID(context()->GetRenderView()->GetRoutingID(),
48                                 element_instance_id);
49
50  // TODO(fsamuel): Should we be reporting an error if the element instance ID
51  // is invalid?
52  if (!guest_view_container)
53    return;
54
55  int guest_instance_id = args[1]->Int32Value();
56
57  scoped_ptr<base::DictionaryValue> params;
58  {
59    scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
60    scoped_ptr<base::Value> params_as_value(
61        converter->FromV8Value(args[2], context()->v8_context()));
62    CHECK(params_as_value->IsType(base::Value::TYPE_DICTIONARY));
63    params.reset(
64        static_cast<base::DictionaryValue*>(params_as_value.release()));
65  }
66
67  guest_view_container->AttachGuest(
68      element_instance_id,
69      guest_instance_id,
70      params.Pass(),
71      args.Length() == 4 ? args[3].As<v8::Function>() :
72          v8::Handle<v8::Function>(),
73      args.GetIsolate());
74
75  args.GetReturnValue().Set(v8::Boolean::New(context()->isolate(), true));
76}
77
78}  // namespace extensions
79