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

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

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

Powered by Google App Engine
This is Rietveld 408576698