cc: Added inline to Tile::IsReadyToDraw
[chromium-blink-merge.git] / chromeos / network / onc / onc_translator_onc_to_shill.cc
blobab0b9d74a63038d480db2bf00d9dda259edb6548
1 // Copyright (c) 2012 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.
5 // The implementation of TranslateONCObjectToShill is structured in two parts:
6 // - The recursion through the existing ONC hierarchy
7 // see TranslateONCHierarchy
8 // - The local translation of an object depending on the associated signature
9 // see LocalTranslator::TranslateFields
11 #include "chromeos/network/onc/onc_translator.h"
13 #include <string>
15 #include "base/json/json_reader.h"
16 #include "base/json/json_writer.h"
17 #include "base/logging.h"
18 #include "base/values.h"
19 #include "chromeos/network/onc/onc_constants.h"
20 #include "chromeos/network/onc/onc_signature.h"
21 #include "chromeos/network/onc/onc_translation_tables.h"
22 #include "third_party/cros_system_api/dbus/service_constants.h"
24 namespace chromeos {
25 namespace onc {
27 namespace {
29 scoped_ptr<base::StringValue> ConvertValueToString(const base::Value& value) {
30 std::string str;
31 if (!value.GetAsString(&str))
32 base::JSONWriter::Write(&value, &str);
33 return make_scoped_ptr(base::Value::CreateStringValue(str));
36 // This class is responsible to translate the local fields of the given
37 // |onc_object| according to |onc_signature| into |shill_dictionary|. This
38 // translation should consider (if possible) only fields of this ONC object and
39 // not nested objects because recursion is handled by the calling function
40 // TranslateONCHierarchy.
41 class LocalTranslator {
42 public:
43 LocalTranslator(const OncValueSignature& onc_signature,
44 const base::DictionaryValue& onc_object,
45 base::DictionaryValue* shill_dictionary)
46 : onc_signature_(&onc_signature),
47 onc_object_(&onc_object),
48 shill_dictionary_(shill_dictionary) {
49 field_translation_table_ = GetFieldTranslationTable(onc_signature);
52 void TranslateFields();
54 private:
55 void TranslateOpenVPN();
56 void TranslateVPN();
57 void TranslateWiFi();
58 void TranslateEAP();
59 void TranslateNetworkConfiguration();
61 // Copies all entries from |onc_object_| to |shill_dictionary_| for which a
62 // translation (shill_property_name) is defined by |onc_signature_|.
63 void CopyFieldsAccordingToSignature();
65 // Adds |value| to |shill_dictionary| at the field shill_property_name given
66 // by the associated signature. Takes ownership of |value|. Does nothing if
67 // |value| is NULL or the property name cannot be read from the signature.
68 void AddValueAccordingToSignature(const std::string& onc_field_name,
69 scoped_ptr<base::Value> value);
71 // If existent, translates the entry at |onc_field_name| in |onc_object_|
72 // using |table|. It is an error if no matching table entry is found. Writes
73 // the result as entry at |shill_property_name| in |shill_dictionary_|.
74 void TranslateWithTableAndSet(const std::string& onc_field_name,
75 const StringTranslationEntry table[],
76 const std::string& shill_property_name);
78 const OncValueSignature* onc_signature_;
79 const FieldTranslationEntry* field_translation_table_;
80 const base::DictionaryValue* onc_object_;
81 base::DictionaryValue* shill_dictionary_;
83 DISALLOW_COPY_AND_ASSIGN(LocalTranslator);
86 void LocalTranslator::TranslateFields() {
87 if (onc_signature_ == &kNetworkConfigurationSignature)
88 TranslateNetworkConfiguration();
89 else if (onc_signature_ == &kVPNSignature)
90 TranslateVPN();
91 else if (onc_signature_ == &kOpenVPNSignature)
92 TranslateOpenVPN();
93 else if (onc_signature_ == &kWiFiSignature)
94 TranslateWiFi();
95 else if (onc_signature_ == &kEAPSignature)
96 TranslateEAP();
97 else
98 CopyFieldsAccordingToSignature();
101 void LocalTranslator::TranslateOpenVPN() {
102 // Shill supports only one RemoteCertKU but ONC a list.
103 // Copy only the first entry if existing.
104 const base::ListValue* certKUs = NULL;
105 std::string certKU;
106 if (onc_object_->GetListWithoutPathExpansion(openvpn::kRemoteCertKU,
107 &certKUs) &&
108 certKUs->GetString(0, &certKU)) {
109 shill_dictionary_->SetStringWithoutPathExpansion(
110 flimflam::kOpenVPNRemoteCertKUProperty, certKU);
113 for (base::DictionaryValue::Iterator it(*onc_object_); !it.IsAtEnd();
114 it.Advance()) {
115 scoped_ptr<base::Value> translated;
116 if (it.key() == vpn::kSaveCredentials ||
117 it.key() == openvpn::kRemoteCertKU ||
118 it.key() == openvpn::kServerCAPEMs) {
119 translated.reset(it.value().DeepCopy());
120 } else {
121 // Shill wants all Provider/VPN fields to be strings.
122 translated = ConvertValueToString(it.value());
124 AddValueAccordingToSignature(it.key(), translated.Pass());
128 void LocalTranslator::TranslateVPN() {
129 std::string type;
130 onc_object_->GetStringWithoutPathExpansion(vpn::kType, &type);
131 TranslateWithTableAndSet(type, kVPNTypeTable,
132 flimflam::kProviderTypeProperty);
134 CopyFieldsAccordingToSignature();
137 void LocalTranslator::TranslateWiFi() {
138 std::string security;
139 onc_object_->GetStringWithoutPathExpansion(wifi::kSecurity, &security);
140 TranslateWithTableAndSet(security, kWiFiSecurityTable,
141 flimflam::kSecurityProperty);
143 // We currently only support managed and no adhoc networks.
144 shill_dictionary_->SetStringWithoutPathExpansion(flimflam::kModeProperty,
145 flimflam::kModeManaged);
146 CopyFieldsAccordingToSignature();
149 void LocalTranslator::TranslateEAP() {
150 std::string outer;
151 onc_object_->GetStringWithoutPathExpansion(eap::kOuter, &outer);
152 TranslateWithTableAndSet(outer, kEAPOuterTable, flimflam::kEapMethodProperty);
154 // Translate the inner protocol only for outer tunneling protocols.
155 if (outer == eap::kPEAP || outer == eap::kEAP_TTLS) {
156 // In ONC the Inner protocol defaults to "Automatic".
157 std::string inner = eap::kAutomatic;
158 // ONC's Inner == "Automatic" translates to omitting the Phase2 property in
159 // Shill.
160 onc_object_->GetStringWithoutPathExpansion(eap::kInner, &inner);
161 if (inner != eap::kAutomatic) {
162 const StringTranslationEntry* table =
163 outer == eap::kPEAP ? kEAP_PEAP_InnerTable : kEAP_TTLS_InnerTable;
164 TranslateWithTableAndSet(inner, table, flimflam::kEapPhase2AuthProperty);
168 CopyFieldsAccordingToSignature();
171 void LocalTranslator::TranslateNetworkConfiguration() {
172 std::string type;
173 onc_object_->GetStringWithoutPathExpansion(network_config::kType, &type);
174 TranslateWithTableAndSet(type, kNetworkTypeTable, flimflam::kTypeProperty);
176 // Shill doesn't allow setting the name for non-VPN networks.
177 if (type == network_type::kVPN) {
178 std::string name;
179 onc_object_->GetStringWithoutPathExpansion(network_config::kName, &name);
180 shill_dictionary_->SetStringWithoutPathExpansion(
181 flimflam::kNameProperty, name);
184 CopyFieldsAccordingToSignature();
187 void LocalTranslator::CopyFieldsAccordingToSignature() {
188 for (base::DictionaryValue::Iterator it(*onc_object_); !it.IsAtEnd();
189 it.Advance()) {
190 AddValueAccordingToSignature(it.key(),
191 make_scoped_ptr(it.value().DeepCopy()));
195 void LocalTranslator::AddValueAccordingToSignature(
196 const std::string& onc_name,
197 scoped_ptr<base::Value> value) {
198 if (!value || !field_translation_table_)
199 return;
201 std::string shill_property_name;
202 if (!GetShillPropertyName(onc_name,
203 field_translation_table_,
204 &shill_property_name))
205 return;
207 shill_dictionary_->SetWithoutPathExpansion(shill_property_name,
208 value.release());
211 void LocalTranslator::TranslateWithTableAndSet(
212 const std::string& onc_value,
213 const StringTranslationEntry table[],
214 const std::string& shill_property_name) {
215 std::string shill_value;
216 if (TranslateStringToShill(table, onc_value, &shill_value)) {
217 shill_dictionary_->SetStringWithoutPathExpansion(shill_property_name,
218 shill_value);
219 return;
221 // As we previously validate ONC, this case should never occur. If it still
222 // occurs, we should check here. Otherwise the failure will only show up much
223 // later in Shill.
224 LOG(ERROR) << "Value '" << onc_value
225 << "' cannot be translated to Shill property "
226 << shill_property_name;
229 // Iterates recursively over |onc_object| and its |signature|. At each object
230 // applies the local translation using LocalTranslator::TranslateFields. The
231 // results are written to |shill_dictionary|.
232 void TranslateONCHierarchy(const OncValueSignature& signature,
233 const base::DictionaryValue& onc_object,
234 base::DictionaryValue* shill_dictionary) {
235 // Translates fields of |onc_object| and writes them to |shill_dictionary_|.
236 LocalTranslator translator(signature, onc_object, shill_dictionary);
237 translator.TranslateFields();
239 // Recurse into nested objects.
240 for (base::DictionaryValue::Iterator it(onc_object); !it.IsAtEnd();
241 it.Advance()) {
242 const base::DictionaryValue* inner_object = NULL;
243 if (!it.value().GetAsDictionary(&inner_object))
244 continue;
246 const OncFieldSignature* field_signature =
247 GetFieldSignature(signature, it.key());
249 TranslateONCHierarchy(*field_signature->value_signature, *inner_object,
250 shill_dictionary);
254 } // namespace
256 scoped_ptr<base::DictionaryValue> TranslateONCObjectToShill(
257 const OncValueSignature* onc_signature,
258 const base::DictionaryValue& onc_object) {
259 CHECK(onc_signature != NULL);
260 scoped_ptr<base::DictionaryValue> shill_dictionary(new base::DictionaryValue);
261 TranslateONCHierarchy(*onc_signature, onc_object, shill_dictionary.get());
262 return shill_dictionary.Pass();
265 } // namespace onc
266 } // namespace chromeos