| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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 "chrome/renderer/extensions/v8_schema_registry.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "base/values.h" | |
| 9 #include "chrome/renderer/extensions/chrome_v8_context.h" | |
| 10 #include "content/public/renderer/v8_value_converter.h" | |
| 11 #include "extensions/common/extension_api.h" | |
| 12 #include "extensions/renderer/object_backed_native_handler.h" | |
| 13 | |
| 14 using content::V8ValueConverter; | |
| 15 | |
| 16 namespace extensions { | |
| 17 | |
| 18 namespace { | |
| 19 | |
| 20 class SchemaRegistryNativeHandler : public ObjectBackedNativeHandler { | |
| 21 public: | |
| 22 SchemaRegistryNativeHandler(V8SchemaRegistry* registry, | |
| 23 scoped_ptr<ChromeV8Context> context) | |
| 24 : ObjectBackedNativeHandler(context.get()), | |
| 25 context_(context.Pass()), | |
| 26 registry_(registry) { | |
| 27 RouteFunction("GetSchema", | |
| 28 base::Bind(&SchemaRegistryNativeHandler::GetSchema, | |
| 29 base::Unretained(this))); | |
| 30 } | |
| 31 | |
| 32 private: | |
| 33 void GetSchema(const v8::FunctionCallbackInfo<v8::Value>& args) { | |
| 34 args.GetReturnValue().Set( | |
| 35 registry_->GetSchema(*v8::String::Utf8Value(args[0]))); | |
| 36 } | |
| 37 | |
| 38 scoped_ptr<ChromeV8Context> context_; | |
| 39 V8SchemaRegistry* registry_; | |
| 40 }; | |
| 41 | |
| 42 } // namespace | |
| 43 | |
| 44 V8SchemaRegistry::V8SchemaRegistry() {} | |
| 45 | |
| 46 V8SchemaRegistry::~V8SchemaRegistry() {} | |
| 47 | |
| 48 scoped_ptr<NativeHandler> V8SchemaRegistry::AsNativeHandler() { | |
| 49 scoped_ptr<ChromeV8Context> context(new ChromeV8Context( | |
| 50 GetOrCreateContext(v8::Isolate::GetCurrent()), | |
| 51 NULL, // no frame | |
| 52 NULL, // no extension | |
| 53 Feature::UNSPECIFIED_CONTEXT)); | |
| 54 return scoped_ptr<NativeHandler>( | |
| 55 new SchemaRegistryNativeHandler(this, context.Pass())); | |
| 56 } | |
| 57 | |
| 58 v8::Handle<v8::Array> V8SchemaRegistry::GetSchemas( | |
| 59 const std::vector<std::string>& apis) { | |
| 60 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | |
| 61 v8::EscapableHandleScope handle_scope(isolate); | |
| 62 v8::Context::Scope context_scope(GetOrCreateContext(isolate)); | |
| 63 | |
| 64 v8::Local<v8::Array> v8_apis(v8::Array::New(isolate, apis.size())); | |
| 65 size_t api_index = 0; | |
| 66 for (std::vector<std::string>::const_iterator i = apis.begin(); | |
| 67 i != apis.end(); ++i) { | |
| 68 v8_apis->Set(api_index++, GetSchema(*i)); | |
| 69 } | |
| 70 return handle_scope.Escape(v8_apis); | |
| 71 } | |
| 72 | |
| 73 v8::Handle<v8::Object> V8SchemaRegistry::GetSchema(const std::string& api) { | |
| 74 if (schema_cache_ != NULL) { | |
| 75 v8::Local<v8::Object> cached_schema = schema_cache_->Get(api); | |
| 76 if (!cached_schema.IsEmpty()) { | |
| 77 return cached_schema; | |
| 78 } | |
| 79 } | |
| 80 | |
| 81 // Slow path: Need to build schema first. | |
| 82 | |
| 83 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | |
| 84 v8::EscapableHandleScope handle_scope(isolate); | |
| 85 v8::Handle<v8::Context> context = GetOrCreateContext(isolate); | |
| 86 v8::Context::Scope context_scope(context); | |
| 87 | |
| 88 const base::DictionaryValue* schema = | |
| 89 ExtensionAPI::GetSharedInstance()->GetSchema(api); | |
| 90 CHECK(schema) << api; | |
| 91 scoped_ptr<V8ValueConverter> v8_value_converter(V8ValueConverter::create()); | |
| 92 v8::Handle<v8::Value> value = v8_value_converter->ToV8Value(schema, context); | |
| 93 CHECK(!value.IsEmpty()); | |
| 94 | |
| 95 v8::Local<v8::Object> v8_schema(v8::Handle<v8::Object>::Cast(value)); | |
| 96 schema_cache_->Set(api, v8_schema); | |
| 97 | |
| 98 return handle_scope.Escape(v8_schema); | |
| 99 } | |
| 100 | |
| 101 v8::Handle<v8::Context> V8SchemaRegistry::GetOrCreateContext( | |
| 102 v8::Isolate* isolate) { | |
| 103 // It's ok to create local handles in this function, since this is only called | |
| 104 // when we have a HandleScope. | |
| 105 if (context_.IsEmpty()) { | |
| 106 v8::Handle<v8::Context> context = v8::Context::New(isolate); | |
| 107 context_.reset(context); | |
| 108 schema_cache_.reset(new SchemaCache(isolate)); | |
| 109 return context; | |
| 110 } | |
| 111 return context_.NewHandle(isolate); | |
| 112 } | |
| 113 | |
| 114 } // namespace extensions | |
| OLD | NEW |