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

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

Issue 2718543004: [Extensions Bindings] Add ChromeSetting custom type (Closed)
Patch Set: rebase Created 3 years, 9 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
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/chrome_setting.h"
6
7 #include "base/memory/ptr_util.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/values.h"
10 #include "extensions/renderer/api_event_handler.h"
11 #include "extensions/renderer/api_request_handler.h"
12 #include "extensions/renderer/api_signature.h"
13 #include "extensions/renderer/api_type_reference_map.h"
14 #include "gin/arguments.h"
15 #include "gin/handle.h"
16 #include "gin/object_template_builder.h"
17
18 namespace extensions {
19
20 v8::Local<v8::Object> ChromeSetting::Create(v8::Local<v8::Context> context,
21 const std::string& property_name,
22 APIRequestHandler* request_handler,
23 APIEventHandler* event_handler,
24 APITypeReferenceMap* type_refs) {
25 auto value_spec = base::MakeUnique<base::DictionaryValue>();
26 // Most ChromeSettings have a pref that matches the property name and are of
27 // type boolean.
28 base::StringPiece pref_name = property_name;
29 base::StringPiece type = "boolean";
30
31 // A few of ChromeSettings are special, and have different arguments.
32 base::StringPiece ref;
33 if (property_name == "animationPolicy") {
34 type = "string";
35 auto enum_list = base::MakeUnique<base::ListValue>();
36 enum_list->AppendString("allowed");
37 enum_list->AppendString("once");
38 enum_list->AppendString("none");
39 value_spec->Set("enum", std::move(enum_list));
40 } else if (property_name == "webRTCIPHandlingPolicy") {
41 ref = "IPHandlingPolicy";
42 } else if (property_name == "spdyProxyEnabled") {
43 pref_name = "spdy_proxy.enabled";
44 } else if (property_name == "dataReductionDailyContentLength") {
45 type = "array";
46 pref_name = "data_reduction.daily_original_length";
47 } else if (property_name == "dataReductionDailyReceivedLength") {
48 type = "array";
49 pref_name = "data_reduction.daily_received_length";
50 } else if (property_name == "dataUsageReportingEnabled") {
51 pref_name = "data_usage_reporting.enabled";
52 } else if (property_name == "proxy") {
53 ref = "ProxyConfig";
54 }
55
56 if (!ref.empty())
57 value_spec->SetString("$ref", ref);
58 else
59 value_spec->SetString("type", type);
60
61 // The set() call takes an object { value: { type: <t> }, ... }, where <t>
62 // is the custom set() argument specified above by value_spec.
63 base::DictionaryValue set_spec;
64 set_spec.SetString("type", "object");
65 auto properties = base::MakeUnique<base::DictionaryValue>();
66 properties->Set("value", std::move(value_spec));
67 set_spec.Set("properties", std::move(properties));
68
69 gin::Handle<ChromeSetting> handle = gin::CreateHandle(
70 context->GetIsolate(),
71 new ChromeSetting(request_handler, event_handler, type_refs,
72 pref_name.as_string(), set_spec));
73 return handle.ToV8().As<v8::Object>();
74 }
75
76 ChromeSetting::ChromeSetting(APIRequestHandler* request_handler,
77 APIEventHandler* event_handler,
78 const APITypeReferenceMap* type_refs,
79 const std::string& pref_name,
80 const base::DictionaryValue& argument_spec)
81 : request_handler_(request_handler),
82 event_handler_(event_handler),
83 type_refs_(type_refs),
84 pref_name_(pref_name),
85 argument_spec_(argument_spec) {}
86
87 ChromeSetting::~ChromeSetting() = default;
88
89 gin::WrapperInfo ChromeSetting::kWrapperInfo = {gin::kEmbedderNativeGin};
90
91 gin::ObjectTemplateBuilder ChromeSetting::GetObjectTemplateBuilder(
92 v8::Isolate* isolate) {
93 return Wrappable<ChromeSetting>::GetObjectTemplateBuilder(isolate)
94 .SetMethod("get", &ChromeSetting::Get)
95 .SetMethod("set", &ChromeSetting::Set)
96 .SetMethod("clear", &ChromeSetting::Clear)
97 .SetProperty("onChange", &ChromeSetting::GetOnChangeEvent);
98 }
99
100 void ChromeSetting::Get(gin::Arguments* arguments) {
101 HandleFunction("get", arguments);
102 }
103
104 void ChromeSetting::Set(gin::Arguments* arguments) {
105 v8::Isolate* isolate = arguments->isolate();
106 v8::HandleScope handle_scope(isolate);
107
108 v8::Local<v8::Object> holder;
109 CHECK(arguments->GetHolder(&holder));
110 v8::Local<v8::Context> context = holder->CreationContext();
111
112 v8::Local<v8::Value> value = arguments->PeekNext();
113 // The set schema included in the Schema object is generic, since it varies
114 // per-setting. However, this is only ever for a single setting, so we can
115 // enforce the types more thoroughly.
116 std::string error;
117 if (!value.IsEmpty() && !argument_spec_.ParseArgument(
118 context, value, *type_refs_, nullptr, &error)) {
119 arguments->ThrowTypeError("Invalid invocation");
120 return;
121 }
122 HandleFunction("set", arguments);
123 }
124
125 void ChromeSetting::Clear(gin::Arguments* arguments) {
126 HandleFunction("clear", arguments);
127 }
128
129 v8::Local<v8::Value> ChromeSetting::GetOnChangeEvent(
130 gin::Arguments* arguments) {
131 v8::Isolate* isolate = arguments->isolate();
132 v8::Local<v8::Object> holder;
133 CHECK(arguments->GetHolder(&holder));
134 v8::Local<v8::Context> context = holder->CreationContext();
135 v8::Local<v8::Object> wrapper = GetWrapper(isolate);
136 v8::Local<v8::Private> key = v8::Private::ForApi(
137 isolate, gin::StringToSymbol(isolate, "onChangeEvent"));
138 v8::Local<v8::Value> event;
139 if (!wrapper->GetPrivate(context, key).ToLocal(&event)) {
140 NOTREACHED();
141 return v8::Local<v8::Value>();
142 }
143
144 DCHECK(!event.IsEmpty());
145 if (event->IsUndefined()) {
146 event = event_handler_->CreateEventInstance(
147 base::StringPrintf("types.ChromeSetting.%s.onChange",
148 pref_name_.c_str()),
149 context);
150 v8::Maybe<bool> set_result = wrapper->SetPrivate(context, key, event);
151 if (!set_result.IsJust() || !set_result.FromJust()) {
152 NOTREACHED();
153 return v8::Local<v8::Value>();
154 }
155 }
156 return event;
157 }
158
159 void ChromeSetting::HandleFunction(const std::string& method_name,
160 gin::Arguments* arguments) {
161 v8::Isolate* isolate = arguments->isolate();
162 v8::HandleScope handle_scope(isolate);
163 v8::Local<v8::Object> holder;
164 CHECK(arguments->GetHolder(&holder));
165 v8::Local<v8::Context> context = holder->CreationContext();
166
167 std::vector<v8::Local<v8::Value>> argument_list;
168 if (arguments->Length() > 0) {
169 // Just copying handles should never fail.
170 CHECK(arguments->GetRemaining(&argument_list));
171 }
172
173 std::string full_name = "types.ChromeSetting." + method_name;
174 std::unique_ptr<base::ListValue> converted_arguments;
175 v8::Local<v8::Function> callback;
176 std::string error;
177 if (!type_refs_->GetTypeMethodSignature(full_name)->ParseArgumentsToJSON(
178 context, argument_list, *type_refs_, &converted_arguments, &callback,
179 &error)) {
180 arguments->ThrowTypeError("Invalid invocation");
181 return;
182 }
183
184 converted_arguments->Insert(0u, base::MakeUnique<base::Value>(pref_name_));
185 request_handler_->StartRequest(context, full_name,
186 std::move(converted_arguments), callback,
187 v8::Local<v8::Function>());
188 }
189
190 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/chrome_setting.h ('k') | extensions/renderer/native_extension_bindings_system.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698