Home | History | Annotate | Download | only in renderer
      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
     98