Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(112)

Side by Side Diff: extensions/renderer/storage_area.cc

Issue 2704823002: [Extensions Bindings] Add support for custom property types (Closed)
Patch Set: . Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « extensions/renderer/storage_area.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 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/storage_area.h"
6
7 #include "base/memory/ptr_util.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/values.h"
10 #include "extensions/common/api/storage.h"
11 #include "extensions/common/extension_api.h"
12 #include "extensions/renderer/api_request_handler.h"
13 #include "extensions/renderer/api_signature.h"
14 #include "gin/arguments.h"
15 #include "gin/handle.h"
16 #include "gin/object_template_builder.h"
17 #include "gin/wrappable.h"
18
19 namespace extensions {
20
21 namespace {
22
23 // gin::Wrappables for each of the storage areas. Since each has slightly
24 // different properties, and the object template is shared between all
25 // instances, this is a little verbose.
Devlin 2017/02/18 02:58:43 jbroman: is there a better way to do this? Luckil
26 class LocalStorageArea final : public gin::Wrappable<LocalStorageArea> {
27 public:
28 LocalStorageArea(APIRequestHandler* request_handler,
29 const APITypeReferenceMap* type_refs)
30 : storage_area_(request_handler, type_refs, "local") {}
31 ~LocalStorageArea() override = default;
32
33 static gin::WrapperInfo kWrapperInfo;
34
35 gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
36 v8::Isolate* isolate) override {
37 gin::ObjectTemplateBuilder builder =
38 Wrappable<LocalStorageArea>::GetObjectTemplateBuilder(isolate);
39 storage_area_.DecorateTemplate(&builder);
40 builder.SetValue("QUOTA_BYTES", api::storage::local::QUOTA_BYTES);
41 return builder;
42 }
43
44 private:
45 StorageArea storage_area_;
46
47 DISALLOW_COPY_AND_ASSIGN(LocalStorageArea);
48 };
49
50 gin::WrapperInfo LocalStorageArea::kWrapperInfo = {gin::kEmbedderNativeGin};
51
52 class SyncStorageArea final : public gin::Wrappable<SyncStorageArea> {
53 public:
54 SyncStorageArea(APIRequestHandler* request_handler,
55 const APITypeReferenceMap* type_refs)
56 : storage_area_(request_handler, type_refs, "sync") {}
57 ~SyncStorageArea() override = default;
58
59 static gin::WrapperInfo kWrapperInfo;
60
61 gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
62 v8::Isolate* isolate) override {
63 gin::ObjectTemplateBuilder builder =
64 Wrappable<SyncStorageArea>::GetObjectTemplateBuilder(isolate);
65 storage_area_.DecorateTemplate(&builder);
66 builder.SetValue("QUOTA_BYTES", api::storage::sync::QUOTA_BYTES);
67 builder.SetValue("QUOTA_BYTES_PER_ITEM",
68 api::storage::sync::QUOTA_BYTES_PER_ITEM);
69 builder.SetValue("MAX_ITEMS", api::storage::sync::MAX_ITEMS);
70 builder.SetValue("MAX_WRITE_OPERATIONS_PER_HOUR",
71 api::storage::sync::MAX_WRITE_OPERATIONS_PER_HOUR);
72 builder.SetValue("MAX_WRITE_OPERATIONS_PER_MINUTE",
73 api::storage::sync::MAX_WRITE_OPERATIONS_PER_MINUTE);
74 builder.SetValue(
75 "MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE",
76 api::storage::sync::MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE);
77 return builder;
78 }
79
80 private:
81 StorageArea storage_area_;
82
83 DISALLOW_COPY_AND_ASSIGN(SyncStorageArea);
84 };
85
86 gin::WrapperInfo SyncStorageArea::kWrapperInfo = {gin::kEmbedderNativeGin};
87
88 class ManagedStorageArea final : public gin::Wrappable<ManagedStorageArea> {
89 public:
90 ManagedStorageArea(APIRequestHandler* request_handler,
91 const APITypeReferenceMap* type_refs)
92 : storage_area_(request_handler, type_refs, "managed") {}
93 ~ManagedStorageArea() override = default;
94
95 static gin::WrapperInfo kWrapperInfo;
96
97 gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
98 v8::Isolate* isolate) override {
99 gin::ObjectTemplateBuilder builder =
100 Wrappable<ManagedStorageArea>::GetObjectTemplateBuilder(isolate);
101 storage_area_.DecorateTemplate(&builder);
102 return builder;
103 }
104
105 private:
106 StorageArea storage_area_;
107
108 DISALLOW_COPY_AND_ASSIGN(ManagedStorageArea);
109 };
110
111 gin::WrapperInfo ManagedStorageArea::kWrapperInfo = {gin::kEmbedderNativeGin};
112
113 } // namespace
114
115 StorageArea::StorageArea(APIRequestHandler* request_handler,
116 const APITypeReferenceMap* type_refs,
117 const std::string& name)
118 : request_handler_(request_handler), type_refs_(type_refs), name_(name) {}
119 StorageArea::~StorageArea() = default;
120
121 // static
122 v8::Local<v8::Object> StorageArea::CreateStorageArea(
123 v8::Local<v8::Context> context,
124 const std::string& property_name,
125 APIRequestHandler* request_handler,
126 APITypeReferenceMap* type_refs) {
127 v8::Context::Scope context_scope(context);
128 v8::Local<v8::Object> object;
129 if (property_name == "local") {
130 gin::Handle<LocalStorageArea> handle =
131 gin::CreateHandle(context->GetIsolate(),
132 new LocalStorageArea(request_handler, type_refs));
133 object = handle.ToV8().As<v8::Object>();
134 } else if (property_name == "sync") {
135 gin::Handle<SyncStorageArea> handle = gin::CreateHandle(
136 context->GetIsolate(), new SyncStorageArea(request_handler, type_refs));
137 object = handle.ToV8().As<v8::Object>();
138 } else {
139 CHECK_EQ("managed", property_name);
140 gin::Handle<ManagedStorageArea> handle =
141 gin::CreateHandle(context->GetIsolate(),
142 new ManagedStorageArea(request_handler, type_refs));
143 object = handle.ToV8().As<v8::Object>();
144 }
145 return object;
146 }
147
148 void StorageArea::DecorateTemplate(gin::ObjectTemplateBuilder* builder) {
149 builder
150 ->SetMethod("get", base::Bind(&StorageArea::HandleFunctionCall,
151 base::Unretained(this), "get"))
152 .SetMethod("set", base::Bind(&StorageArea::HandleFunctionCall,
153 base::Unretained(this), "set"))
154 .SetMethod("remove", base::Bind(&StorageArea::HandleFunctionCall,
155 base::Unretained(this), "remove"))
156 .SetMethod("clear", base::Bind(&StorageArea::HandleFunctionCall,
157 base::Unretained(this), "clear"))
158 .SetMethod("getBytesInUse",
159 base::Bind(&StorageArea::HandleFunctionCall,
160 base::Unretained(this), "getBytesInUse"));
161 }
162
163 void StorageArea::HandleFunctionCall(const std::string& method_name,
164 gin::Arguments* arguments) {
165 v8::Isolate* isolate = arguments->isolate();
166 v8::HandleScope handle_scope(isolate);
167 v8::Local<v8::Context> context = isolate->GetCurrentContext();
168
169 std::vector<v8::Local<v8::Value>> argument_list;
170 if (arguments->Length() > 0) {
171 // Just copying handles should never fail.
172 CHECK(arguments->GetRemaining(&argument_list));
173 }
174
175 std::unique_ptr<base::ListValue> converted_arguments;
176 v8::Local<v8::Function> callback;
177 std::string error;
178 if (!GetFunctionSchema("storage", "storage.StorageArea", method_name)
179 .ParseArgumentsToJSON(context, argument_list, *type_refs_,
180 &converted_arguments, &callback, &error)) {
181 arguments->ThrowTypeError("Invalid invocation");
182 }
183
184 converted_arguments->Insert(0u, base::MakeUnique<base::Value>(name_));
185 request_handler_->StartRequest(context, "storage." + method_name,
186 std::move(converted_arguments), callback,
187 v8::Local<v8::Function>());
188 }
189
190 const APISignature& StorageArea::GetFunctionSchema(
191 base::StringPiece api_name,
192 base::StringPiece type_name,
193 base::StringPiece function_name) {
194 std::string full_name = base::StringPrintf(
195 "%s.%s.%s", api_name.data(), type_name.data(), function_name.data());
196 auto iter = signatures_.find(full_name);
197 if (iter != signatures_.end())
198 return *iter->second;
199
200 const base::DictionaryValue* full_schema =
201 ExtensionAPI::GetSharedInstance()->GetSchema(api_name.as_string());
202 const base::ListValue* types = nullptr;
203 CHECK(full_schema->GetList("types", &types));
204 const base::DictionaryValue* type_schema = nullptr;
205 for (const auto& type : *types) {
206 const base::DictionaryValue* type_dict = nullptr;
207 CHECK(type->GetAsDictionary(&type_dict));
208 std::string id;
209 CHECK(type_dict->GetString("id", &id));
210 if (id == type_name) {
211 type_schema = type_dict;
212 break;
213 }
214 }
215 CHECK(type_schema);
216 const base::ListValue* type_functions = nullptr;
217 CHECK(type_schema->GetList("functions", &type_functions));
218 const base::ListValue* parameters = nullptr;
219 for (const auto& function : *type_functions) {
220 const base::DictionaryValue* function_dict = nullptr;
221 CHECK(function->GetAsDictionary(&function_dict));
222 std::string name;
223 CHECK(function_dict->GetString("name", &name));
224 if (name == function_name) {
225 CHECK(function_dict->GetList("parameters", &parameters));
226 break;
227 }
228 }
229 CHECK(parameters);
230 auto signature = base::MakeUnique<APISignature>(*parameters);
231 auto raw_signature = signature.get();
232 signatures_[full_name] = std::move(signature);
233 return *raw_signature;
234 }
235
236 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/storage_area.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698