Commit 6917d1f6 authored by stevenjb's avatar stevenjb Committed by Commit bot

MD Settings: Third party VPN support

BUG=643729
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:closure_compilation

Review-Url: https://codereview.chromium.org/2311473002
Cr-Commit-Position: refs/heads/master@{#419104}
parent fb139e4a
...@@ -930,6 +930,9 @@ ...@@ -930,6 +930,9 @@
<message name="IDS_SETTINGS_INTERNET_ADD_VPN" desc="Settings > Internet > Add VPN label."> <message name="IDS_SETTINGS_INTERNET_ADD_VPN" desc="Settings > Internet > Add VPN label.">
Add OpenVPN / L2TP... Add OpenVPN / L2TP...
</message> </message>
<message name="IDS_SETTINGS_INTERNET_ADD_THIRD_PARTY_VPN" desc="Settings > Internet > Add third party VPN label">
Add <ph name="PROVIDER_NAME">$1<ex>VPN Demo</ex></ph>...
</message>
<message name="IDS_SETTINGS_INTERNET_NETWORK_SECTION_ACCESS_POINT" desc="Settings > Internet > Network details: Access Point section label."> <message name="IDS_SETTINGS_INTERNET_NETWORK_SECTION_ACCESS_POINT" desc="Settings > Internet > Network details: Access Point section label.">
Access Point Access Point
</message> </message>
......
...@@ -10,7 +10,10 @@ ...@@ -10,7 +10,10 @@
'../settings_page/compiled_resources2.gyp:settings_animated_pages', '../settings_page/compiled_resources2.gyp:settings_animated_pages',
'<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types', '<(DEPTH)/ui/webui/resources/cr_elements/network/compiled_resources2.gyp:cr_onc_types',
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert',
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
'<(EXTERNS_GYP):chrome_send', '<(EXTERNS_GYP):chrome_send',
'<(EXTERNS_GYP):management',
'<(EXTERNS_GYP):networking_private',
'<(INTERFACES_GYP):networking_private_interface', '<(INTERFACES_GYP):networking_private_interface',
], ],
'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
......
...@@ -191,7 +191,8 @@ ...@@ -191,7 +191,8 @@
<!-- Advanced section --> <!-- Advanced section -->
<iron-collapse opened="[[advancedExpanded_]]"> <iron-collapse opened="[[advancedExpanded_]]">
<div class="layout vertical indented"> <div class="layout vertical indented">
<div class="settings-box single-column stretch"> <div class="settings-box single-column stretch"
hidden$="[[!hasAdvancedOrDeviceFields_(networkProperties)]]">
<!-- Advanced properties --> <!-- Advanced properties -->
<network-property-list <network-property-list
hidden$="[[!hasAdvancedFields_(networkProperties)]]" hidden$="[[!hasAdvancedFields_(networkProperties)]]"
......
...@@ -164,7 +164,7 @@ Polymer({ ...@@ -164,7 +164,7 @@ Polymer({
// Update the detail page title. // Update the detail page title.
this.parentNode.pageTitle = this.parentNode.pageTitle =
CrOnc.getNetworkName(this.networkProperties, this.i18n); CrOnc.getNetworkName(this.networkProperties, this);
}, },
/** @private */ /** @private */
...@@ -621,13 +621,16 @@ Polymer({ ...@@ -621,13 +621,16 @@ Polymer({
'RestrictedConnectivity', 'Cellular.ServingOperator.Name'); 'RestrictedConnectivity', 'Cellular.ServingOperator.Name');
} }
if (this.networkProperties.Type == CrOnc.Type.VPN) { if (this.networkProperties.Type == CrOnc.Type.VPN) {
fields.push('VPN.Host', 'VPN.Type'); let vpnType = CrOnc.getActiveValue(this.networkProperties.VPN.Type);
if (this.networkProperties.VPN.Type == 'OpenVPN') if (vpnType == 'ThirdPartyVPN') {
fields.push('VPN.OpenVPN.Username');
else if (this.networkProperties.VPN.Type == 'L2TP-IPsec')
fields.push('VPN.L2TP.Username');
else if (this.networkProperties.VPN.Type == 'ThirdPartyVPN')
fields.push('VPN.ThirdPartyVPN.ProviderName'); fields.push('VPN.ThirdPartyVPN.ProviderName');
} else {
fields.push('VPN.Host', 'VPN.Type');
if (vpnType == 'OpenVPN')
fields.push('VPN.OpenVPN.Username');
else if (vpnType == 'L2TP-IPsec')
fields.push('VPN.L2TP.Username');
}
} }
if (this.networkProperties.Type == CrOnc.Type.WI_FI) if (this.networkProperties.Type == CrOnc.Type.WI_FI)
fields.push('RestrictedConnectivity'); fields.push('RestrictedConnectivity');
...@@ -702,6 +705,14 @@ Polymer({ ...@@ -702,6 +705,14 @@ Polymer({
return this.hasVisibleFields_(this.getDeviceFields_()); return this.hasVisibleFields_(this.getDeviceFields_());
}, },
/**
* @return {boolean}
* @private
*/
hasAdvancedOrDeviceFields_: function() {
return this.hasAdvancedFields_() || this.hasDeviceFields_();
},
/** /**
* @return {boolean} True if the network section should be shown. * @return {boolean} True if the network section should be shown.
* @private * @private
......
<link rel="import" href="chrome://resources/cr_elements/icons.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html">
<link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html"> <link rel="import" href="chrome://resources/cr_elements/network/cr_onc_types.html">
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
<link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html"> <link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html">
...@@ -50,6 +51,14 @@ ...@@ -50,6 +51,14 @@
on-tap="onAddVPNTap_"> on-tap="onAddVPNTap_">
<div class="start add-no-icon">$i18n{internetAddVPN}</div> <div class="start add-no-icon">$i18n{internetAddVPN}</div>
</div> </div>
<template is="dom-repeat" items="[[thirdPartyVpnProviders_]]">
<div actionable class="settings-box continuation center"
on-tap="onAddThirdPartyVpnTap_" provider="[[item]]">
<div class="start add-no-icon">
[[getAddThirdParrtyVpnLabel_(item)]]
</div>
</div>
</template>
</template> </template>
</neon-animatable> </neon-animatable>
<template is="dom-if" route-path="/networkDetail" no-search> <template is="dom-if" route-path="/networkDetail" no-search>
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
Polymer({ Polymer({
is: 'settings-internet-page', is: 'settings-internet-page',
behaviors: [I18nBehavior],
properties: { properties: {
/** /**
* Interface for networkingPrivate calls. May be overriden by tests. * Interface for networkingPrivate calls. May be overriden by tests.
...@@ -34,6 +36,43 @@ Polymer({ ...@@ -34,6 +36,43 @@ Polymer({
type: Boolean, type: Boolean,
value: false, value: false,
}, },
/**
* List of third party VPN providers.
* @type {!Array<!chrome.networkingPrivate.ThirdPartyVPNProperties>}
* @private
*/
thirdPartyVpnProviders_: {
type: Array,
value: function() {
return [];
}
},
},
/** @override */
attached: function() {
chrome.management.onInstalled.addListener(
this.onExtensionAdded_.bind(this));
chrome.management.onEnabled.addListener(this.onExtensionAdded_.bind(this));
chrome.management.onUninstalled.addListener(
this.onExtensionRemoved_.bind(this));
chrome.management.onDisabled.addListener(
this.onExtensionDisabled_.bind(this));
chrome.management.getAll(this.onGetAllExtensions_.bind(this));
},
/** @override */
detached: function() {
chrome.management.onInstalled.removeListener(
this.onExtensionAdded_.bind(this));
chrome.management.onEnabled.removeListener(
this.onExtensionAdded_.bind(this));
chrome.management.onUninstalled.removeListener(
this.onExtensionRemoved_.bind(this));
chrome.management.onDisabled.removeListener(
this.onExtensionDisabled_.bind(this));
}, },
/** /**
...@@ -66,13 +105,101 @@ Polymer({ ...@@ -66,13 +105,101 @@ Polymer({
this.addConnectionExpanded_ = !this.addConnectionExpanded_; this.addConnectionExpanded_ = !this.addConnectionExpanded_;
}, },
/*** @private */ /** @private */
onAddWiFiTap_: function() { onAddWiFiTap_: function() {
chrome.send('addNetwork', [CrOnc.Type.WI_FI]); chrome.send('addNetwork', [CrOnc.Type.WI_FI]);
}, },
/*** @private */ /** @private */
onAddVPNTap_: function() { onAddVPNTap_: function() {
chrome.send('addNetwork', [CrOnc.Type.VPN]); chrome.send('addNetwork', [CrOnc.Type.VPN]);
}, },
/**
* @param {!{model:
* !{item: !chrome.networkingPrivate.ThirdPartyVPNProperties},
* }} event
* @private
*/
onAddThirdPartyVpnTap_: function(event) {
let provider = event.model.item;
chrome.send('addNetwork', [CrOnc.Type.VPN, provider.ExtensionID]);
},
/**
* chrome.management.getAll callback.
* @param {!Array<!chrome.management.ExtensionInfo>} extensions
* @private
*/
onGetAllExtensions_: function(extensions) {
let vpnProviders = [];
for (var extension of extensions)
this.addVpnProvider_(vpnProviders, extension);
this.thirdPartyVpnProviders_ = vpnProviders;
},
/**
* If |extension| is a third-party VPN provider, add it to |vpnProviders|.
* @param {!Array<!chrome.networkingPrivate.ThirdPartyVPNProperties>}
* vpnProviders
* @param {!chrome.management.ExtensionInfo} extension
* @private
*/
addVpnProvider_: function(vpnProviders, extension) {
if (!extension.enabled ||
extension.permissions.indexOf('vpnProvider') == -1) {
return;
}
if (vpnProviders.find(function(provider) {
return provider.ExtensionID == extension.id;
})) {
return;
}
var newProvider = {
ExtensionID: extension.id,
ProviderName: extension.name,
};
vpnProviders.push(newProvider);
},
/**
* chrome.management.onInstalled or onEnabled event.
* @param {!chrome.management.ExtensionInfo} extension
* @private
*/
onExtensionAdded_: function(extension) {
this.addVpnProvider_(this.thirdPartyVpnProviders_, extension);
},
/**
* chrome.management.onUninstalled event.
* @param {string} extensionId
* @private
*/
onExtensionRemoved_: function(extensionId) {
for (var i = 0; i < this.thirdPartyVpnProviders_.length; ++i) {
var provider = this.thirdPartyVpnProviders_[i];
if (provider.ExtensionID == extensionId) {
this.splice('thirdPartyVpnProviders_', i, 1);
break;
}
}
},
/**
* chrome.management.onDisabled event.
* @param {{id: string}} extension
* @private
*/
onExtensionDisabled_: function(extension) {
this.onExtensionRemoved_(extension.id);
},
/**
* @param {!chrome.networkingPrivate.ThirdPartyVPNProperties} provider
* @return {string}
*/
getAddThirdParrtyVpnLabel_: function(provider) {
return this.i18n('internetAddThirdPartyVPN', provider.ProviderName);
}
}); });
...@@ -670,6 +670,7 @@ void AddEasyUnlockStrings(content::WebUIDataSource* html_source) { ...@@ -670,6 +670,7 @@ void AddEasyUnlockStrings(content::WebUIDataSource* html_source) {
void AddInternetStrings(content::WebUIDataSource* html_source) { void AddInternetStrings(content::WebUIDataSource* html_source) {
LocalizedString localized_strings[] = { LocalizedString localized_strings[] = {
{"internetAddConnection", IDS_SETTINGS_INTERNET_ADD_CONNECTION}, {"internetAddConnection", IDS_SETTINGS_INTERNET_ADD_CONNECTION},
{"internetAddThirdPartyVPN", IDS_SETTINGS_INTERNET_ADD_THIRD_PARTY_VPN},
{"internetAddVPN", IDS_SETTINGS_INTERNET_ADD_VPN}, {"internetAddVPN", IDS_SETTINGS_INTERNET_ADD_VPN},
{"internetAddWiFi", IDS_SETTINGS_INTERNET_ADD_WIFI}, {"internetAddWiFi", IDS_SETTINGS_INTERNET_ADD_WIFI},
{"internetDetailPageTitle", IDS_SETTINGS_INTERNET_DETAIL}, {"internetDetailPageTitle", IDS_SETTINGS_INTERNET_DETAIL},
......
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
{ {
'target_name': 'cr_onc_types', 'target_name': 'cr_onc_types',
'dependencies': [ 'dependencies': [
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
'<(EXTERNS_GYP):networking_private', '<(EXTERNS_GYP):networking_private',
], ],
'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
......
...@@ -91,7 +91,7 @@ Polymer({ ...@@ -91,7 +91,7 @@ Polymer({
} }
let network = /** @type {!CrOnc.NetworkStateProperties} */ (this.item); let network = /** @type {!CrOnc.NetworkStateProperties} */ (this.item);
if (this.isListItem) if (this.isListItem)
return CrOnc.getNetworkName(network, this.i18n); return CrOnc.getNetworkName(network, this);
return this.i18n('OncType' + network.Type); return this.i18n('OncType' + network.Type);
}, },
...@@ -117,7 +117,7 @@ Polymer({ ...@@ -117,7 +117,7 @@ Polymer({
return this.i18n('networkListItemConnected'); return this.i18n('networkListItemConnected');
if (network.Name && network.ConnectionState) { if (network.Name && network.ConnectionState) {
return this.getConnectionStateText_( return this.getConnectionStateText_(
network.ConnectionState, CrOnc.getNetworkName(network, this.i18n)); network.ConnectionState, CrOnc.getNetworkName(network, this));
} }
return this.i18n('networkDisabled'); return this.i18n('networkDisabled');
}, },
......
...@@ -314,22 +314,22 @@ CrOnc.getAutoConnect = function(properties) { ...@@ -314,22 +314,22 @@ CrOnc.getAutoConnect = function(properties) {
/** /**
* @param {!CrOnc.NetworkProperties|!CrOnc.NetworkStateProperties|undefined} * @param {!CrOnc.NetworkProperties|!CrOnc.NetworkStateProperties|undefined}
* properties The ONC network properties or state properties. * properties The ONC network properties or state properties.
* @param {!Object<function(string, ...string):string>} i18n * @param {!I18nBehavior.Proto} i18nBehavior An I18nBehavior instance.
* @return {string} The name to display for |network|. * @return {string} The name to display for |network|.
*/ */
CrOnc.getNetworkName = function(properties, i18n) { CrOnc.getNetworkName = function(properties, i18nBehavior) {
if (!properties) if (!properties)
return ''; return '';
let name = CrOnc.getStateOrActiveString(properties.Name); let name = CrOnc.getStateOrActiveString(properties.Name);
let type = CrOnc.getStateOrActiveString(properties.Type); let type = CrOnc.getStateOrActiveString(properties.Type);
if (!name) if (!name)
return i18n.call('OncType' + type); return i18nBehavior.i18n('OncType' + type);
if (type == 'VPN' && properties.VPN) { if (type == 'VPN' && properties.VPN) {
let vpnType = CrOnc.getStateOrActiveString(properties.VPN.Type); let vpnType = CrOnc.getStateOrActiveString(properties.VPN.Type);
if (vpnType == 'ThirdPartyVPN' && properties.VPN.ThirdPartyVPN) { if (vpnType == 'ThirdPartyVPN' && properties.VPN.ThirdPartyVPN) {
let providerName = properties.VPN.ThirdPartyVPN.ProviderName; let providerName = properties.VPN.ThirdPartyVPN.ProviderName;
if (providerName) if (providerName)
return i18n.call('vpnNameTemplate', providerName, name); return i18nBehavior.i18n('vpnNameTemplate', providerName, name);
} }
} }
return name; return name;
......
...@@ -67,3 +67,16 @@ var I18nBehavior = { ...@@ -67,3 +67,16 @@ var I18nBehavior = {
return loadTimeData.valueExists(id); return loadTimeData.valueExists(id);
}, },
}; };
/**
* TODO(stevenjb): Replace with an interface. b/24294625
* @typedef {{
* i18n: function(string, ...string): string}},
* i18nAdvanced: function({
* substitutions: (Array<string>|undefined),
* attrs: (Object<function(Node, string):boolean>|undefined),
* tags: (Array<string>|undefined)}, opts),
* i18nExists: function(string)
* }}
*/
I18nBehavior.Proto;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment