summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-21 16:05:46 +0000
committerstevenjb@chromium.org <stevenjb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-21 16:07:35 +0000
commitba37c3405e4e33be4fb578871b706837a02b9f28 (patch)
tree7643a8cb1302401384f3c3f174c3a56946789f57
parent4e5cb4028b3acf74fa5d8f15d0a1c9843e449c22 (diff)
downloadchromium_src-ba37c3405e4e33be4fb578871b706837a02b9f28.zip
chromium_src-ba37c3405e4e33be4fb578871b706837a02b9f28.tar.gz
chromium_src-ba37c3405e4e33be4fb578871b706837a02b9f28.tar.bz2
Use Managed properties for Preferred and Provider.
This includes some necessary ONC translation fixes. BUG=279351 R=armansito@chromium.org, pneubeck@chromium.org Review URL: https://codereview.chromium.org/482243002 Cr-Commit-Position: refs/heads/master@{#291085} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@291085 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/resources/options/chromeos/internet_detail.html6
-rw-r--r--chrome/browser/resources/options/chromeos/internet_detail.js213
-rw-r--r--chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc164
-rw-r--r--chromeos/network/onc/onc_signature.cc1
-rw-r--r--chromeos/network/onc/onc_translation_tables.cc14
-rw-r--r--chromeos/network/onc/onc_translation_tables.h26
-rw-r--r--chromeos/network/onc/onc_translator_onc_to_shill.cc32
-rw-r--r--chromeos/network/onc/onc_translator_shill_to_onc.cc96
-rw-r--r--chromeos/network/onc/onc_translator_unittest.cc6
-rw-r--r--chromeos/test/data/network/shill_openvpn_with_errors.json26
-rw-r--r--chromeos/test/data/network/shill_output_l2tpipsec.json14
-rw-r--r--chromeos/test/data/network/shill_output_openvpn.json34
-rw-r--r--chromeos/test/data/network/shill_output_openvpn_with_errors.json28
-rw-r--r--chromeos/test/data/network/shill_wifi_with_state.json2
-rw-r--r--chromeos/test/data/network/translation_of_shill_l2tpipsec.onc4
-rw-r--r--chromeos/test/data/network/translation_of_shill_wifi_with_state.onc2
-rw-r--r--components/onc/docs/onc_spec.html11
-rw-r--r--components/onc/onc_constants.cc1
-rw-r--r--components/onc/onc_constants.h1
19 files changed, 475 insertions, 206 deletions
diff --git a/chrome/browser/resources/options/chromeos/internet_detail.html b/chrome/browser/resources/options/chromeos/internet_detail.html
index ec541b2..dd939e8 100644
--- a/chrome/browser/resources/options/chromeos/internet_detail.html
+++ b/chrome/browser/resources/options/chromeos/internet_detail.html
@@ -74,8 +74,8 @@
<label for="prefer-network-wifi"
i18n-content="inetPreferredNetwork">
</label>
- <span class="controlled-setting-indicator" data="preferred"
- for="prefer-network-wifi">
+ <span class="controlled-setting-indicator"
+ managed="Priority" for="prefer-network-wifi">
</span>
</span>
</span>
@@ -224,7 +224,7 @@
<td>
<input class="option-value" id="inet-server-hostname"></input>
<span class="controlled-setting-indicator"
- data="serverHostname" for="inet-server-hostname"></span>
+ managed="VPN.Host" for="inet-server-hostname"></span>
</td>
</tr>
<tr>
diff --git a/chrome/browser/resources/options/chromeos/internet_detail.js b/chrome/browser/resources/options/chromeos/internet_detail.js
index 7447b52..431e7d2 100644
--- a/chrome/browser/resources/options/chromeos/internet_detail.js
+++ b/chrome/browser/resources/options/chromeos/internet_detail.js
@@ -15,23 +15,60 @@ cr.define('options.internet', function() {
/** @const */ var ArrayDataModel = cr.ui.ArrayDataModel;
/** @const */ var IPAddressField = options.internet.IPAddressField;
+ var GetManagedTypes = {
+ ACTIVE: 0,
+ TRANSLATED: 1,
+ RECOMMENDED: 2
+ };
+
/**
- * Helper function to get the "Active" value of a property from a dictionary
- * that includes ONC managed properties, e.g. getActiveValue(data, 'Name').
- * We use (data, key) instead of getActiveValue(data[key]) so that we can
- * (possibly) add ONC key validation once all properties use ONC.
+ * Gets the value of a property from a dictionary |data| that includes ONC
+ * managed properties, e.g. getManagedValue(data, 'Name'). See notes for
+ * getManagedProperty.
* @param {object} data The properties dictionary.
* @param {string} key The property key.
- * @return {*} the property value or undefined.
+ * @param {string} type (Optional) The type of property to get as defined in
+ * GetManagedTypes:
+ * 'ACTIVE' (default) - gets the active value
+ * 'TRANSLATED' - gets the traslated or active value
+ * 'RECOMMENDED' - gets the recommended value
+ * @return {*} The property value or undefined.
*/
- function getActiveValue(data, key) {
- if (!(key in data))
- return undefined;
- var property = data[key];
+ function getManagedValue(data, key, type) {
+ var property = getManagedProperty(data, key);
if (typeof property != 'object')
return property;
+ if (type == GetManagedTypes.RECOMMENDED)
+ return getRecommendedValue(property);
+ if (type == GetManagedTypes.TRANSLATED && 'Translated' in property)
+ return property['Translated'];
+ // Otherwise get the Active value (defalt behavior).
if ('Active' in property)
return property['Active'];
+ // If no Active value is defined, return the effective value.
+ return getEffectiveValue(property);
+ }
+
+ /**
+ * Get the recommended value from a Managed property ONC dictionary.
+ * @param {object} property The managed property ONC dictionary.
+ * @return {*} the effective value or undefined.
+ */
+ function getRecommendedValue(property) {
+ if (property['UserEditable'])
+ return property['UserPolicy'];
+ if (property['DeviceEditable'])
+ return property['DevicePolicy'];
+ // No value recommended by policy.
+ return undefined;
+ }
+
+ /**
+ * Get the effective value from a Managed property ONC dictionary.
+ * @param {object} property The managed property ONC dictionary.
+ * @return {*} The effective value or undefined.
+ */
+ function getEffectiveValue(property) {
if ('Effective' in property) {
var effective = property.Effective;
if (effective in property)
@@ -41,15 +78,26 @@ cr.define('options.internet', function() {
}
/**
- * Helper function for nested ONC properties, e.g. data[WiFi][Strength].
- * @param {object|string} property The property which must ether be
- * a dictionary object or not be present.
- * @return {*} the property value or undefined.
+ * Gets either a managed property dictionary or an unmanaged value from
+ * dictionary |data| that includes ONC managed properties. This supports
+ * nested dictionaries, e.g. getManagedProperty(data, 'VPN.Type').
+ * @param {object} data The properties dictionary.
+ * @param {string} key The property key.
+ * @return {*} The property value or dictionary if it exists, otherwise
+ * undefined.
*/
- function getActiveDictionaryValue(data, dict, key) {
- if (!(dict in data))
- return undefined;
- return getActiveValue(data[dict], key);
+ function getManagedProperty(data, key) {
+ while (true) {
+ var index = key.indexOf('.');
+ if (index < 0)
+ break;
+ var keyComponent = key.substr(0, index);
+ if (!(keyComponent in data))
+ return undefined;
+ data = data[keyComponent];
+ key = key.substr(index + 1);
+ }
+ return data[key];
}
/**
@@ -135,7 +183,7 @@ cr.define('options.internet', function() {
function getNetworkName(data) {
if (data.type == 'Ethernet')
return loadTimeData.getString('ethernetName');
- return getActiveValue(data, 'Name');
+ return getManagedValue(data, 'Name');
}
/////////////////////////////////////////////////////////////////////////////
@@ -908,7 +956,7 @@ cr.define('options.internet', function() {
return;
}
- var connectState = getActiveValue(data, 'ConnectionState');
+ var connectState = getManagedValue(data, 'ConnectionState');
if (connectState == 'NotConnected') {
$('details-internet-login').hidden = false;
// Connecting to an unconfigured network might trigger certificate
@@ -921,7 +969,7 @@ cr.define('options.internet', function() {
$('details-internet-disconnect').hidden = false;
}
- var connectable = getActiveValue(data, 'Connectable');
+ var connectable = getManagedValue(data, 'Connectable');
if (connectState != 'Connected' &&
(!connectable || this.hasSecurity ||
(data.type == 'Wimax' || data.type == 'VPN'))) {
@@ -946,7 +994,7 @@ cr.define('options.internet', function() {
// Update our cached data object.
updateDataObject(data, update);
- var connectionState = getActiveValue(data, 'ConnectionState');
+ var connectionState = getManagedValue(data, 'ConnectionState');
var connectionStateString = networkOncStateString(connectionState);
detailsPage.deviceConnected = data.deviceConnected;
detailsPage.connected = connectionState == 'Connected';
@@ -982,11 +1030,11 @@ cr.define('options.internet', function() {
DetailsInternetPage.showDetailedInfo = function(data) {
var detailsPage = DetailsInternetPage.getInstance();
- data.type = getActiveValue(data, 'Type'); // Get Active Type value.
+ data.type = getManagedValue(data, 'Type'); // Get Active Type value.
// Populate header
$('network-details-title').textContent = getNetworkName(data);
- var connectionState = getActiveValue(data, 'ConnectionState');
+ var connectionState = getManagedValue(data, 'ConnectionState');
var connectionStateString = networkOncStateString(connectionState);
detailsPage.connected = connectionState == 'Connected';
$('network-details-subtitle-status').textContent = connectionStateString;
@@ -1130,7 +1178,7 @@ cr.define('options.internet', function() {
DetailsInternetPage.updateNameServerDisplay(data.nameServerType);
- var macAddress = getActiveValue(data, 'MacAddress');
+ var macAddress = getManagedValue(data, 'MacAddress');
if (macAddress) {
$('hardware-address').textContent = macAddress;
$('hardware-address-row').style.display = 'table-row';
@@ -1153,8 +1201,7 @@ cr.define('options.internet', function() {
// Signal strength as percentage (for WiFi and Wimax).
var signalStrength;
if (data.type == 'WiFi' || data.type == 'Wimax') {
- signalStrength =
- getActiveDictionaryValue(data, data.type, 'SignalStrength');
+ signalStrength = getManagedValue(data, data.type + '.SignalStrength');
}
if (!signalStrength)
signalStrength = 0;
@@ -1163,21 +1210,20 @@ cr.define('options.internet', function() {
detailsPage.type = data.type;
if (data.type == 'WiFi') {
- assert(data.WiFi, 'WiFi network has no WiFi object' + networkName);
+ assert('WiFi' in data, 'WiFi network has no WiFi object' + networkName);
OptionsPage.showTab($('wifi-network-nav-tab'));
detailsPage.gsm = false;
detailsPage.shared = data.shared;
$('wifi-connection-state').textContent = connectionStateString;
- var ssid = getActiveDictionaryValue(data, 'WiFi', 'SSID');
+ var ssid = getManagedValue(data, 'WiFi.SSID');
$('wifi-ssid').textContent = ssid ? ssid : networkName;
- setOrHideParent('wifi-bssid',
- getActiveDictionaryValue(data, 'WiFi', 'BSSID'));
- var security = getActiveDictionaryValue(data, 'WiFi', 'Security');
+ setOrHideParent('wifi-bssid', getManagedValue(data, 'WiFi.BSSID'));
+ var security = getManagedValue(data, 'WiFi.Security');
if (security == 'None')
security = undefined;
setOrHideParent('wifi-security', security);
// Frequency is in MHz.
- var frequency = getActiveDictionaryValue(data, 'WiFi', 'Frequency');
+ var frequency = getManagedValue(data, 'WiFi.Frequency');
if (!frequency)
frequency = 0;
var frequencyFormat = loadTimeData.getString('inetFrequencyFormat');
@@ -1185,31 +1231,33 @@ cr.define('options.internet', function() {
$('wifi-frequency').textContent = frequencyFormat;
$('wifi-signal-strength').textContent = strengthString;
setOrHideParent('wifi-hardware-address',
- getActiveValue(data, 'MacAddress'));
+ getManagedValue(data, 'MacAddress'));
detailsPage.showPreferred = data.remembered;
- $('prefer-network-wifi').checked = data.preferred.value;
+ var priority = getManagedValue(data, 'Priority');
+ $('prefer-network-wifi').checked = priority > 0;
$('prefer-network-wifi').disabled = !data.remembered;
$('auto-connect-network-wifi').checked =
- getActiveValue(data, 'AutoConnect');
+ getManagedValue(data, 'AutoConnect');
$('auto-connect-network-wifi').disabled = !data.remembered;
detailsPage.hasSecurity = security != undefined;
} else if (data.type == 'Wimax') {
- assert(data.Wimax, 'Wimax network has no Wimax object' + networkName);
+ assert('Wimax' in data,
+ 'Wimax network has no Wimax object' + networkName);
OptionsPage.showTab($('wimax-network-nav-tab'));
detailsPage.gsm = false;
detailsPage.shared = data.shared;
detailsPage.showPreferred = data.remembered;
$('wimax-connection-state').textContent = connectionStateString;
$('auto-connect-network-wimax').checked =
- getActiveValue(data, 'AutoConnect');
+ getManagedValue(data, 'AutoConnect');
$('auto-connect-network-wimax').disabled = !data.remembered;
var identity;
if (data.Wimax.EAP)
- identity = getActiveValue(data.Wimax.EAP, 'Identity');
+ identity = getManagedValue(data.Wimax.EAP, 'Identity');
setOrHideParent('wimax-eap-identity', identity);
$('wimax-signal-strength').textContent = strengthString;
} else if (data.type == 'Cellular') {
- assert(data.Cellular,
+ assert('Cellular' in data,
'Cellular network has no Cellular object' + networkName);
OptionsPage.showTab($('cellular-conn-nav-tab'));
if (data.showCarrierSelect && data.currentCarrierIndex != -1) {
@@ -1227,27 +1275,29 @@ cr.define('options.internet', function() {
}
$('network-technology').textContent =
- getActiveDictionaryValue(data, 'Cellular', 'NetworkTechnology');
+ getManagedValue(data, 'Cellular.NetworkTechnology');
$('activation-state').textContent = data.activationState;
$('roaming-state').textContent = data.roamingState;
$('restricted-pool').textContent = data.restrictedPool;
$('error-state').textContent = data.errorMessage;
$('manufacturer').textContent =
- getActiveDictionaryValue(data, 'Cellular', 'Manufacturer');
- $('model-id').textContent =
- getActiveDictionaryValue(data, 'Cellular', 'ModelID');
+ getManagedValue(data, 'Cellular.Manufacturer');
+ $('model-id').textContent = getManagedValue(data, 'Cellular.ModelID');
$('firmware-revision').textContent =
- getActiveDictionaryValue(data, 'Cellular', 'FirmwareRevision');
+ getManagedValue(data, 'Cellular.FirmwareRevision');
$('hardware-revision').textContent =
- getActiveDictionaryValue(data, 'Cellular', 'HardwareRevision');
- $('mdn').textContent = getActiveDictionaryValue(data, 'Cellular', 'MDN');
+ getManagedValue(data, 'Cellular.HardwareRevision');
+ $('mdn').textContent = getManagedValue(data, 'Cellular.MDN');
// Show ServingOperator properties only if available.
- if (data.Cellular.ServingOperator) {
- $('operator-name').textContent =
- getActiveValue(data.Cellular.ServingOperator, 'Name');
- $('operator-code').textContent =
- getActiveValue(data.Cellular.ServingOperator, 'Code');
+ var servingOperatorName =
+ getManagedValue(data, 'Cellular.ServingOperator.Name');
+ var servingOperatorCode =
+ getManagedValue(data, 'Cellular.ServingOperator.Code');
+ if (servingOperatorName != undefined &&
+ servingOperatorCode != undefined) {
+ $('operator-name').textContent = servingOperatorName;
+ $('operator-code').textContent = servingOperatorCode;
} else {
$('operator-name').parentElement.hidden = true;
$('operator-code').parentElement.hidden = true;
@@ -1258,23 +1308,18 @@ cr.define('options.internet', function() {
updateHidden('#details-internet-page .cdma-only', false);
// Show IMEI/ESN/MEID/MIN/PRL only if they are available.
- setOrHideParent('esn', getActiveDictionaryValue(data, 'Cellular', 'ESN'));
- setOrHideParent(
- 'imei', getActiveDictionaryValue(data, 'Cellular', 'IMEI'));
- setOrHideParent(
- 'meid', getActiveDictionaryValue(data, 'Cellular', 'MEID'));
- setOrHideParent('min', getActiveDictionaryValue(data, 'Cellular', 'MIN'));
- setOrHideParent(
- 'prl-version',
- getActiveDictionaryValue(data, 'Cellular', 'PRLVersion'));
-
- var family = getActiveDictionaryValue(data, 'Cellular', 'GSM');
+ setOrHideParent('esn', getManagedValue(data, 'Cellular.ESN'));
+ setOrHideParent('imei', getManagedValue(data, 'Cellular.IMEI'));
+ setOrHideParent('meid', getManagedValue(data, 'Cellular.MEID'));
+ setOrHideParent('min', getManagedValue(data, 'Cellular.MIN'));
+ setOrHideParent('prl-version',
+ getManagedValue(data, 'Cellular.PRLVersion'));
+
+ var family = getManagedValue(data, 'Cellular.GSM');
detailsPage.gsm = family == 'GSM';
if (detailsPage.gsm) {
- $('iccid').textContent =
- getActiveDictionaryValue(data, 'Cellular', 'ICCID');
- $('imsi').textContent =
- getActiveDictionaryValue(data, 'Cellular', 'IMSI');
+ $('iccid').textContent = getManagedValue(data, 'Cellular.ICCID');
+ $('imsi').textContent = getManagedValue(data, 'Cellular.IMSI');
var apnSelector = $('select-apn');
// Clear APN lists, keep only last element that "other".
@@ -1324,7 +1369,7 @@ cr.define('options.internet', function() {
$('change-pin').hidden = !lockEnabled;
}
$('auto-connect-network-cellular').checked =
- getActiveValue(data, 'AutoConnect');
+ getManagedValue(data, 'AutoConnect');
$('auto-connect-network-cellular').disabled = false;
$('buyplan-details').hidden = !data.showBuyButton;
@@ -1337,16 +1382,24 @@ cr.define('options.internet', function() {
OptionsPage.showTab($('vpn-nav-tab'));
detailsPage.gsm = false;
$('inet-service-name').textContent = networkName;
- $('inet-provider-type').textContent = data.providerType;
- $('inet-username').textContent = data.username;
+ $('inet-provider-type').textContent =
+ getManagedValue(data, 'VPN.Type', GetManagedTypes.TRANSLATED);
+ var providerType =
+ getManagedValue(data, 'VPN.Type', GetManagedTypes.ACTIVE);
+ var providerKey = 'VPN.' + providerType;
+ $('inet-username').textContent =
+ getManagedValue(data, providerKey + '.Username');
var inetServerHostname = $('inet-server-hostname');
- inetServerHostname.value = data.serverHostname.value;
+ inetServerHostname.value = getManagedValue(data, 'VPN.Host');
inetServerHostname.resetHandler = function() {
PageManager.hideBubble();
- inetServerHostname.value = data.serverHostname.recommendedValue;
+ var recommended =
+ getManagedValue(data, 'VPN.Host', GetManagedTypes.RECOMMENDED);
+ if (recommended != undefined)
+ inetServerHostname.value = recommended;
};
$('auto-connect-network-vpn').checked =
- getActiveValue(data, 'AutoConnect');
+ getManagedValue(data, 'AutoConnect');
$('auto-connect-network-vpn').disabled = false;
} else {
OptionsPage.showTab($('internet-nav-tab'));
@@ -1356,16 +1409,20 @@ cr.define('options.internet', function() {
var indicators = cr.doc.querySelectorAll(
'#details-internet-page .controlled-setting-indicator');
for (var i = 0; i < indicators.length; i++) {
- var attributeName =
- indicators[i].hasAttribute('managed') ? 'managed' : 'data';
+ var managed = indicators[i].hasAttribute('managed');
+ var attributeName = managed ? 'managed' : 'data';
var propName = indicators[i].getAttribute(attributeName);
- if (!propName || !data[propName])
+ if (!propName)
+ continue;
+ var propValue =
+ managed ? getManagedProperty(data, propName) : data[propName];
+ if (propValue == undefined)
continue;
var event;
- if (attributeName == 'managed')
- event = detailsPage.createManagedEvent_(propName, data[propName]);
+ if (managed)
+ event = detailsPage.createManagedEvent_(propName, propValue);
else
- event = detailsPage.createControlledEvent_(propName, data[propName]);
+ event = detailsPage.createControlledEvent_(propName, propValue);
indicators[i].handlePrefChange(event);
var forElement = $(indicators[i].getAttribute('for'));
if (forElement) {
diff --git a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
index c4c8e95..f49f63e 100644
--- a/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/internet_options_handler.cc
@@ -43,6 +43,7 @@
#include "chromeos/network/network_state_handler.h"
#include "chromeos/network/network_util.h"
#include "chromeos/network/onc/onc_signature.h"
+#include "chromeos/network/onc/onc_translation_tables.h"
#include "chromeos/network/onc/onc_translator.h"
#include "chromeos/network/onc/onc_utils.h"
#include "components/onc/onc_constants.h"
@@ -62,6 +63,10 @@ namespace options {
namespace {
+// The key in a Managed Value dictionary for translated values.
+// TODO(stevenjb): Consider making this part of the ONC spec.
+const char kTranslatedKey[] = "Translated";
+
// Keys for the network description dictionary passed to the web ui. Make sure
// to keep the strings in sync with what the JavaScript side uses.
const char kNetworkInfoKeyIconURL[] = "iconURL";
@@ -149,8 +154,6 @@ const char kTagNetworkId[] = "networkId";
const char kTagOptions[] = "options";
const char kTagPassword[] = "password";
const char kTagPolicy[] = "policy";
-const char kTagPreferred[] = "preferred";
-const char kTagProviderType[] = "providerType";
const char kTagProviderApnList[] = "providerApnList";
const char kTagRecommended[] = "recommended";
const char kTagRecommendedValue[] = "recommendedValue";
@@ -158,7 +161,6 @@ const char kTagRemembered[] = "remembered";
const char kTagRememberedList[] = "rememberedList";
const char kTagRestrictedPool[] = "restrictedPool";
const char kTagRoamingState[] = "roamingState";
-const char kTagServerHostname[] = "serverHostname";
const char kTagCarriers[] = "carriers";
const char kTagCurrentCarrierIndex[] = "currentCarrierIndex";
const char kTagShared[] = "shared";
@@ -334,20 +336,20 @@ const char* GetOncSettingString(::onc::ONCSource onc_source) {
// Creates a GetManagedProperties style dictionary and adds it to |settings|.
// |default_value| represents either the recommended value if |recommended|
-// is true, or the enforced value if |recommended| is false.
+// is true, or the enforced value if |recommended| is false. |settings_dict_key|
+// is expected to be an ONC key with no '.' in it.
// Note(stevenjb): This is bridge code until we use GetManagedProperties to
// retrieve Shill properties.
-void SetManagedValueDictionary(const char* key,
- const base::Value* value,
- ::onc::ONCSource onc_source,
- bool recommended,
- const base::Value* default_value,
- base::DictionaryValue* settings) {
+void SetManagedValueDictionaryEx(const char* settings_dict_key,
+ const base::Value& value,
+ ::onc::ONCSource onc_source,
+ bool recommended,
+ const base::Value* default_value,
+ base::DictionaryValue* settings_dict) {
base::DictionaryValue* dict = new base::DictionaryValue();
- settings->Set(key, dict);
+ settings_dict->SetWithoutPathExpansion(settings_dict_key, dict);
- DCHECK(value);
- dict->Set(::onc::kAugmentationActiveSetting, value->DeepCopy());
+ dict->Set(::onc::kAugmentationActiveSetting, value.DeepCopy());
if (onc_source == ::onc::ONC_SOURCE_NONE)
return;
@@ -360,9 +362,9 @@ void SetManagedValueDictionary(const char* key,
if (default_value) {
std::string policy_source = GetOncPolicyString(onc_source);
dict->Set(policy_source, default_value->DeepCopy());
- if (recommended && !value->Equals(default_value)) {
+ if (recommended && !value.Equals(default_value)) {
std::string setting_source = GetOncSettingString(onc_source);
- dict->Set(setting_source, value->DeepCopy());
+ dict->Set(setting_source, value.DeepCopy());
dict->SetString(::onc::kAugmentationEffectiveSetting, setting_source);
} else {
dict->SetString(::onc::kAugmentationEffectiveSetting, policy_source);
@@ -370,6 +372,48 @@ void SetManagedValueDictionary(const char* key,
}
}
+// Wrapper for SetManagedValueDictionaryEx that does the policy lookup.
+// Note: We have to pass |onc_key| separately from |settings_dict_key| since
+// we might be populating a sub-dictionary in which case |onc_key| will be the
+// complete path (e.g. 'VPN.Host') and |settings_dict_key| is the dictionary key
+// (e.g. 'Host').
+void SetManagedValueDictionary(const std::string& guid,
+ const char* settings_dict_key,
+ const base::Value& value,
+ const std::string& onc_key,
+ base::DictionaryValue* settings_dict) {
+ ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE;
+ const base::DictionaryValue* onc =
+ onc::FindPolicyForActiveUser(guid, &onc_source);
+ DCHECK_EQ(onc == NULL, onc_source == ::onc::ONC_SOURCE_NONE);
+ const base::Value* default_value = NULL;
+ bool recommended = false;
+ if (onc) {
+ onc->Get(onc_key, &default_value);
+ recommended = onc::IsRecommendedValue(onc, onc_key);
+ }
+ SetManagedValueDictionaryEx(settings_dict_key,
+ value,
+ onc_source,
+ recommended,
+ default_value,
+ settings_dict);
+}
+
+// Creates a GetManagedProperties style dictionary with an Active value and
+// a Translated value, and adds it to |settings|.
+// Note(stevenjb): This is bridge code until we use GetManagedProperties to
+// retrieve Shill properties and include Translated values.
+void SetTranslatedDictionary(const char* settings_dict_key,
+ const std::string& value,
+ const std::string& translated_value,
+ base::DictionaryValue* settings_dict) {
+ base::DictionaryValue* dict = new base::DictionaryValue();
+ settings_dict->Set(settings_dict_key, dict);
+ dict->SetString(::onc::kAugmentationActiveSetting, value);
+ dict->SetString(kTranslatedKey, translated_value);
+}
+
std::string CopyStringFromDictionary(const base::DictionaryValue& source,
const std::string& src_key,
const std::string& dest_key,
@@ -387,46 +431,55 @@ void PopulateVPNDetails(const NetworkState* vpn,
base::DictionaryValue* dictionary) {
// Name and Remembered are set in PopulateConnectionDetails().
// Provider properties are stored in the "Provider" dictionary.
- const base::DictionaryValue* provider_properties = NULL;
+ const base::DictionaryValue* shill_provider_properties = NULL;
if (!shill_properties.GetDictionaryWithoutPathExpansion(
- shill::kProviderProperty, &provider_properties)) {
+ shill::kProviderProperty, &shill_provider_properties)) {
LOG(ERROR) << "No provider properties for VPN: " << vpn->path();
return;
}
- std::string provider_type;
- provider_properties->GetStringWithoutPathExpansion(
- shill::kTypeProperty, &provider_type);
- dictionary->SetString(kTagProviderType,
- internet_options_strings::ProviderTypeString(
- provider_type,
- *provider_properties));
+ base::DictionaryValue* vpn_dictionary = new base::DictionaryValue;
+ dictionary->Set(::onc::network_config::kVPN, vpn_dictionary);
+ std::string shill_provider_type;
+ if (!shill_provider_properties->GetStringWithoutPathExpansion(
+ shill::kTypeProperty, &shill_provider_type)) {
+ LOG(ERROR) << "Shill VPN has no Provider.Type: " << vpn->path();
+ return;
+ }
+ std::string onc_provider_type;
+ onc::TranslateStringToONC(
+ onc::kVPNTypeTable, shill_provider_type, &onc_provider_type);
+ SetTranslatedDictionary(
+ ::onc::vpn::kType,
+ onc_provider_type,
+ internet_options_strings::ProviderTypeString(shill_provider_type,
+ *shill_provider_properties),
+ vpn_dictionary);
+
+ std::string provider_type_key;
std::string username;
- if (provider_type == shill::kProviderOpenVpn) {
- provider_properties->GetStringWithoutPathExpansion(
+ if (shill_provider_type == shill::kProviderOpenVpn) {
+ provider_type_key = ::onc::vpn::kOpenVPN;
+ shill_provider_properties->GetStringWithoutPathExpansion(
shill::kOpenVPNUserProperty, &username);
} else {
- provider_properties->GetStringWithoutPathExpansion(
+ provider_type_key = ::onc::vpn::kL2TP;
+ shill_provider_properties->GetStringWithoutPathExpansion(
shill::kL2tpIpsecUserProperty, &username);
}
- dictionary->SetString(kTagUsername, username);
+ base::DictionaryValue* provider_type_dictionary = new base::DictionaryValue;
+ vpn_dictionary->Set(provider_type_key, provider_type_dictionary);
+ provider_type_dictionary->SetString(::onc::vpn::kUsername, username);
- ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE;
- const base::DictionaryValue* onc =
- onc::FindPolicyForActiveUser(vpn->guid(), &onc_source);
-
- NetworkPropertyUIData hostname_ui_data;
- hostname_ui_data.ParseOncProperty(
- onc_source,
- onc,
- ::onc::network_config::VpnProperty(::onc::vpn::kHost));
std::string provider_host;
- provider_properties->GetStringWithoutPathExpansion(
+ shill_provider_properties->GetStringWithoutPathExpansion(
shill::kHostProperty, &provider_host);
- SetValueDictionary(kTagServerHostname,
- new base::StringValue(provider_host),
- hostname_ui_data,
- dictionary);
+ SetManagedValueDictionary(
+ vpn->guid(),
+ ::onc::vpn::kHost,
+ base::StringValue(provider_host),
+ ::onc::network_config::VpnProperty(::onc::vpn::kHost),
+ vpn_dictionary);
}
// Given a list of supported carrier's by the device, return the index of
@@ -1332,11 +1385,11 @@ void InternetOptionsHandler::PopulateDictionaryDetailsCallback(
int priority = 0;
shill_properties.GetIntegerWithoutPathExpansion(
shill::kPriorityProperty, &priority);
- bool preferred = priority > 0;
- SetValueDictionary(kTagPreferred,
- new base::FundamentalValue(preferred),
- property_ui_data,
- dictionary.get());
+ SetManagedValueDictionary(network->guid(),
+ ::onc::network_config::kPriority,
+ base::FundamentalValue(priority),
+ ::onc::network_config::kPriority,
+ dictionary.get());
std::string onc_path_to_auto_connect;
if (network->Matches(NetworkTypePattern::WiFi())) {
@@ -1371,8 +1424,7 @@ void InternetOptionsHandler::PopulateDictionaryDetailsCallback(
shill_properties.GetBooleanWithoutPathExpansion(
shill::kAutoConnectProperty, &auto_connect);
- scoped_ptr<base::Value> auto_connect_value(
- new base::FundamentalValue(auto_connect));
+ base::FundamentalValue auto_connect_value(auto_connect);
::onc::ONCSource auto_connect_onc_source = onc_source;
DCHECK_EQ(onc == NULL, onc_source == ::onc::ONC_SOURCE_NONE);
@@ -1397,15 +1449,15 @@ void InternetOptionsHandler::PopulateDictionaryDetailsCallback(
: ::onc::ONC_SOURCE_DEVICE_POLICY;
if (auto_connect) {
LOG(WARNING) << "Policy prevents autoconnect, but value is True.";
- auto_connect_value.reset(new base::FundamentalValue(false));
+ auto_connect_value = base::FundamentalValue(false);
}
}
- SetManagedValueDictionary(shill::kAutoConnectProperty,
- auto_connect_value.get(),
- auto_connect_onc_source,
- auto_connect_recommended,
- auto_connect_default_value,
- dictionary.get());
+ SetManagedValueDictionaryEx(shill::kAutoConnectProperty,
+ auto_connect_value,
+ auto_connect_onc_source,
+ auto_connect_recommended,
+ auto_connect_default_value,
+ dictionary.get());
}
// Show details dialog
diff --git a/chromeos/network/onc/onc_signature.cc b/chromeos/network/onc/onc_signature.cc
index 4e1bdeb..2b750fb 100644
--- a/chromeos/network/onc/onc_signature.cc
+++ b/chromeos/network/onc/onc_signature.cc
@@ -290,6 +290,7 @@ const OncFieldSignature network_configuration_fields[] = {
{ ::onc::network_config::kName, &kStringSignature},
// Not supported, yet.
{ ::onc::network_config::kNameServers, &kStringListSignature},
+ { ::onc::network_config::kPriority, &kIntegerSignature},
{ ::onc::network_config::kProxySettings, &kProxySettingsSignature},
{ ::onc::kRemove, &kBoolSignature},
// Not supported, yet.
diff --git a/chromeos/network/onc/onc_translation_tables.cc b/chromeos/network/onc/onc_translation_tables.cc
index 119b62b..3cf512c 100644
--- a/chromeos/network/onc/onc_translation_tables.cc
+++ b/chromeos/network/onc/onc_translation_tables.cc
@@ -43,7 +43,8 @@ const FieldTranslationEntry ipsec_fields[] = {
// Ignored by Shill, not necessary to synchronize.
// { ::onc::ipsec::kIKEVersion, shill::kL2tpIpsecIkeVersion },
{ ::onc::ipsec::kPSK, shill::kL2tpIpsecPskProperty},
- { ::onc::vpn::kSaveCredentials, shill::kSaveCredentialsProperty},
+ // This field is converted during translation, see onc_translator_*.
+ // { ::onc::vpn::kSaveCredentials, shill::kSaveCredentialsProperty},
{ ::onc::ipsec::kServerCAPEMs, shill::kL2tpIpsecCaCertPemProperty},
{NULL}};
@@ -55,8 +56,7 @@ const FieldTranslationEntry xauth_fields[] = {
const FieldTranslationEntry l2tp_fields[] = {
{ ::onc::vpn::kPassword, shill::kL2tpIpsecPasswordProperty},
// We don't synchronize l2tp's SaveCredentials field for now, as Shill
- // doesn't
- // support separate settings for ipsec and l2tp.
+ // doesn't support separate settings for ipsec and l2tp.
// { ::onc::vpn::kSaveCredentials, &kBoolSignature },
{ ::onc::vpn::kUsername, shill::kL2tpIpsecUserProperty}, {NULL}};
@@ -80,7 +80,8 @@ const FieldTranslationEntry openvpn_fields[] = {
// { ::onc::openvpn::kRemoteCertKU, shill::kOpenVPNRemoteCertKUProperty },
{ ::onc::openvpn::kRemoteCertTLS, shill::kOpenVPNRemoteCertTLSProperty},
{ ::onc::openvpn::kRenegSec, shill::kOpenVPNRenegSecProperty},
- { ::onc::vpn::kSaveCredentials, shill::kSaveCredentialsProperty},
+ // This field is converted during translation, see onc_translator_*.
+ // { ::onc::vpn::kSaveCredentials, shill::kSaveCredentialsProperty},
{ ::onc::openvpn::kServerCAPEMs, shill::kOpenVPNCaCertPemProperty},
{ ::onc::openvpn::kServerPollTimeout,
shill::kOpenVPNServerPollTimeoutProperty},
@@ -99,8 +100,8 @@ const FieldTranslationEntry verify_x509_fields[] = {
const FieldTranslationEntry vpn_fields[] = {
{ ::onc::vpn::kAutoConnect, shill::kAutoConnectProperty},
- { ::onc::vpn::kHost, shill::kProviderHostProperty},
- // This field is converted during translation, see onc_translator_*.
+ // These fields are converted during translation, see onc_translator_*.
+ // { ::onc::vpn::kHost, shill::kProviderHostProperty},
// { ::onc::vpn::kType, shill::kProviderTypeProperty },
{NULL}};
@@ -159,6 +160,7 @@ const FieldTranslationEntry network_fields[] = {
{ ::onc::network_config::kGUID, shill::kGuidProperty},
{ ::onc::network_config::kConnectable, shill::kConnectableProperty },
{ ::onc::network_config::kErrorState, shill::kErrorProperty },
+ { ::onc::network_config::kPriority, shill::kPriorityProperty },
// Shill doesn't allow setting the name for non-VPN networks.
// Name is conditionally translated, see onc_translator_*.
diff --git a/chromeos/network/onc/onc_translation_tables.h b/chromeos/network/onc/onc_translation_tables.h
index 4563b66..1053f37 100644
--- a/chromeos/network/onc/onc_translation_tables.h
+++ b/chromeos/network/onc/onc_translation_tables.h
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "chromeos/chromeos_export.h"
#include "chromeos/network/onc/onc_signature.h"
namespace chromeos {
@@ -25,12 +26,12 @@ struct StringTranslationEntry {
// These tables contain the mapping from ONC strings to Shill strings.
// These are NULL-terminated arrays.
-extern const StringTranslationEntry kNetworkTypeTable[];
-extern const StringTranslationEntry kVPNTypeTable[];
-extern const StringTranslationEntry kWiFiSecurityTable[];
-extern const StringTranslationEntry kEAPOuterTable[];
-extern const StringTranslationEntry kEAP_PEAP_InnerTable[];
-extern const StringTranslationEntry kEAP_TTLS_InnerTable[];
+CHROMEOS_EXPORT extern const StringTranslationEntry kNetworkTypeTable[];
+CHROMEOS_EXPORT extern const StringTranslationEntry kVPNTypeTable[];
+CHROMEOS_EXPORT extern const StringTranslationEntry kWiFiSecurityTable[];
+CHROMEOS_EXPORT extern const StringTranslationEntry kEAPOuterTable[];
+CHROMEOS_EXPORT extern const StringTranslationEntry kEAP_PEAP_InnerTable[];
+CHROMEOS_EXPORT extern const StringTranslationEntry kEAP_TTLS_InnerTable[];
// A separate translation table for cellular properties that are stored in a
// Shill Device instead of a Service. The |shill_property_name| entries
@@ -48,14 +49,15 @@ bool GetShillPropertyName(const std::string& onc_field_name,
std::string* shill_property_name);
// Translate individual strings to Shill using the above tables.
-bool TranslateStringToShill(const StringTranslationEntry table[],
- const std::string& onc_value,
- std::string* shill_value);
+CHROMEOS_EXPORT bool TranslateStringToShill(
+ const StringTranslationEntry table[],
+ const std::string& onc_value,
+ std::string* shill_value);
// Translate individual strings to ONC using the above tables.
-bool TranslateStringToONC(const StringTranslationEntry table[],
- const std::string& shill_value,
- std::string* onc_value);
+CHROMEOS_EXPORT bool TranslateStringToONC(const StringTranslationEntry table[],
+ const std::string& shill_value,
+ std::string* onc_value);
} // namespace onc
} // namespace chromeos
diff --git a/chromeos/network/onc/onc_translator_onc_to_shill.cc b/chromeos/network/onc/onc_translator_onc_to_shill.cc
index 2fd411f..e7e7782 100644
--- a/chromeos/network/onc/onc_translator_onc_to_shill.cc
+++ b/chromeos/network/onc/onc_translator_onc_to_shill.cc
@@ -55,6 +55,7 @@ class LocalTranslator {
private:
void TranslateEthernet();
void TranslateOpenVPN();
+ void TranslateIPsec();
void TranslateVPN();
void TranslateWiFi();
void TranslateEAP();
@@ -94,6 +95,8 @@ void LocalTranslator::TranslateFields() {
TranslateVPN();
else if (onc_signature_ == &kOpenVPNSignature)
TranslateOpenVPN();
+ else if (onc_signature_ == &kIPsecSignature)
+ TranslateIPsec();
else if (onc_signature_ == &kWiFiSignature)
TranslateWiFi();
else if (onc_signature_ == &kEAPSignature)
@@ -117,6 +120,14 @@ void LocalTranslator::TranslateEthernet() {
}
void LocalTranslator::TranslateOpenVPN() {
+ // SaveCredentials needs special handling when translating from Shill -> ONC
+ // so handle it explicitly here.
+ bool save_credentials;
+ if (onc_object_->GetBooleanWithoutPathExpansion(
+ ::onc::vpn::kSaveCredentials, &save_credentials)) {
+ shill_dictionary_->SetBooleanWithoutPathExpansion(
+ shill::kSaveCredentialsProperty, save_credentials);
+ }
// Shill supports only one RemoteCertKU but ONC a list.
// Copy only the first entry if existing.
const base::ListValue* certKUs = NULL;
@@ -131,8 +142,7 @@ void LocalTranslator::TranslateOpenVPN() {
for (base::DictionaryValue::Iterator it(*onc_object_); !it.IsAtEnd();
it.Advance()) {
scoped_ptr<base::Value> translated;
- if (it.key() == ::onc::vpn::kSaveCredentials ||
- it.key() == ::onc::openvpn::kRemoteCertKU ||
+ if (it.key() == ::onc::openvpn::kRemoteCertKU ||
it.key() == ::onc::openvpn::kServerCAPEMs) {
translated.reset(it.value().DeepCopy());
} else {
@@ -143,7 +153,25 @@ void LocalTranslator::TranslateOpenVPN() {
}
}
+void LocalTranslator::TranslateIPsec() {
+ CopyFieldsAccordingToSignature();
+
+ // SaveCredentials needs special handling when translating from Shill -> ONC
+ // so handle it explicitly here.
+ bool save_credentials;
+ if (onc_object_->GetBooleanWithoutPathExpansion(
+ ::onc::vpn::kSaveCredentials, &save_credentials)) {
+ shill_dictionary_->SetBooleanWithoutPathExpansion(
+ shill::kSaveCredentialsProperty, save_credentials);
+ }
+}
+
void LocalTranslator::TranslateVPN() {
+ std::string host;
+ if (onc_object_->GetStringWithoutPathExpansion(::onc::vpn::kHost, &host)) {
+ shill_dictionary_->SetStringWithoutPathExpansion(
+ shill::kProviderHostProperty, host);
+ }
std::string type;
onc_object_->GetStringWithoutPathExpansion(::onc::vpn::kType, &type);
TranslateWithTableAndSet(type, kVPNTypeTable, shill::kProviderTypeProperty);
diff --git a/chromeos/network/onc/onc_translator_shill_to_onc.cc b/chromeos/network/onc/onc_translator_shill_to_onc.cc
index 19e7eff..224e26c 100644
--- a/chromeos/network/onc/onc_translator_shill_to_onc.cc
+++ b/chromeos/network/onc/onc_translator_shill_to_onc.cc
@@ -89,6 +89,12 @@ class ShillToONCTranslator {
// |onc_field_name|.
void TranslateAndAddNestedObject(const std::string& onc_field_name);
+ // Sets |onc_field_name| in dictionary |onc_dictionary_name| in |onc_object_|
+ // to |value| if the dictionary exists.
+ void SetNestedOncValue(const std::string& onc_dictionary_name,
+ const std::string& onc_field_name,
+ const base::Value& value);
+
// Translates a list of nested objects and adds the list to |onc_object_| at
// |onc_field_name|. If there are errors while parsing individual objects or
// if the resulting list contains no entries, the result will not be added to
@@ -117,6 +123,10 @@ class ShillToONCTranslator {
const StringTranslationEntry table[],
const std::string& onc_field_name);
+ // Returns the name of the Shill service provided in |shill_dictionary_|
+ // for debugging.
+ std::string GetName();
+
const base::DictionaryValue* shill_dictionary_;
const OncValueSignature* onc_signature_;
const FieldTranslationEntry* field_translation_table_;
@@ -182,8 +192,7 @@ void ShillToONCTranslator::TranslateOpenVPN() {
for (const OncFieldSignature* field_signature = onc_signature_->fields;
field_signature->onc_field_name != NULL; ++field_signature) {
const std::string& onc_field_name = field_signature->onc_field_name;
- if (onc_field_name == ::onc::vpn::kSaveCredentials ||
- onc_field_name == ::onc::openvpn::kRemoteCertKU ||
+ if (onc_field_name == ::onc::openvpn::kRemoteCertKU ||
onc_field_name == ::onc::openvpn::kServerCAPEMs) {
CopyProperty(field_signature);
continue;
@@ -213,7 +222,8 @@ void ShillToONCTranslator::TranslateOpenVPN() {
LOG(ERROR) << "Shill property '" << shill_property_name
<< "' with value " << *shill_value
<< " couldn't be converted to base::Value::Type "
- << field_signature->value_signature->onc_type;
+ << field_signature->value_signature->onc_type
+ << ": " << GetName();
} else {
onc_object_->SetWithoutPathExpansion(onc_field_name,
translated.release());
@@ -221,7 +231,7 @@ void ShillToONCTranslator::TranslateOpenVPN() {
} else {
LOG(ERROR) << "Shill property '" << shill_property_name
<< "' has value " << *shill_value
- << ", but expected a string";
+ << ", but expected a string: " << GetName();
}
}
}
@@ -233,19 +243,48 @@ void ShillToONCTranslator::TranslateIPsec() {
}
void ShillToONCTranslator::TranslateVPN() {
- TranslateWithTableAndSet(
- shill::kProviderTypeProperty, kVPNTypeTable, ::onc::vpn::kType);
CopyPropertiesAccordingToSignature();
- std::string vpn_type;
- if (onc_object_->GetStringWithoutPathExpansion(::onc::vpn::kType,
- &vpn_type)) {
- if (vpn_type == ::onc::vpn::kTypeL2TP_IPsec) {
- TranslateAndAddNestedObject(::onc::vpn::kIPsec);
- TranslateAndAddNestedObject(::onc::vpn::kL2TP);
- } else {
- TranslateAndAddNestedObject(vpn_type);
- }
+ // Parse Shill Provider dictionary. Note, this may not exist, e.g. if we are
+ // just translating network state in network_util::TranslateNetworkStateToONC.
+ const base::DictionaryValue* provider = NULL;
+ if (!shill_dictionary_->GetDictionaryWithoutPathExpansion(
+ shill::kProviderProperty, &provider)) {
+ return;
+ }
+ std::string shill_provider_type, onc_provider_type;
+ provider->GetStringWithoutPathExpansion(shill::kTypeProperty,
+ &shill_provider_type);
+ if (!TranslateStringToONC(
+ kVPNTypeTable, shill_provider_type, &onc_provider_type)) {
+ return;
+ }
+ onc_object_->SetStringWithoutPathExpansion(::onc::vpn::kType,
+ onc_provider_type);
+ std::string provider_host;
+ if (provider->GetStringWithoutPathExpansion(shill::kHostProperty,
+ &provider_host)) {
+ onc_object_->SetStringWithoutPathExpansion(::onc::vpn::kHost,
+ provider_host);
+ }
+
+ // Translate the nested dictionary.
+ std::string provider_type_dictionary;
+ if (onc_provider_type == ::onc::vpn::kTypeL2TP_IPsec) {
+ TranslateAndAddNestedObject(::onc::vpn::kIPsec, *provider);
+ TranslateAndAddNestedObject(::onc::vpn::kL2TP, *provider);
+ provider_type_dictionary = ::onc::vpn::kIPsec;
+ } else {
+ TranslateAndAddNestedObject(onc_provider_type, *provider);
+ provider_type_dictionary = onc_provider_type;
+ }
+
+ bool save_credentials;
+ if (shill_dictionary_->GetBooleanWithoutPathExpansion(
+ shill::kSaveCredentialsProperty, &save_credentials)) {
+ SetNestedOncValue(provider_type_dictionary,
+ ::onc::vpn::kSaveCredentials,
+ base::FundamentalValue(save_credentials));
}
}
@@ -411,6 +450,19 @@ void ShillToONCTranslator::TranslateAndAddNestedObject(
onc_object_->SetWithoutPathExpansion(onc_field_name, nested_object.release());
}
+void ShillToONCTranslator::SetNestedOncValue(
+ const std::string& onc_dictionary_name,
+ const std::string& onc_field_name,
+ const base::Value& value) {
+ base::DictionaryValue* nested;
+ if (!onc_object_->GetDictionaryWithoutPathExpansion(
+ onc_dictionary_name, &nested)) {
+ nested = new base::DictionaryValue;
+ onc_object_->SetWithoutPathExpansion(onc_dictionary_name, nested);
+ }
+ nested->SetWithoutPathExpansion(onc_field_name, value.DeepCopy());
+}
+
void ShillToONCTranslator::TranslateAndAddListOfObjects(
const std::string& onc_field_name,
const base::ListValue& list) {
@@ -419,7 +471,7 @@ void ShillToONCTranslator::TranslateAndAddListOfObjects(
if (field_signature->value_signature->onc_type != base::Value::TYPE_LIST) {
LOG(ERROR) << "ONC Field name: '" << onc_field_name << "' has type '"
<< field_signature->value_signature->onc_type
- << "', expected: base::Value::TYPE_LIST.";
+ << "', expected: base::Value::TYPE_LIST: " << GetName();
return;
}
DCHECK(field_signature->value_signature->onc_array_entry_signature);
@@ -478,7 +530,8 @@ void ShillToONCTranslator::CopyProperty(
<< " has base::Value::Type " << shill_value->GetType()
<< " but ONC field '" << field_signature->onc_field_name
<< "' requires type "
- << field_signature->value_signature->onc_type << ".";
+ << field_signature->value_signature->onc_type
+ << ": " << GetName();
return;
}
@@ -501,7 +554,14 @@ void ShillToONCTranslator::TranslateWithTableAndSet(
return;
}
LOG(ERROR) << "Shill property '" << shill_property_name << "' with value "
- << shill_value << " couldn't be translated to ONC";
+ << shill_value << " couldn't be translated to ONC: " << GetName();
+}
+
+std::string ShillToONCTranslator::GetName() {
+ DCHECK(shill_dictionary_);
+ std::string name;
+ shill_dictionary_->GetStringWithoutPathExpansion(shill::kNameProperty, &name);
+ return name;
}
} // namespace
diff --git a/chromeos/network/onc/onc_translator_unittest.cc b/chromeos/network/onc/onc_translator_unittest.cc
index 29a77b9..bce14cb 100644
--- a/chromeos/network/onc/onc_translator_unittest.cc
+++ b/chromeos/network/onc/onc_translator_unittest.cc
@@ -98,11 +98,11 @@ INSTANTIATE_TEST_CASE_P(
"translation_of_shill_wifi_clientcert.onc"),
std::make_pair("shill_wifi_wpa1.json",
"translation_of_shill_wifi_wpa1.onc"),
- std::make_pair("shill_l2tpipsec.json",
+ std::make_pair("shill_output_l2tpipsec.json",
"translation_of_shill_l2tpipsec.onc"),
- std::make_pair("shill_openvpn.json",
+ std::make_pair("shill_output_openvpn.json",
"translation_of_shill_openvpn.onc"),
- std::make_pair("shill_openvpn_with_errors.json",
+ std::make_pair("shill_output_openvpn_with_errors.json",
"translation_of_shill_openvpn_with_errors.onc"),
std::make_pair("shill_wifi_with_state.json",
"translation_of_shill_wifi_with_state.onc"),
diff --git a/chromeos/test/data/network/shill_openvpn_with_errors.json b/chromeos/test/data/network/shill_openvpn_with_errors.json
deleted file mode 100644
index 9ac9d53..0000000
--- a/chromeos/test/data/network/shill_openvpn_with_errors.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- // Missing GUID.
- "Type": "vpn",
- "Name": "my vpn",
- // String instead of Int.
- "SaveCredentials": "false",
- "Provider.Type": "openvpn",
- "Provider.Host": "vpn.my.domain.com",
- "OpenVPN.AuthRetry": "interact",
- "OpenVPN.User": "abc ${LOGIN_EMAIL} def",
- "OpenVPN.Password": "some password",
- "OpenVPN.StaticChallenge": "Please enter token OTP",
- "OpenVPN.CompLZO": "true",
- // Int instead of String.
- "OpenVPN.ServerPollTimeout": 10,
- "OpenVPN.RemoteCertKU": "e0",
- "OpenVPN.RemoteCertTLS": "server",
- "OpenVPN.Port": "443",
- "OpenVPN.TLSRemote": "my.domain.com",
- "OpenVPN.KeyDirection": "1",
- "OpenVPN.RenegSec": "0",
- "OpenVPN.RemoteCertEKU": "TLS Web Server Authentication",
- "OpenVPN.Proto": "udp",
- "OpenVPN.PushPeerInfo": "true",
- "OpenVPN.TLSAuthContents": "-----BEGIN OpenVPN Static key V1-----\n83f8e7ccd99be189b4663e18615f9166\nd885cdea6c8accb0ebf5be304f0b8081\n5404f2a6574e029815d7a2fb65b83d0c\n676850714c6a56b23415a78e06aad6b1\n34900dd512049598382039e4816cb5ff\n1848532b71af47578c9b4a14b5bca49f\n99e0ae4dae2f4e5eadfea374aeb8fb1e\na6fdf02adc73ea778dfd43d64bf7bc75\n7779d629498f8c2fbfd32812bfdf6df7\n8cebafafef3e5496cb13202274f2768a\n1959bc53d67a70945c4c8c6f34b63327\nfb60dc84990ffec1243461e0b6310f61\ne90aee1f11fb6292d6f5fcd7cd508aab\n50d80f9963589c148cb4b933ec86128d\ned77d3fad6005b62f36369e2319f52bd\n09c6d2e52cce2362a05009dc29b6b39a\n-----END OpenVPN Static key V1-----\n"
-}
diff --git a/chromeos/test/data/network/shill_output_l2tpipsec.json b/chromeos/test/data/network/shill_output_l2tpipsec.json
new file mode 100644
index 0000000..4848ab4
--- /dev/null
+++ b/chromeos/test/data/network/shill_output_l2tpipsec.json
@@ -0,0 +1,14 @@
+{ "GUID": "guid",
+ "Type": "vpn",
+ "Name": "MyL2TPVPN",
+ "Provider": {
+ "Host": "some.host.org",
+ "L2TPIPsec.PSK": "some_preshared_key",
+ "L2TPIPsec.User": "some username",
+ "L2TPIPsec.XauthPassword": "some xauth password",
+ "L2TPIPsec.XauthUser": "some xauth username",
+ "L2TPIPsec.Password": "some password",
+ "Type": "l2tpipsec",
+ },
+ "SaveCredentials": true
+}
diff --git a/chromeos/test/data/network/shill_output_openvpn.json b/chromeos/test/data/network/shill_output_openvpn.json
new file mode 100644
index 0000000..692834c
--- /dev/null
+++ b/chromeos/test/data/network/shill_output_openvpn.json
@@ -0,0 +1,34 @@
+{
+ "AutoConnect":true,
+ "GUID":"{a3860e83-f03d-4cb1-bafa-b22c9e746950}",
+ "Name":"my vpn",
+ "Provider": {
+ "Host":"vpn.my.domain.com",
+ "OpenVPN.AuthRetry":"interact",
+ "OpenVPN.CACertPEM":[
+ "pem1",
+ "pem2"
+ ],
+ "OpenVPN.CompLZO":"true",
+ "OpenVPN.KeyDirection":"1",
+ "OpenVPN.Password":"some password",
+ "OpenVPN.Port":"443",
+ "OpenVPN.Proto":"udp",
+ "OpenVPN.PushPeerInfo":"true",
+ "OpenVPN.RemoteCertEKU":"TLS Web Server Authentication",
+ "OpenVPN.RemoteCertKU":"e0",
+ "OpenVPN.RemoteCertTLS":"server",
+ "OpenVPN.RenegSec":"0",
+ "OpenVPN.ServerPollTimeout":"10",
+ "OpenVPN.StaticChallenge":"Please enter token OTP",
+ "OpenVPN.TLSAuthContents":"-----BEGIN OpenVPN Static key V1-----\n83f8e7ccd99be189b4663e18615f9166\nd885cdea6c8accb0ebf5be304f0b8081\n5404f2a6574e029815d7a2fb65b83d0c\n676850714c6a56b23415a78e06aad6b1\n34900dd512049598382039e4816cb5ff\n1848532b71af47578c9b4a14b5bca49f\n99e0ae4dae2f4e5eadfea374aeb8fb1e\na6fdf02adc73ea778dfd43d64bf7bc75\n7779d629498f8c2fbfd32812bfdf6df7\n8cebafafef3e5496cb13202274f2768a\n1959bc53d67a70945c4c8c6f34b63327\nfb60dc84990ffec1243461e0b6310f61\ne90aee1f11fb6292d6f5fcd7cd508aab\n50d80f9963589c148cb4b933ec86128d\ned77d3fad6005b62f36369e2319f52bd\n09c6d2e52cce2362a05009dc29b6b39a\n-----END OpenVPN Static key V1-----\n",
+ "OpenVPN.TLSRemote":"my.domain.com",
+ "OpenVPN.User":"abc ${LOGIN_EMAIL} def",
+ "OpenVPN.VerifyHash":"some hash",
+ "OpenVPN.VerifyX509Name":"some x509 name",
+ "OpenVPN.VerifyX509Type":"name-prefix",
+ "Type":"openvpn",
+ },
+ "SaveCredentials":false,
+ "Type":"vpn"
+}
diff --git a/chromeos/test/data/network/shill_output_openvpn_with_errors.json b/chromeos/test/data/network/shill_output_openvpn_with_errors.json
new file mode 100644
index 0000000..3639283
--- /dev/null
+++ b/chromeos/test/data/network/shill_output_openvpn_with_errors.json
@@ -0,0 +1,28 @@
+{
+ // Missing GUID.
+ "Type": "vpn",
+ "Name": "my vpn",
+ // String instead of Boolean.
+ "SaveCredentials": "false!",
+ "Provider": {
+ "Host": "vpn.my.domain.com",
+ "OpenVPN.AuthRetry": "interact",
+ "OpenVPN.User": "abc ${LOGIN_EMAIL} def",
+ "OpenVPN.Password": "some password",
+ "OpenVPN.StaticChallenge": "Please enter token OTP",
+ "OpenVPN.CompLZO": "true",
+ // Int instead of String.
+ "OpenVPN.ServerPollTimeout": 10,
+ "OpenVPN.RemoteCertKU": "e0",
+ "OpenVPN.RemoteCertTLS": "server",
+ "OpenVPN.Port": "443",
+ "OpenVPN.TLSRemote": "my.domain.com",
+ "OpenVPN.KeyDirection": "1",
+ "OpenVPN.RenegSec": "0",
+ "OpenVPN.RemoteCertEKU": "TLS Web Server Authentication",
+ "OpenVPN.Proto": "udp",
+ "OpenVPN.PushPeerInfo": "true",
+ "OpenVPN.TLSAuthContents": "-----BEGIN OpenVPN Static key V1-----\n83f8e7ccd99be189b4663e18615f9166\nd885cdea6c8accb0ebf5be304f0b8081\n5404f2a6574e029815d7a2fb65b83d0c\n676850714c6a56b23415a78e06aad6b1\n34900dd512049598382039e4816cb5ff\n1848532b71af47578c9b4a14b5bca49f\n99e0ae4dae2f4e5eadfea374aeb8fb1e\na6fdf02adc73ea778dfd43d64bf7bc75\n7779d629498f8c2fbfd32812bfdf6df7\n8cebafafef3e5496cb13202274f2768a\n1959bc53d67a70945c4c8c6f34b63327\nfb60dc84990ffec1243461e0b6310f61\ne90aee1f11fb6292d6f5fcd7cd508aab\n50d80f9963589c148cb4b933ec86128d\ned77d3fad6005b62f36369e2319f52bd\n09c6d2e52cce2362a05009dc29b6b39a\n-----END OpenVPN Static key V1-----\n",
+ "Type": "openvpn"
+ }
+}
diff --git a/chromeos/test/data/network/shill_wifi_with_state.json b/chromeos/test/data/network/shill_wifi_with_state.json
index 865162b..8ae1dc5 100644
--- a/chromeos/test/data/network/shill_wifi_with_state.json
+++ b/chromeos/test/data/network/shill_wifi_with_state.json
@@ -1,9 +1,11 @@
{
"AutoConnect": true,
+ "Connectable": true,
"GUID": "{64c4f86b-cf6a-4e4a-8eff-456def}",
"Mode": "managed",
"Name": "OpenWrt",
"Passphrase": "some passphrase",
+ "Priority": 1,
"Security": "psk",
"State": "idle",
"Strength": 10,
diff --git a/chromeos/test/data/network/translation_of_shill_l2tpipsec.onc b/chromeos/test/data/network/translation_of_shill_l2tpipsec.onc
index 1e6d3da..271a7182 100644
--- a/chromeos/test/data/network/translation_of_shill_l2tpipsec.onc
+++ b/chromeos/test/data/network/translation_of_shill_l2tpipsec.onc
@@ -20,7 +20,7 @@
},
"L2TP": {
"Username": "some username",
- "Password": "some password"
- }
+ "Password": "some password",
+ },
}
}
diff --git a/chromeos/test/data/network/translation_of_shill_wifi_with_state.onc b/chromeos/test/data/network/translation_of_shill_wifi_with_state.onc
index c49bf16..d149a43 100644
--- a/chromeos/test/data/network/translation_of_shill_wifi_with_state.onc
+++ b/chromeos/test/data/network/translation_of_shill_wifi_with_state.onc
@@ -1,6 +1,8 @@
{
+ "Connectable": true,
"GUID": "{64c4f86b-cf6a-4e4a-8eff-456def}",
"Name": "OpenWrt",
+ "Priority": 1,
"Type": "WiFi",
"WiFi": {
"AutoConnect": true,
diff --git a/components/onc/docs/onc_spec.html b/components/onc/docs/onc_spec.html
index 4b72a3e..6822117 100644
--- a/components/onc/docs/onc_spec.html
+++ b/components/onc/docs/onc_spec.html
@@ -400,6 +400,17 @@
networks. The format is 00:11:22:AA:BB:CC.
</dd>
+ <dt class="field">Priority</dt>
+ <dd>
+ <span class="field_meta">
+ (optional)
+ <span class="type">integer</span>
+ </span>
+ Provides a suggested priority value for this network. May be used by the
+ system to determine which network to connect to when multiple configured
+ networks are available (or may be ignored).
+ </dd>
+
</dl>
<section>
diff --git a/components/onc/onc_constants.cc b/components/onc/onc_constants.cc
index 1c1dccda..4909aed 100644
--- a/components/onc/onc_constants.cc
+++ b/components/onc/onc_constants.cc
@@ -41,6 +41,7 @@ const char kIPConfigs[] = "IPConfigs";
const char kMacAddress[] = "MacAddress";
const char kName[] = "Name";
const char kNameServers[] = "NameServers";
+const char kPriority[] = "Priority";
const char kProxySettings[] = "ProxySettings";
const char kSearchDomains[] = "SearchDomains";
const char kConnectionState[] = "ConnectionState";
diff --git a/components/onc/onc_constants.h b/components/onc/onc_constants.h
index 5db4c92..371570c 100644
--- a/components/onc/onc_constants.h
+++ b/components/onc/onc_constants.h
@@ -65,6 +65,7 @@ ONC_EXPORT extern const char kIPConfigs[];
ONC_EXPORT extern const char kMacAddress[];
ONC_EXPORT extern const char kName[];
ONC_EXPORT extern const char kNameServers[];
+ONC_EXPORT extern const char kPriority[];
ONC_EXPORT extern const char kProxySettings[];
ONC_EXPORT extern const char kSearchDomains[];
ONC_EXPORT extern const char kConnectionState[];