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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: extensions/renderer/chrome_setting.cc
diff --git a/extensions/renderer/chrome_setting.cc b/extensions/renderer/chrome_setting.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c32c094245b6f58e00dd120be245938a38ff715d
--- /dev/null
+++ b/extensions/renderer/chrome_setting.cc
@@ -0,0 +1,182 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/renderer/chrome_setting.h"
+
+#include "base/memory/ptr_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/values.h"
+#include "extensions/renderer/api_custom_types.h"
+#include "extensions/renderer/api_event_handler.h"
+#include "extensions/renderer/api_request_handler.h"
+#include "extensions/renderer/api_signature.h"
+#include "gin/arguments.h"
+#include "gin/handle.h"
+#include "gin/object_template_builder.h"
+
+namespace extensions {
+
+v8::Local<v8::Object> ChromeSetting::CreateChromeSetting(
+ v8::Local<v8::Context> context,
+ const std::string& property_name,
+ APIRequestHandler* request_handler,
+ APIEventHandler* event_handler,
+ APITypeReferenceMap* type_refs) {
+ auto value_spec = base::MakeUnique<base::DictionaryValue>();
+ // Most ChromeSettings have a pref that matches the property name and are of
+ // type boolean.
+ 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.
+ std::string type = "boolean";
+
+ // A few of ChromeSettings are special, and have different arguments.
+ std::string ref;
+ if (property_name == "animationPolicy") {
+ type = "string";
+ auto enum_list = base::MakeUnique<base::ListValue>();
+ enum_list->AppendString("allowed");
+ enum_list->AppendString("once");
+ enum_list->AppendString("none");
+ value_spec->Set("enum", std::move(enum_list));
+ } else if (property_name == "webRTCIPHandlingPolicy") {
+ ref = "IPHandlingPolicy";
+ } else if (property_name == "spdyProxyEnabled") {
+ pref_name = "spdy_proxy.enabled";
+ } else if (property_name == "dataReductionDailyContentLength") {
+ type = "array";
+ pref_name = "data_reduction.daily_original_length";
+ } else if (property_name == "dataReductionDailyReceivedLength") {
+ type = "array";
+ pref_name = "data_reduction.daily_received_length";
+ } else if (property_name == "dataUsageReportingEnabled") {
+ pref_name = "data_usage_reporting.enabled";
+ } else if (property_name == "proxy") {
+ ref = "ProxyConfig";
+ }
+
+ if (!ref.empty())
+ value_spec->SetString("$ref", ref);
+ else
+ value_spec->SetString("type", type);
+
+ // The set() call takes an object { value: { type: <t> }, ... }, where <t>
+ // is the custom set() argument specified above by value_spec.
+ base::DictionaryValue set_spec;
+ set_spec.SetString("type", "object");
+ auto properties = base::MakeUnique<base::DictionaryValue>();
+ properties->Set("value", std::move(value_spec));
+ set_spec.Set("properties", std::move(properties));
+
+ gin::Handle<ChromeSetting> handle =
+ gin::CreateHandle(context->GetIsolate(),
+ new ChromeSetting(request_handler, event_handler,
+ type_refs, pref_name, set_spec));
+ return handle.ToV8().As<v8::Object>();
+}
+
+ChromeSetting::ChromeSetting(APIRequestHandler* request_handler,
+ APIEventHandler* event_handler,
+ const APITypeReferenceMap* type_refs,
+ const std::string& pref_name,
+ const base::DictionaryValue& argument_spec)
+ : request_handler_(request_handler),
+ event_handler_(event_handler),
+ type_refs_(type_refs),
+ pref_name_(pref_name),
+ argument_spec_(argument_spec) {}
+
+ChromeSetting::~ChromeSetting() = default;
+
+gin::WrapperInfo ChromeSetting::kWrapperInfo = {gin::kEmbedderNativeGin};
+
+gin::ObjectTemplateBuilder ChromeSetting::GetObjectTemplateBuilder(
+ v8::Isolate* isolate) {
+ return Wrappable<ChromeSetting>::GetObjectTemplateBuilder(isolate)
+ .SetMethod("get", &ChromeSetting::Get)
+ .SetMethod("set", &ChromeSetting::Set)
+ .SetMethod("clear", &ChromeSetting::Clear)
+ .SetProperty("onChange", &ChromeSetting::GetOnChangeEvent);
+}
+
+void ChromeSetting::Get(gin::Arguments* arguments) {
+ HandleFunction("get", arguments);
+}
+
+void ChromeSetting::Set(gin::Arguments* arguments) {
+ v8::Isolate* isolate = arguments->isolate();
+ v8::HandleScope handle_scope(isolate);
+
+ v8::Local<v8::Object> holder;
+ CHECK(arguments->GetHolder(&holder));
+ v8::Local<v8::Context> context = holder->CreationContext();
+
+ v8::Local<v8::Value> value = arguments->PeekNext();
+ // The set schema included in the Schema object is generic, since it varies
+ // per-setting. However, this is only ever for a single setting, so we can
+ // enforce the types more thoroughly.
+ std::string error;
+ if (!value.IsEmpty() &&
+ !argument_spec_.ParseArgument(context, value, *type_refs_, nullptr,
+ &error)) {
+ arguments->ThrowTypeError("Invalid invocation");
+ return;
+ }
+ HandleFunction("set", arguments);
+}
+
+void ChromeSetting::Clear(gin::Arguments* arguments) {
+ HandleFunction("clear", arguments);
+}
+
+v8::Local<v8::Value> ChromeSetting::GetOnChangeEvent(
+ gin::Arguments* arguments) {
+ v8::Local<v8::Value> event;
+ if (event_.IsEmpty()) {
+ v8::Local<v8::Object> holder;
+ CHECK(arguments->GetHolder(&holder));
+ v8::Local<v8::Context> context = holder->CreationContext();
+
+ event = event_handler_->CreateEventInstance(
+ base::StringPrintf("types.ChromeSetting.%s.onChange",
+ pref_name_.c_str()),
+ context);
+ event_.Reset(arguments->isolate(), event);
+ } else {
+ event = event_.Get(arguments->isolate());
+ }
+ return event;
+}
+
+void ChromeSetting::HandleFunction(const std::string& method_name,
+ gin::Arguments* arguments) {
+ v8::Isolate* isolate = arguments->isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Object> holder;
+ CHECK(arguments->GetHolder(&holder));
+ v8::Local<v8::Context> context = holder->CreationContext();
+
+ std::vector<v8::Local<v8::Value>> argument_list;
+ if (arguments->Length() > 0) {
+ // Just copying handles should never fail.
+ CHECK(arguments->GetRemaining(&argument_list));
+ }
+
+ std::unique_ptr<base::ListValue> converted_arguments;
+ v8::Local<v8::Function> callback;
+ std::string error;
+
+ if (!api_custom_types::GetFunctionSchema("types", "types.ChromeSetting",
+ method_name)
+ .ParseArgumentsToJSON(context, argument_list, *type_refs_,
+ &converted_arguments, &callback, &error)) {
+ arguments->ThrowTypeError("Invalid invocation");
+ return;
+ }
+
+ converted_arguments->Insert(0u, base::MakeUnique<base::Value>(pref_name_));
+ request_handler_->StartRequest(context, "types.ChromeSetting." + method_name,
+ std::move(converted_arguments), callback,
+ v8::Local<v8::Function>());
+}
+
+} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698