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 @@
<message name="IDS_SETTINGS_INTERNET_ADD_VPN" desc="Settings > Internet > Add VPN label.">
Add OpenVPN / L2TP...
</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.">
Access Point
</message>
......
......@@ -10,7 +10,10 @@
'../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/js/compiled_resources2.gyp:assert',
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
'<(EXTERNS_GYP):chrome_send',
'<(EXTERNS_GYP):management',
'<(EXTERNS_GYP):networking_private',
'<(INTERFACES_GYP):networking_private_interface',
],
'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
......
......@@ -191,7 +191,8 @@
<!-- Advanced section -->
<iron-collapse opened="[[advancedExpanded_]]">
<div class="layout vertical indented">
<div class="settings-box single-column stretch">
<div class="settings-box single-column stretch"
hidden$="[[!hasAdvancedOrDeviceFields_(networkProperties)]]">
<!-- Advanced properties -->
<network-property-list
hidden$="[[!hasAdvancedFields_(networkProperties)]]"
......
......@@ -164,7 +164,7 @@ Polymer({
// Update the detail page title.
this.parentNode.pageTitle =
CrOnc.getNetworkName(this.networkProperties, this.i18n);
CrOnc.getNetworkName(this.networkProperties, this);
},
/** @private */
......@@ -621,13 +621,16 @@ Polymer({
'RestrictedConnectivity', 'Cellular.ServingOperator.Name');
}
if (this.networkProperties.Type == CrOnc.Type.VPN) {
fields.push('VPN.Host', 'VPN.Type');
if (this.networkProperties.VPN.Type == 'OpenVPN')
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')
let vpnType = CrOnc.getActiveValue(this.networkProperties.VPN.Type);
if (vpnType == 'ThirdPartyVPN') {
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)
fields.push('RestrictedConnectivity');
......@@ -702,6 +705,14 @@ Polymer({
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.
* @private
......
<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/html/i18n_behavior.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/neon-animation/neon-animatable.html">
......@@ -50,6 +51,14 @@
on-tap="onAddVPNTap_">
<div class="start add-no-icon">$i18n{internetAddVPN}</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>
</neon-animatable>
<template is="dom-if" route-path="/networkDetail" no-search>
......
......@@ -10,6 +10,8 @@
Polymer({
is: 'settings-internet-page',
behaviors: [I18nBehavior],
properties: {
/**
* Interface for networkingPrivate calls. May be overriden by tests.
......@@ -34,6 +36,43 @@ Polymer({
type: Boolean,
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({
this.addConnectionExpanded_ = !this.addConnectionExpanded_;
},
/*** @private */
/** @private */
onAddWiFiTap_: function() {
chrome.send('addNetwork', [CrOnc.Type.WI_FI]);
},
/*** @private */
/** @private */
onAddVPNTap_: function() {
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) {
void AddInternetStrings(content::WebUIDataSource* html_source) {
LocalizedString localized_strings[] = {
{"internetAddConnection", IDS_SETTINGS_INTERNET_ADD_CONNECTION},
{"internetAddThirdPartyVPN", IDS_SETTINGS_INTERNET_ADD_THIRD_PARTY_VPN},
{"internetAddVPN", IDS_SETTINGS_INTERNET_ADD_VPN},
{"internetAddWiFi", IDS_SETTINGS_INTERNET_ADD_WIFI},
{"internetDetailPageTitle", IDS_SETTINGS_INTERNET_DETAIL},
......
......@@ -53,6 +53,7 @@
{
'target_name': 'cr_onc_types',
'dependencies': [
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
'<(EXTERNS_GYP):networking_private',
],
'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
......
......@@ -91,7 +91,7 @@ Polymer({
}
let network = /** @type {!CrOnc.NetworkStateProperties} */ (this.item);
if (this.isListItem)
return CrOnc.getNetworkName(network, this.i18n);
return CrOnc.getNetworkName(network, this);
return this.i18n('OncType' + network.Type);
},
......@@ -117,7 +117,7 @@ Polymer({
return this.i18n('networkListItemConnected');
if (network.Name && network.ConnectionState) {
return this.getConnectionStateText_(
network.ConnectionState, CrOnc.getNetworkName(network, this.i18n));
network.ConnectionState, CrOnc.getNetworkName(network, this));
}
return this.i18n('networkDisabled');
},
......
......@@ -314,22 +314,22 @@ CrOnc.getAutoConnect = function(properties) {
/**
* @param {!CrOnc.NetworkProperties|!CrOnc.NetworkStateProperties|undefined}
* 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|.
*/
CrOnc.getNetworkName = function(properties, i18n) {
CrOnc.getNetworkName = function(properties, i18nBehavior) {
if (!properties)
return '';
let name = CrOnc.getStateOrActiveString(properties.Name);
let type = CrOnc.getStateOrActiveString(properties.Type);
if (!name)
return i18n.call('OncType' + type);
return i18nBehavior.i18n('OncType' + type);
if (type == 'VPN' && properties.VPN) {
let vpnType = CrOnc.getStateOrActiveString(properties.VPN.Type);
if (vpnType == 'ThirdPartyVPN' && properties.VPN.ThirdPartyVPN) {
let providerName = properties.VPN.ThirdPartyVPN.ProviderName;
if (providerName)
return i18n.call('vpnNameTemplate', providerName, name);
return i18nBehavior.i18n('vpnNameTemplate', providerName, name);
}
}
return name;
......
......@@ -67,3 +67,16 @@ var I18nBehavior = {
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