Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 | |
| OLD | NEW |