1 // Copyright 2015 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.
7 * 'cr-settings-internet-detail' is the settings subpage containing details
10 * @group Chrome Settings Elements
11 * @element cr-settings-internet-detail
16 /** @const */ var CARRIER_VERIZON = 'Verizon Wireless';
19 is: 'cr-settings-internet-detail-page',
23 * The network GUID to display details for.
28 observer: 'guidChanged_',
32 * The current state for the network matching |guid|. TODO(stevenjb): Use
33 * chrome.networkingProperties.NetworkPoperties once it is defined. This
34 * will be a super-set of NetworkStateProperties. Currently properties that
35 * are not defined in NetworkStateProperties are accessed through
36 * CrOnc.getActive* which uses [] to access the property, which avoids any
37 * type checking (see CrOnc.getProperty for more info).
38 * @type {?CrOnc.NetworkStateProperties}
43 observer: 'networkStateChanged_'
47 * The network AutoConnect state.
52 observer: 'autoConnectChanged_'
56 * The network preferred state.
61 observer: 'preferNetworkChanged_'
65 * The network IP Address.
73 * Object providing network type values for data binding.
79 CELLULAR: CrOnc.Type.CELLULAR,
80 ETHERNET: CrOnc.Type.ETHERNET,
82 WIFI: CrOnc.Type.WI_FI,
83 WIMAX: CrOnc.Type.WI_MAX,
90 * Listener function for chrome.networkingPrivate.onNetworksChanged event.
91 * @type {function(!Array<string>)}
94 networksChangedListener_: function() {},
97 attached: function() {
98 this.networksChangedListener_ = this.onNetworksChangedEvent_.bind(this);
99 chrome.networkingPrivate.onNetworksChanged.addListener(
100 this.networksChangedListener_);
104 detached: function() {
105 chrome.networkingPrivate.onNetworksChanged.removeListener(
106 this.networksChangedListener_);
110 * Polymer guid changed method.
112 guidChanged_: function() {
115 this.getNetworkDetails_();
119 * Polymer networkState changed method.
121 networkStateChanged_: function() {
122 if (!this.networkState)
125 // Update autoConnect if it has changed. Default value is false.
126 var autoConnect = /** @type {boolean} */(
127 CrOnc.getActiveTypeValue(this.networkState, 'AutoConnect')) || false;
128 if (autoConnect != this.autoConnect)
129 this.autoConnect = autoConnect;
131 // Update preferNetwork if it has changed. Default value is false.
132 var preferNetwork = this.networkState.Priority > 0;
133 if (preferNetwork != this.preferNetwork)
134 this.preferNetwork = preferNetwork;
136 // Set the IPAddress property to the IPV4 Address.
137 var ipv4 = CrOnc.getIPConfigForType(this.networkState, CrOnc.IPType.IPV4);
138 this.IPAddress = (ipv4 && ipv4.IPAddress) || '';
142 * Polymer autoConnect changed method.
144 autoConnectChanged_: function() {
145 if (!this.networkState || !this.guid)
147 var onc = this.getEmptyNetworkProperties_();
148 CrOnc.setTypeProperty(onc, 'AutoConnect', this.autoConnect);
149 this.setNetworkProperties_(onc);
153 * Polymer preferNetwork changed method.
155 preferNetworkChanged_: function() {
156 if (!this.networkState || !this.guid)
158 var onc = this.getEmptyNetworkProperties_();
159 onc.Priority = this.preferNetwork ? 1 : 0;
160 this.setNetworkProperties_(onc);
164 * networkingPrivate.onNetworksChanged event callback.
165 * @param {!Array<string>} networkIds The list of changed network GUIDs.
168 onNetworksChangedEvent_: function(networkIds) {
169 if (networkIds.indexOf(this.guid) != -1)
170 this.getNetworkDetails_();
174 * Calls networkingPrivate.getProperties for this.guid.
177 getNetworkDetails_: function() {
180 chrome.networkingPrivate.getProperties(
181 this.guid, this.getPropertiesCallback_.bind(this));
185 * networkingPrivate.getProperties callback.
186 * @param {Object} properties The network properties.
189 getPropertiesCallback_: function(properties) {
190 this.networkState = /** @type {CrOnc.NetworkStateProperties}*/(properties);
192 // If state becomes null (i.e. the network is no longer visible), close
199 * @param {!chrome.networkingPrivate.NetworkConfigProperties} onc The ONC
200 * network properties.
203 setNetworkProperties_: function(onc) {
206 chrome.networkingPrivate.setProperties(this.guid, onc, function() {
207 if (chrome.runtime.lastError) {
208 // An error typically indicates invalid input; request the properties
209 // to update any invalid fields.
210 this.getNetworkDetails_();
216 * @return {!chrome.networkingPrivate.NetworkConfigProperties} An ONC
217 * dictionary with just the Type property set. Used for passing properties
218 * to setNetworkProperties_.
221 getEmptyNetworkProperties_: function() {
222 return {Type: this.networkState.Type};
226 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
227 * @return {string} The text to display for the network name.
230 getStateName_: function(state) {
231 return (state && state.Name) || '';
235 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
236 * @return {string} The text to display for the network connection state.
239 getStateText_: function(state) {
240 // TODO(stevenjb): Localize.
241 return (state && state.ConnectionState) || '';
245 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
246 * @return {boolean} True if the state is connected.
249 isConnectedState_: function(state) {
250 return !!state && state.ConnectionState == CrOnc.ConnectionState.CONNECTED;
254 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
255 * @return {boolean} Whether or not to show the 'Connect' button.
258 showConnect_: function(state) {
259 return !!state && state.Type != CrOnc.Type.ETHERNET &&
260 state.ConnectionState == CrOnc.ConnectionState.NOT_CONNECTED;
264 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
265 * @return {boolean} Whether or not to show the 'Activate' button.
268 showActivate_: function(state) {
269 if (!state || state.Type != CrOnc.Type.CELLULAR)
271 var activation = state.Cellular.ActivationState;
272 return activation == CrOnc.ActivationState.NOT_ACTIVATED ||
273 activation == CrOnc.ActivationState.PARTIALLY_ACTIVATED;
277 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
278 * @return {boolean} Whether or not to show the 'View Account' button.
281 showViewAccount_: function(state) {
282 // Show either the 'Activate' or the 'View Account' button.
283 if (this.showActivate_(state))
286 if (!state || state.Type != CrOnc.Type.CELLULAR || !state.Cellular)
289 // Only show if online payment URL is provided or the carrier is Verizon.
290 var carrier = CrOnc.getActiveValue(state, 'Cellular.Carrier');
291 if (carrier != CARRIER_VERIZON) {
292 var paymentPortal = /** @type {CrOnc.PaymentPortal|undefined} */(
293 CrOnc.getActiveValue(state, 'Cellular.PaymentPortal'));
294 if (!paymentPortal || !paymentPortal.Url)
298 // Only show for connected networks or LTE networks with a valid MDN.
299 if (!this.isConnectedState_(state)) {
300 var technology = /** @type {CrOnc.NetworkTechnology|undefined} */(
301 CrOnc.getActiveValue(state, 'Cellular.NetworkTechnology'));
302 if (technology != CrOnc.NetworkTechnology.LTE &&
303 technology != CrOnc.NetworkTechnology.LTE_ADVANCED) {
306 if (!CrOnc.getActiveValue(state, 'Cellular.MDN'))
314 * @return {boolean} Whether or not to enable the network connect button.
317 enableConnect_: function(state) {
318 if (!state || !this.showConnect_(state))
320 if (state.Type == CrOnc.Type.CELLULAR && CrOnc.isSimLocked(state))
322 // TODO(stevenjb): For VPN, check connected state of any network.
327 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
328 * @return {boolean} Whether or not to show the 'Disconnect' button.
331 showDisconnect_: function(state) {
332 return !!state && state.Type != CrOnc.Type.ETHERNET &&
333 state.ConnectionState != CrOnc.ConnectionState.NOT_CONNECTED;
337 * Callback when the Connect button is clicked.
340 onConnectClicked_: function() {
341 chrome.networkingPrivate.startConnect(this.guid);
345 * Callback when the Disconnect button is clicked.
348 onDisconnectClicked_: function() {
349 chrome.networkingPrivate.startDisconnect(this.guid);
353 * Callback when the Activate button is clicked.
356 onActivateClicked_: function() {
357 chrome.networkingPrivate.startActivate(this.guid);
361 * Callback when the View Account button is clicked.
364 onViewAccountClicked_: function() {
365 // startActivate() will show the account page for activated networks.
366 chrome.networkingPrivate.startActivate(this.guid);
370 * Event triggered for elements associated with network properties.
371 * @param {!{detail: !{field: string, value: (string|!Object)}}} event
374 onNetworkPropertyChange_: function(event) {
375 if (!this.networkState)
377 var field = event.detail.field;
378 var value = event.detail.value;
379 var onc = this.getEmptyNetworkProperties_();
380 if (field == 'APN') {
381 CrOnc.setTypeProperty(onc, 'APN', value);
382 } else if (field == 'SIMLockStatus') {
383 CrOnc.setTypeProperty(onc, 'SIMLockStatus', value);
385 console.error('Unexpected property change event: ', field);
388 this.setNetworkProperties_(onc);
392 * Event triggered when the IP Config or NameServers element changes.
393 * @param {!{detail: !{field: string,
394 * value: (string|!CrOnc.IPConfigProperties|
395 * !Array<string>)}}} event
396 * The network-ip-config or network-nameservers change event.
399 onIPConfigChange_: function(event) {
400 if (!this.networkState)
402 var field = event.detail.field;
403 var value = event.detail.value;
404 // Get an empty ONC dictionary and set just the IP Config properties that
406 var onc = this.getEmptyNetworkProperties_();
408 /** @type {chrome.networkingPrivate.IPConfigType|undefined} */(
409 CrOnc.getActiveValue(this.networkState, 'IPAddressConfigType'));
410 if (field == 'IPAddressConfigType') {
411 var newIpConfigType =
412 /** @type {chrome.networkingPrivate.IPConfigType} */(value);
413 if (newIpConfigType == ipConfigType)
415 onc.IPAddressConfigType = newIpConfigType;
416 } else if (field == 'NameServersConfigType') {
418 /** @type {chrome.networkingPrivate.IPConfigType|undefined} */(
419 CrOnc.getActiveValue(this.networkState, 'NameServersConfigType'));
420 var newNsConfigType =
421 /** @type {chrome.networkingPrivate.IPConfigType} */(value);
422 if (newNsConfigType == nsConfigType)
424 onc.NameServersConfigType = newNsConfigType;
425 } else if (field == 'StaticIPConfig') {
426 if (ipConfigType == CrOnc.IPConfigType.STATIC) {
427 var staticIpConfig = /** @type {CrOnc.IPConfigProperties|undefined} */(
428 CrOnc.getActiveValue(this.networkState, 'StaticIPConfig'));
429 if (staticIpConfig &&
430 this.allPropertiesMatch_(staticIpConfig,
431 /** @type {!Object} */(value))) {
435 onc.IPAddressConfigType = CrOnc.IPConfigType.STATIC;
436 if (!onc.StaticIPConfig) {
438 /** @type {!chrome.networkingPrivate.IPConfigProperties} */({});
440 for (let key in value)
441 onc.StaticIPConfig[key] = value[key];
442 } else if (field == 'NameServers') {
443 // If a StaticIPConfig property is specified and its NameServers value
444 // matches the new value, no need to set anything.
445 var nameServers = /** @type {!Array<string>} */(value);
446 if (onc.NameServersConfigType == CrOnc.IPConfigType.STATIC &&
447 onc.StaticIPConfig &&
448 onc.StaticIPConfig.NameServers == nameServers) {
451 onc.NameServersConfigType = CrOnc.IPConfigType.STATIC;
452 if (!onc.StaticIPConfig) {
454 /** @type {!chrome.networkingPrivate.IPConfigProperties} */({});
456 onc.StaticIPConfig.NameServers = nameServers;
458 console.error('Unexpected change field: ' + field);
461 // setValidStaticIPConfig will fill in any other properties from
462 // networkState. This is necessary since we update IP Address and
463 // NameServers independently.
464 CrOnc.setValidStaticIPConfig(onc, this.networkState);
465 this.setNetworkProperties_(onc);
469 * Event triggered when the Proxy configuration element changes.
470 * @param {!{detail: {field: string, value: !CrOnc.ProxySettings}}} event
471 * The network-proxy change event.
474 onProxyChange_: function(event) {
475 if (!this.networkState)
477 var field = event.detail.field;
478 var value = event.detail.value;
479 if (field != 'ProxySettings')
481 var onc = this.getEmptyNetworkProperties_();
482 CrOnc.setProperty(onc, 'ProxySettings', /** @type {!Object} */(value));
483 this.setNetworkProperties_(onc);
487 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
488 * @return {boolean} True if the shared message should be shown.
491 showShared_: function(state) {
493 (state.Source == 'Device' || state.Source == 'DevicePolicy');
497 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
498 * @return {boolean} True if the AutoConnect checkbox should be shown.
501 showAutoConnect_: function(state) {
502 return !!state && state.Type != CrOnc.Type.ETHERNET &&
503 state.Source != CrOnc.Source.NONE;
507 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
508 * @return {boolean} True if the prefer network checkbox should be shown.
511 showPreferNetwork_: function(state) {
512 // TODO(stevenjb): Resolve whether or not we want to allow "preferred" for
513 // state.Type == CrOnc.Type.ETHERNET.
514 return !!state && state.Source != CrOnc.Source.NONE;
518 * @param {boolean} preferNetwork
519 * @return {string} The icon to use for the preferred button.
522 getPreferredIcon_: function(preferNetwork) {
523 return preferNetwork ? 'star' : 'star-border';
527 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
528 * @return {!Array<string>} The fields to display in the info section.
531 getInfoFields_: function(state) {
532 /** @type {!Array<string>} */ var fields = [];
536 if (state.Type == CrOnc.Type.CELLULAR) {
537 fields.push('Cellular.ActivationState',
538 'Cellular.RoamingState',
539 'RestrictedConnectivity',
540 'Cellular.ServingOperator.Name');
542 if (state.Type == CrOnc.Type.VPN) {
543 fields.push('VPN.Host', 'VPN.Type');
544 if (state.VPN.Type == 'OpenVPN')
545 fields.push('VPN.OpenVPN.Username');
546 else if (state.VPN.Type == 'L2TP-IPsec')
547 fields.push('VPN.L2TP.Username');
548 else if (state.VPN.Type == 'ThirdPartyVPN')
549 fields.push('VPN.ThirdPartyVPN.ProviderName');
551 if (state.Type == CrOnc.Type.WI_FI)
552 fields.push('RestrictedConnectivity');
553 if (state.Type == CrOnc.Type.WI_MAX) {
554 fields.push('RestrictedConnectivity', 'WiMAX.EAP.Identity');
560 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
561 * @return {!Array<string>} The fields to display in the Advanced section.
564 getAdvancedFields_: function(state) {
565 /** @type {!Array<string>} */ var fields = [];
568 fields.push('MacAddress');
569 if (state.Type == CrOnc.Type.CELLULAR) {
570 fields.push('Cellular.Carrier',
572 'Cellular.NetworkTechnology',
573 'Cellular.ServingOperator.Code');
575 if (state.Type == CrOnc.Type.WI_FI) {
576 fields.push('WiFi.SSID',
579 'WiFi.SignalStrength',
582 if (state.Type == CrOnc.Type.WI_MAX)
583 fields.push('WiFi.SignalStrength');
588 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
589 * @return {!Array<string>} The fields to display in the device section.
592 getDeviceFields_: function(state) {
593 /** @type {!Array<string>} */ var fields = [];
596 if (state.Type == CrOnc.Type.CELLULAR) {
597 fields.push('Cellular.HomeProvider.Name',
598 'Cellular.HomeProvider.Country',
599 'Cellular.HomeProvider.Code',
600 'Cellular.Manufacturer',
602 'Cellular.FirmwareRevision',
603 'Cellular.HardwareRevision',
611 'Cellular.PRLVersion');
617 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
618 * @return {boolean} True if there are any advanced fields to display.
621 hasAdvancedOrDeviceFields_: function(state) {
622 return this.getAdvancedFields_(state).length > 0 ||
623 this.hasDeviceFields_(state);
627 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
628 * @return {boolean} True if there are any device fields to display.
631 hasDeviceFields_: function(state) {
632 var fields = this.getDeviceFields_(state);
633 return fields.length > 0;
637 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
638 * @return {boolean} True if the network section should be shown.
641 hasNetworkSection_: function(state) {
642 return !!state && state.Type != CrOnc.Type.VPN;
646 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
647 * @param {string} type The network type.
648 * @return {boolean} True if the network type matches 'type'.
651 isType_: function(state, type) {
652 return !!state && state.Type == type;
656 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
657 * @return {boolean} True if the Cellular SIM section should be shown.
660 showCellularSim_: function(state) {
661 if (!state || state.Type != 'Cellular')
663 return CrOnc.getActiveValue(state, 'Cellular.Family') == 'GSM';
667 * @param {!Object} curValue
668 * @param {!Object} newValue
669 * @return {boolean} True if all properties set in |newValue| are equal to
670 * the corresponding properties in |curValue|. Note: Not all properties
671 * of |curValue| need to be specified in |newValue| for this to return
675 allPropertiesMatch_: function(curValue, newValue) {
676 for (let key in newValue) {
677 if (newValue[key] != curValue[key])