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',
27 value: 'internet-detail',
40 * Whether the page is a subpage.
48 * Title for the page header and navigation menu.
53 return loadTimeData.getString('internetDetailPageTitle');
58 * Reflects the selected settings page. We use this to extract guid from
59 * window.location.href when this page is navigated to. This is a
60 * workaround for a bug in the 1.0 version of more-routing where
61 * selected-params='{{params}}' is not correctly setting params in
62 * settings_main.html. TODO(stevenjb): Remove once more-routing is fixed.
63 * @type {?{PAGE_ID: string}}
68 observer: 'selectedPageChanged_'
72 * Name of the 'core-icon' to show. TODO(stevenjb): Update this with the
73 * icon for the active internet connection.
77 value: 'settings-ethernet',
82 * The network GUID to display details for.
87 observer: 'guidChanged_',
91 * The current state for the network matching |guid|. TODO(stevenjb): Use
92 * chrome.networkingProperties.NetworkPoperties once it is defined. This
93 * will be a super-set of NetworkStateProperties. Currently properties that
94 * are not defined in NetworkStateProperties are accessed through
95 * CrOnc.getActive* which uses [] to access the property, which avoids any
96 * type checking (see CrOnc.getProperty for more info).
97 * @type {?CrOnc.NetworkStateProperties}
102 observer: 'networkStateChanged_'
106 * The network AutoConnect state.
111 observer: 'autoConnectChanged_'
115 * The network preferred state.
120 observer: 'preferNetworkChanged_'
124 * The network IP Address.
132 * Object providing network type values for data binding.
138 CELLULAR: CrOnc.Type.CELLULAR,
139 ETHERNET: CrOnc.Type.ETHERNET,
141 WIFI: CrOnc.Type.WI_FI,
142 WIMAX: CrOnc.Type.WI_MAX,
149 * Listener function for chrome.networkingPrivate.onNetworksChanged event.
150 * @type {function(!Array<string>)}
153 networksChangedListener_: function() {},
156 attached: function() {
157 this.networksChangedListener_ = this.onNetworksChangedEvent_.bind(this);
158 chrome.networkingPrivate.onNetworksChanged.addListener(
159 this.networksChangedListener_);
163 detached: function() {
164 chrome.networkingPrivate.onNetworksChanged.removeListener(
165 this.networksChangedListener_);
169 * Polymer guid changed method.
171 guidChanged_: function() {
174 this.getNetworkDetails_();
178 * Polymer guid changed method. TODO(stevenjb): Remove, see TODO above.
180 selectedPageChanged_: function() {
181 if ((this.selectedPage && this.selectedPage.PAGE_ID) != this.PAGE_ID)
183 var href = window.location.href;
184 var idx = href.lastIndexOf('/');
185 var guid = href.slice(idx + 1);
190 * Polymer networkState changed method.
192 networkStateChanged_: function() {
193 if (!this.networkState)
196 // Update autoConnect if it has changed. Default value is false.
197 var autoConnect = /** @type {boolean} */(
198 CrOnc.getActiveTypeValue(this.networkState, 'AutoConnect')) || false;
199 if (autoConnect != this.autoConnect)
200 this.autoConnect = autoConnect;
202 // Update preferNetwork if it has changed. Default value is false.
203 var preferNetwork = this.networkState.Priority > 0;
204 if (preferNetwork != this.preferNetwork)
205 this.preferNetwork = preferNetwork;
207 // Set the IPAddress property to the IPV4 Address.
208 var ipv4 = CrOnc.getIPConfigForType(this.networkState, CrOnc.IPType.IPV4);
209 this.IPAddress = (ipv4 && ipv4.IPAddress) || '';
213 * Polymer autoConnect changed method.
215 autoConnectChanged_: function() {
216 if (!this.networkState || !this.guid)
218 var onc = this.getEmptyNetworkProperties_();
219 CrOnc.setTypeProperty(onc, 'AutoConnect', this.autoConnect);
220 this.setNetworkProperties_(onc);
224 * Polymer preferNetwork changed method.
226 preferNetworkChanged_: function() {
227 if (!this.networkState || !this.guid)
229 var onc = this.getEmptyNetworkProperties_();
230 onc.Priority = this.preferNetwork ? 1 : 0;
231 this.setNetworkProperties_(onc);
235 * networkingPrivate.onNetworksChanged event callback.
236 * @param {!Array<string>} networkIds The list of changed network GUIDs.
239 onNetworksChangedEvent_: function(networkIds) {
240 if (networkIds.indexOf(this.guid) != -1)
241 this.getNetworkDetails_();
245 * Calls networkingPrivate.getProperties for this.guid.
248 getNetworkDetails_: function() {
251 chrome.networkingPrivate.getProperties(
252 this.guid, this.getPropertiesCallback_.bind(this));
256 * networkingPrivate.getProperties callback.
257 * @param {Object} properties The network properties.
260 getPropertiesCallback_: function(properties) {
261 this.networkState = /** @type {CrOnc.NetworkStateProperties}*/(properties);
263 // If state becomes null (i.e. the network is no longer visible), close
265 this.navigateBack_();
270 * @param {!chrome.networkingPrivate.NetworkConfigProperties} onc The ONC
271 * network properties.
274 setNetworkProperties_: function(onc) {
277 chrome.networkingPrivate.setProperties(this.guid, onc, function() {
278 if (chrome.runtime.lastError) {
279 // An error typically indicates invalid input; request the properties
280 // to update any invalid fields.
281 this.getNetworkDetails_();
287 * @return {!chrome.networkingPrivate.NetworkConfigProperties} An ONC
288 * dictionary with just the Type property set. Used for passing properties
289 * to setNetworkProperties_.
292 getEmptyNetworkProperties_: function() {
293 return {Type: this.networkState.Type};
297 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
298 * @return {string} The text to display for the network name.
301 getStateName_: function(state) {
302 return (state && state.Name) || '';
306 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
307 * @return {string} The text to display for the network connection state.
310 getStateText_: function(state) {
311 // TODO(stevenjb): Localize.
312 return (state && state.ConnectionState) || '';
316 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
317 * @return {boolean} True if the state is connected.
320 isConnectedState_: function(state) {
321 return !!state && state.ConnectionState == CrOnc.ConnectionState.CONNECTED;
325 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
326 * @return {boolean} Whether or not to show the 'Connect' button.
329 showConnect_: function(state) {
330 return !!state && state.Type != CrOnc.Type.ETHERNET &&
331 state.ConnectionState == CrOnc.ConnectionState.NOT_CONNECTED;
335 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
336 * @return {boolean} Whether or not to show the 'Activate' button.
339 showActivate_: function(state) {
340 if (!state || state.Type != CrOnc.Type.CELLULAR)
342 var activation = state.Cellular.ActivationState;
343 return activation == CrOnc.ActivationState.NOT_ACTIVATED ||
344 activation == CrOnc.ActivationState.PARTIALLY_ACTIVATED;
348 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
349 * @return {boolean} Whether or not to show the 'View Account' button.
352 showViewAccount_: function(state) {
353 // Show either the 'Activate' or the 'View Account' button.
354 if (this.showActivate_(state))
357 if (!state || state.Type != CrOnc.Type.CELLULAR || !state.Cellular)
360 // Only show if online payment URL is provided or the carrier is Verizon.
361 var carrier = CrOnc.getActiveValue(state, 'Cellular.Carrier');
362 if (carrier != CARRIER_VERIZON) {
363 var paymentPortal = /** @type {CrOnc.PaymentPortal|undefined} */(
364 CrOnc.getActiveValue(state, 'Cellular.PaymentPortal'));
365 if (!paymentPortal || !paymentPortal.Url)
369 // Only show for connected networks or LTE networks with a valid MDN.
370 if (!this.isConnectedState_(state)) {
371 var technology = /** @type {CrOnc.NetworkTechnology|undefined} */(
372 CrOnc.getActiveValue(state, 'Cellular.NetworkTechnology'));
373 if (technology != CrOnc.NetworkTechnology.LTE &&
374 technology != CrOnc.NetworkTechnology.LTE_ADVANCED) {
377 if (!CrOnc.getActiveValue(state, 'Cellular.MDN'))
385 * @return {boolean} Whether or not to enable the network connect button.
388 enableConnect_: function(state) {
389 if (!state || !this.showConnect_(state))
391 if (state.Type == CrOnc.Type.CELLULAR && CrOnc.isSimLocked(state))
393 // TODO(stevenjb): For VPN, check connected state of any network.
398 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
399 * @return {boolean} Whether or not to show the 'Disconnect' button.
402 showDisconnect_: function(state) {
403 return !!state && state.Type != CrOnc.Type.ETHERNET &&
404 state.ConnectionState != CrOnc.ConnectionState.NOT_CONNECTED;
408 * Callback when the Connect button is clicked.
411 onConnectClicked_: function() {
412 chrome.networkingPrivate.startConnect(this.guid);
416 * Callback when the Disconnect button is clicked.
419 onDisconnectClicked_: function() {
420 chrome.networkingPrivate.startDisconnect(this.guid);
424 * Callback when the Activate button is clicked.
427 onActivateClicked_: function() {
428 chrome.networkingPrivate.startActivate(this.guid);
432 * Callback when the View Account button is clicked.
435 onViewAccountClicked_: function() {
436 // startActivate() will show the account page for activated networks.
437 chrome.networkingPrivate.startActivate(this.guid);
441 * Event triggered for elements associated with network properties.
442 * @param {!{detail: !{field: string, value: (string|!Object)}}} event
445 onNetworkPropertyChange_: function(event) {
446 if (!this.networkState)
448 var field = event.detail.field;
449 var value = event.detail.value;
450 var onc = this.getEmptyNetworkProperties_();
451 if (field == 'APN') {
452 CrOnc.setTypeProperty(onc, 'APN', value);
453 } else if (field == 'SIMLockStatus') {
454 CrOnc.setTypeProperty(onc, 'SIMLockStatus', value);
456 console.error('Unexpected property change event: ', field);
459 this.setNetworkProperties_(onc);
463 * Event triggered when the IP Config or NameServers element changes.
464 * @param {!{detail: !{field: string,
465 * value: (string|!CrOnc.IPConfigProperties|
466 * !Array<string>)}}} event
467 * The network-ip-config or network-nameservers change event.
470 onIPConfigChange_: function(event) {
471 if (!this.networkState)
473 var field = event.detail.field;
474 var value = event.detail.value;
475 // Get an empty ONC dictionary and set just the IP Config properties that
477 var onc = this.getEmptyNetworkProperties_();
479 /** @type {chrome.networkingPrivate.IPConfigType|undefined} */(
480 CrOnc.getActiveValue(this.networkState, 'IPAddressConfigType'));
481 if (field == 'IPAddressConfigType') {
482 var newIpConfigType =
483 /** @type {chrome.networkingPrivate.IPConfigType} */(value);
484 if (newIpConfigType == ipConfigType)
486 onc.IPAddressConfigType = newIpConfigType;
487 } else if (field == 'NameServersConfigType') {
489 /** @type {chrome.networkingPrivate.IPConfigType|undefined} */(
490 CrOnc.getActiveValue(this.networkState, 'NameServersConfigType'));
491 var newNsConfigType =
492 /** @type {chrome.networkingPrivate.IPConfigType} */(value);
493 if (newNsConfigType == nsConfigType)
495 onc.NameServersConfigType = newNsConfigType;
496 } else if (field == 'StaticIPConfig') {
497 if (ipConfigType == CrOnc.IPConfigType.STATIC) {
498 var staticIpConfig = /** @type {CrOnc.IPConfigProperties|undefined} */(
499 CrOnc.getActiveValue(this.networkState, 'StaticIPConfig'));
500 if (staticIpConfig &&
501 this.allPropertiesMatch_(staticIpConfig,
502 /** @type {!Object} */(value))) {
506 onc.IPAddressConfigType = CrOnc.IPConfigType.STATIC;
507 if (!onc.StaticIPConfig) {
509 /** @type {!chrome.networkingPrivate.IPConfigProperties} */({});
511 for (let key in value)
512 onc.StaticIPConfig[key] = value[key];
513 } else if (field == 'NameServers') {
514 // If a StaticIPConfig property is specified and its NameServers value
515 // matches the new value, no need to set anything.
516 var nameServers = /** @type {!Array<string>} */(value);
517 if (onc.NameServersConfigType == CrOnc.IPConfigType.STATIC &&
518 onc.StaticIPConfig &&
519 onc.StaticIPConfig.NameServers == nameServers) {
522 onc.NameServersConfigType = CrOnc.IPConfigType.STATIC;
523 if (!onc.StaticIPConfig) {
525 /** @type {!chrome.networkingPrivate.IPConfigProperties} */({});
527 onc.StaticIPConfig.NameServers = nameServers;
529 console.error('Unexpected change field: ' + field);
532 // setValidStaticIPConfig will fill in any other properties from
533 // networkState. This is necessary since we update IP Address and
534 // NameServers independently.
535 CrOnc.setValidStaticIPConfig(onc, this.networkState);
536 this.setNetworkProperties_(onc);
540 * Event triggered when the Proxy configuration element changes.
541 * @param {!{detail: {field: string, value: !CrOnc.ProxySettings}}} event
542 * The network-proxy change event.
545 onProxyChange_: function(event) {
546 if (!this.networkState)
548 var field = event.detail.field;
549 var value = event.detail.value;
550 if (field != 'ProxySettings')
552 var onc = this.getEmptyNetworkProperties_();
553 CrOnc.setProperty(onc, 'ProxySettings', /** @type {!Object} */(value));
554 this.setNetworkProperties_(onc);
558 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
559 * @return {boolean} True if the shared message should be shown.
562 showShared_: function(state) {
564 (state.Source == 'Device' || state.Source == 'DevicePolicy');
568 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
569 * @return {boolean} True if the AutoConnect checkbox should be shown.
572 showAutoConnect_: function(state) {
573 return !!state && state.Type != CrOnc.Type.ETHERNET &&
574 state.Source != CrOnc.Source.NONE;
578 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
579 * @return {boolean} True if the prefer network checkbox should be shown.
582 showPreferNetwork_: function(state) {
583 // TODO(stevenjb): Resolve whether or not we want to allow "preferred" for
584 // state.Type == CrOnc.Type.ETHERNET.
585 return !!state && state.Source != CrOnc.Source.NONE;
589 * @param {boolean} preferNetwork
590 * @return {string} The icon to use for the preferred button.
593 getPreferredIcon_: function(preferNetwork) {
594 return preferNetwork ? 'star' : 'star-border';
598 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
599 * @return {!Array<string>} The fields to display in the info section.
602 getInfoFields_: function(state) {
603 /** @type {!Array<string>} */ var fields = [];
607 if (state.Type == CrOnc.Type.CELLULAR) {
608 fields.push('Cellular.ActivationState',
609 'Cellular.RoamingState',
610 'RestrictedConnectivity',
611 'Cellular.ServingOperator.Name');
613 if (state.Type == CrOnc.Type.VPN) {
614 fields.push('VPN.Host', 'VPN.Type');
615 if (state.VPN.Type == 'OpenVPN')
616 fields.push('VPN.OpenVPN.Username');
617 else if (state.VPN.Type == 'L2TP-IPsec')
618 fields.push('VPN.L2TP.Username');
619 // TODO(stevenjb): ThirdPartyVPN
621 if (state.Type == CrOnc.Type.WI_FI)
622 fields.push('RestrictedConnectivity');
623 if (state.Type == CrOnc.Type.WI_MAX) {
624 fields.push('RestrictedConnectivity', 'WiMAX.EAP.Identity');
630 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
631 * @return {!Array<string>} The fields to display in the Advanced section.
634 getAdvancedFields_: function(state) {
635 /** @type {!Array<string>} */ var fields = [];
638 fields.push('MacAddress');
639 if (state.Type == CrOnc.Type.CELLULAR) {
640 fields.push('Cellular.Carrier',
642 'Cellular.NetworkTechnology',
643 'Cellular.ServingOperator.Code');
645 if (state.Type == CrOnc.Type.WI_FI) {
646 fields.push('WiFi.SSID',
649 'WiFi.SignalStrength',
652 if (state.Type == CrOnc.Type.WI_MAX)
653 fields.push('WiFi.SignalStrength');
658 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
659 * @return {!Array<string>} The fields to display in the device section.
662 getDeviceFields_: function(state) {
663 /** @type {!Array<string>} */ var fields = [];
666 if (state.Type == CrOnc.Type.CELLULAR) {
667 fields.push('Cellular.HomeProvider.Name',
668 'Cellular.HomeProvider.Country',
669 'Cellular.HomeProvider.Code',
670 'Cellular.Manufacturer',
672 'Cellular.FirmwareRevision',
673 'Cellular.HardwareRevision',
681 'Cellular.PRLVersion');
687 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
688 * @return {boolean} True if there are any advanced fields to display.
691 hasAdvancedOrDeviceFields_: function(state) {
692 return this.getAdvancedFields_(state).length > 0 ||
693 this.hasDeviceFields_(state);
697 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
698 * @return {boolean} True if there are any device fields to display.
701 hasDeviceFields_: function(state) {
702 var fields = this.getDeviceFields_(state);
703 return fields.length > 0;
707 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
708 * @return {boolean} True if the network section should be shown.
711 hasNetworkSection_: function(state) {
712 return !!state && state.Type != CrOnc.Type.VPN;
716 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
717 * @param {string} type The network type.
718 * @return {boolean} True if the network type matches 'type'.
721 isType_: function(state, type) {
722 return !!state && state.Type == type;
726 * @param {?CrOnc.NetworkStateProperties} state The network state properties.
727 * @return {boolean} True if the Cellular SIM section should be shown.
730 showCellularSim_: function(state) {
731 if (!state || state.Type != 'Cellular')
733 return CrOnc.getActiveValue(state, 'Cellular.Family') == 'GSM';
737 * Navigate to the previous page.
740 navigateBack_: function() {
741 MoreRouting.navigateTo('internet');
745 * @param {!Object} curValue
746 * @param {!Object} newValue
747 * @return {boolean} True if all properties set in |newValue| are equal to
748 * the corresponding properties in |curValue|. Note: Not all properties
749 * of |curValue| need to be specified in |newValue| for this to return
753 allPropertiesMatch_: function(curValue, newValue) {
754 for (let key in newValue) {
755 if (newValue[key] != curValue[key])