Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / extensions / renderer / object_backed_native_handler.cc
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/object_backed_native_handler.h"
6
7 #include "base/logging.h"
8 #include "base/memory/linked_ptr.h"
9 #include "extensions/renderer/console.h"
10 #include "extensions/renderer/module_system.h"
11 #include "extensions/renderer/script_context.h"
12 #include "v8/include/v8.h"
13
14 namespace extensions {
15
16 namespace {
17 // Key for the base::Bound routed function.
18 const char* kHandlerFunction = "handler_function";
19 }  // namespace
20
21 ObjectBackedNativeHandler::ObjectBackedNativeHandler(ScriptContext* context)
22     : router_data_(context->v8_context()->GetIsolate()),
23       context_(context),
24       object_template_(
25           v8::ObjectTemplate::New(context->v8_context()->GetIsolate())) {}
26
27 ObjectBackedNativeHandler::~ObjectBackedNativeHandler() { Invalidate(); }
28
29 v8::Handle<v8::Object> ObjectBackedNativeHandler::NewInstance() {
30   return object_template_.NewHandle(v8::Isolate::GetCurrent())->NewInstance();
31 }
32
33 // static
34 void ObjectBackedNativeHandler::Router(
35     const v8::FunctionCallbackInfo<v8::Value>& args) {
36   v8::HandleScope handle_scope(args.GetIsolate());
37   v8::Handle<v8::Object> data = args.Data().As<v8::Object>();
38
39   v8::Handle<v8::Value> handler_function_value =
40       data->Get(v8::String::NewFromUtf8(args.GetIsolate(), kHandlerFunction));
41   // See comment in header file for why we do this.
42   if (handler_function_value.IsEmpty() ||
43       handler_function_value->IsUndefined()) {
44     console::Error(args.GetIsolate()->GetCallingContext(),
45                    "Extension view no longer exists");
46     return;
47   }
48   DCHECK(handler_function_value->IsExternal());
49   static_cast<HandlerFunction*>(
50       handler_function_value.As<v8::External>()->Value())->Run(args);
51 }
52
53 void ObjectBackedNativeHandler::RouteFunction(
54     const std::string& name,
55     const HandlerFunction& handler_function) {
56   v8::Isolate* isolate = v8::Isolate::GetCurrent();
57   v8::HandleScope handle_scope(isolate);
58   v8::Context::Scope context_scope(context_->v8_context());
59
60   v8::Local<v8::Object> data = v8::Object::New(isolate);
61   data->Set(
62       v8::String::NewFromUtf8(isolate, kHandlerFunction),
63       v8::External::New(isolate, new HandlerFunction(handler_function)));
64   v8::Handle<v8::FunctionTemplate> function_template =
65       v8::FunctionTemplate::New(isolate, Router, data);
66   object_template_.NewHandle(isolate)
67       ->Set(isolate, name.c_str(), function_template);
68   router_data_.Append(data);
69 }
70
71 v8::Isolate* ObjectBackedNativeHandler::GetIsolate() const {
72   return context_->isolate();
73 }
74
75 void ObjectBackedNativeHandler::Invalidate() {
76   if (!is_valid())
77     return;
78   v8::Isolate* isolate = v8::Isolate::GetCurrent();
79   v8::HandleScope handle_scope(isolate);
80   v8::Context::Scope context_scope(context_->v8_context());
81
82   for (size_t i = 0; i < router_data_.Size(); i++) {
83     v8::Handle<v8::Object> data = router_data_.Get(i);
84     v8::Handle<v8::Value> handler_function_value =
85         data->Get(v8::String::NewFromUtf8(isolate, kHandlerFunction));
86     CHECK(!handler_function_value.IsEmpty());
87     delete static_cast<HandlerFunction*>(
88         handler_function_value.As<v8::External>()->Value());
89     data->Delete(v8::String::NewFromUtf8(isolate, kHandlerFunction));
90   }
91   router_data_.Clear();
92   object_template_.reset();
93   context_ = NULL;
94   NativeHandler::Invalidate();
95 }
96
97 }  // namespace extensions