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 |