Support badges and connecting animation in cr-network-icon element

This is a follow-up to https://codereview.chromium.org/874283006
which introduces the cr-network-icon Polymer element for
displaying an icon representing network state in web UI.

It also includes minor changes to the fake shill implementation to facilitate manual testing.

BUG=455499

Review URL: https://codereview.chromium.org/954293003

Cr-Commit-Position: refs/heads/master@{#318824}
diff --git a/chrome/browser/resources/chromeos/network_ui/network_ui.css b/chrome/browser/resources/chromeos/network_ui/network_ui.css
index c3fbf87..874e916a 100644
--- a/chrome/browser/resources/chromeos/network_ui/network_ui.css
+++ b/chrome/browser/resources/chromeos/network_ui/network_ui.css
@@ -50,6 +50,11 @@
   font-weight: bold;
 }
 
+.state-table-icon-cell {
+  display: flex;
+  justify-content: center;
+}
+
 .state-table-expand-button-cell {
   text-align: center;
 }
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc
index 9549971..3c945b1 100644
--- a/chromeos/chromeos_switches.cc
+++ b/chromeos/chromeos_switches.cc
@@ -261,6 +261,7 @@
 // Overrides network stub behavior. By default, ethernet, wifi and vpn are
 // enabled, and transitions occur instantaneously. Multiple options can be
 // comma separated (no spaces). Note: all options are in the format 'foo=x'.
+// Values are case sensitive and based on Shill names in service_constants.h.
 // See FakeShillManagerClient::SetInitialNetworkState for implementation.
 // Examples:
 //  'clear=1' - Clears all default configurations
@@ -270,6 +271,7 @@
 //  'wifi=none' - Wifi is unavailable
 //  'wifi=portal' - Wifi connection will be in Portal state
 //  'cellular=1' - Cellular is initially connected
+//  'cellular=LTE' - Cellular is initially connected, technology is LTE
 //  'interactive=3' - Interactive mode, connect/scan/etc requests take 3 secs
 const char kShillStub[] = "shill-stub";
 
diff --git a/chromeos/dbus/fake_shill_manager_client.cc b/chromeos/dbus/fake_shill_manager_client.cc
index 72dedef..2702ad9 100644
--- a/chromeos/dbus/fake_shill_manager_client.cc
+++ b/chromeos/dbus/fake_shill_manager_client.cc
@@ -105,6 +105,19 @@
                            base::StringValue(shill::kStatePortal));
 }
 
+bool IsCellularTechnology(const std::string& type) {
+  return (type == shill::kNetworkTechnology1Xrtt ||
+          type == shill::kNetworkTechnologyEvdo ||
+          type == shill::kNetworkTechnologyGsm ||
+          type == shill::kNetworkTechnologyGprs ||
+          type == shill::kNetworkTechnologyEdge ||
+          type == shill::kNetworkTechnologyUmts ||
+          type == shill::kNetworkTechnologyHspa ||
+          type == shill::kNetworkTechnologyHspaPlus ||
+          type == shill::kNetworkTechnologyLte ||
+          type == shill::kNetworkTechnologyLteAdvanced);
+}
+
 const char* kTechnologyUnavailable = "unavailable";
 const char* kNetworkActivated = "activated";
 const char* kNetworkDisabled = "disabled";
@@ -118,6 +131,7 @@
 
 FakeShillManagerClient::FakeShillManagerClient()
     : interactive_delay_(0),
+      cellular_technology_(shill::kNetworkTechnologyGsm),
       weak_ptr_factory_(this) {
   ParseCommandLineSwitch();
 }
@@ -776,7 +790,7 @@
                          shill::kTypeCellular,
                          state,
                          add_to_visible);
-    base::StringValue technology_value(shill::kNetworkTechnologyGsm);
+    base::StringValue technology_value(cellular_technology_);
     devices->SetDeviceProperty("/device/cellular1",
                                shill::kTechnologyFamilyProperty,
                                technology_value);
@@ -1066,7 +1080,6 @@
 bool FakeShillManagerClient::SetInitialNetworkState(std::string type_arg,
                                                     std::string state_arg) {
   std::string state;
-  state_arg = base::StringToLowerASCII(state_arg);
   if (state_arg.empty() || state_arg == "1" || state_arg == "on" ||
       state_arg == "enabled" || state_arg == "connected" ||
       state_arg == "online") {
@@ -1088,12 +1101,20 @@
   } else if (state_arg == "active" || state_arg == "activated") {
     // Technology is enabled, a service is connected and Activated.
     state = kNetworkActivated;
+  } else if (type_arg == shill::kTypeCellular &&
+             IsCellularTechnology(state_arg)) {
+    state = shill::kStateOnline;
+    cellular_technology_ = state_arg;
+  } else if (type_arg == shill::kTypeCellular && state_arg == "LTEAdvanced") {
+    // Special case, Shill name contains a ' '.
+    state = shill::kStateOnline;
+    cellular_technology_ = shill::kNetworkTechnologyLteAdvanced;
   } else {
-    LOG(ERROR) << "Unrecognized initial state: " << state_arg;
+    LOG(ERROR) << "Unrecognized initial state: " << type_arg << "="
+               << state_arg;
     return false;
   }
 
-  type_arg = base::StringToLowerASCII(type_arg);
   // Special cases
   if (type_arg == "wireless") {
     shill_initial_state_map_[shill::kTypeWifi] = state;
diff --git a/chromeos/dbus/fake_shill_manager_client.h b/chromeos/dbus/fake_shill_manager_client.h
index b21b2a1..61d1809 100644
--- a/chromeos/dbus/fake_shill_manager_client.h
+++ b/chromeos/dbus/fake_shill_manager_client.h
@@ -142,6 +142,9 @@
   // Initial state for fake services.
   std::map<std::string, std::string> shill_initial_state_map_;
 
+  // Technology type for fake cellular service.
+  std::string cellular_technology_;
+
   // Roaming state for fake cellular service.
   std::string roaming_state_;
 
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_3g.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_3g.png
new file mode 100644
index 0000000..cfe578b
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_3g.png
Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_4g.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_4g.png
new file mode 100644
index 0000000..0729051
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_4g.png
Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_edge.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_edge.png
new file mode 100644
index 0000000..1620182
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_edge.png
Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_evdo.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_evdo.png
new file mode 100644
index 0000000..7742ace
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_evdo.png
Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_gsm.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_gsm.png
new file mode 100644
index 0000000..b6690aa
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_gsm.png
Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_hspa.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_hspa.png
new file mode 100644
index 0000000..c1760fe
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_hspa.png
Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_hspa_plus.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_hspa_plus.png
new file mode 100644
index 0000000..ff2ac509
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_hspa_plus.png
Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_lte.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_lte.png
new file mode 100644
index 0000000..16d3157
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_lte.png
Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_lte_advanced.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_lte_advanced.png
new file mode 100644
index 0000000..d97c035d
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_lte_advanced.png
Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/badge_roaming.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_roaming.png
new file mode 100644
index 0000000..7036c55
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_network_icon/badge_roaming.png
Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/secure.png b/ui/webui/resources/cr_elements/cr_network_icon/badge_secure.png
similarity index 100%
rename from ui/webui/resources/cr_elements/cr_network_icon/secure.png
rename to ui/webui/resources/cr_elements/cr_network_icon/badge_secure.png
Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.css b/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.css
index 3406bcc..1ba4729 100644
--- a/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.css
+++ b/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.css
@@ -4,8 +4,10 @@
 
 :host {
   display: inline-block;
+  height: 50px;
   overflow: hidden;
   position: relative;
+  width: 50px;
 }
 
 #icon {
@@ -38,10 +40,39 @@
   top: -400%;
 }
 
+/* Connecting animation */
+
+#icon.connecting {
+  -webkit-animation: levels 1s infinite;
+  -webkit-animation-timing-function: steps(4, start);
+}
+
+@-webkit-keyframes levels {
+  from {
+    top: 0%;
+  }
+  to {
+    top: -400%;
+  }
+}
+
+/* Badges. */
+/* Note: These use left/right because we do not reverse the badges for RTL. */
+
+/* Upper-left corner */
+#technology {
+  height: 40%;
+  left: 0px;
+  position: absolute;
+  top: 0px;
+}
+
+/* Lower-right corner */
+#roaming,
 #secure {
   height: 40%;
-  margin-left: 60%;
-  margin-top: 60%;
+  left: 60%;
   position: absolute;
+  top: 60%;
   width: 40%;
 }
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.html b/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.html
index a8a53fb2..4762f6c 100644
--- a/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.html
+++ b/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.html
@@ -3,9 +3,15 @@
 <polymer-element name="cr-network-icon">
   <template>
     <link rel="stylesheet" href="cr_network_icon.css">
-    <img id="icon">
+    <img id="icon" src="{{iconType | toImageSrc}}">
+    <img id="technology" src="{{technology | toBadgeImageSrc}}"
+        hidden?="{{!technology}}">
+    <img id="roaming"
+        src="chrome://resources/cr_elements/cr_network_icon/badge_roaming.png"
+        hidden?="{{!roaming}}">
     <img id="secure"
-        src="chrome://resources/cr_elements/cr_network_icon/secure.png">
+        src="chrome://resources/cr_elements/cr_network_icon/badge_secure.png"
+        hidden?="{{!secure}}">
   </template>
   <script src="cr_network_icon.js"></script>
 </polymer-element>
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.js b/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.js
index 4f6c4d5..c70079e 100644
--- a/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.js
+++ b/ui/webui/resources/cr_elements/cr_network_icon/cr_network_icon.js
@@ -10,10 +10,8 @@
 (function() {
 /**
  * @typedef {{
+ *   showBadges: boolean,
  *   showDisconnected: boolean,
- *   iconType: string,
- *   connected: boolean,
- *   secure: boolean,
  *   strength: number
  * }}
  */
@@ -51,6 +49,30 @@
  * @element cr-network-icon
  */
 Polymer('cr-network-icon', {
+  /**
+   * The icon type to use for the base image of the icon.
+   * @type string
+   */
+  iconType: 'ethernet',
+
+  /**
+   * Set to true to show a badge for roaming networks.
+   * @type boolean
+   */
+  roaming: false,
+
+  /**
+   * Set to true to show a badge for secure networks.
+   * @type boolean
+   */
+  secure: false,
+
+  /**
+   * Set to the name of a technology to show show a badge.
+   * @type string
+   */
+  technology: '',
+
   publish: {
     /**
      * If set, the ONC data properties will be used to display the icon.
@@ -85,9 +107,7 @@
   /** @override */
   attached: function() {
     var params = /** @type {IconParams} */ {
-      connected: false,
-      iconType: 'ethernet',
-      secure: false,
+      showBadges: false,
       showDisconnected: true,
       strength: 0,
     };
@@ -99,12 +119,9 @@
    * network state.
    */
   networkStateChanged: function() {
-    var iconType = getIconTypeFromNetworkType(this.networkState.data.Type);
+    this.iconType = getIconTypeFromNetworkType(this.networkState.data.Type);
     var params = /** @type {IconParams} */ {
-      connected: this.networkState.data.ConnectionState == 'Connected',
-      iconType: iconType,
-      secure: iconType == 'wifi' &&
-          this.networkState.getWiFiSecurity() != 'None',
+      showBadges: true,
       showDisconnected: !this.isListItem,
       strength: this.networkState.getStrength(),
     };
@@ -116,10 +133,9 @@
    * of network, showing a disconnected icon where appropriate and no badges.
    */
   networkTypeChanged: function() {
+    this.iconType = getIconTypeFromNetworkType(this.networkType);
     var params = /** @type {IconParams} */ {
-      connected: false,
-      iconType: getIconTypeFromNetworkType(this.networkType),
-      secure: false,
+      showBadges: false,
       showDisconnected: true,
       strength: 0,
     };
@@ -127,32 +143,126 @@
   },
 
   /**
+   * Returns the url for an image based on identifier |id|.
+   * @param {string} src The identifier describing the image.
+   * @return {string} The url to use for the image 'src' property.
+   */
+  toImageSrc: function(id) {
+    return id ? RESOURCE_IMAGE_BASE + id + RESOURCE_IMAGE_EXT : '';
+  },
+
+  /**
+   * Returns the url for a badge image based on identifier |id|.
+   * @param {string} id The identifier describing the badge.
+   * @return {string} The url to use for the badge image 'src' property.
+   */
+  toBadgeImageSrc: function(id) {
+    return id ? this.toImageSrc('badge_' + id) : '';
+  },
+
+  /**
    * Sets the icon and badge based on the current state and |strength|.
    * @param {!IconParams} params The set of params describing the icon.
    * @private
    */
   setIcon_: function(params) {
     var icon = this.$.icon;
-    if (params.iconType)
-      icon.src = RESOURCE_IMAGE_BASE + params.iconType + RESOURCE_IMAGE_EXT;
 
-    var multiLevel, strength;
-    if (params.iconType == 'wifi' || params.iconType == 'mobile') {
-      multiLevel = true;
-      strength = (params.showDisconnected && !params.connected) ?
-          -1 : params.strength;
+    var multiLevel = (this.iconType == 'wifi' || this.iconType == 'mobile');
+
+    if (this.networkState && multiLevel) {
+      this.setMultiLevelIcon_(params);
     } else {
-      multiLevel = false;
-      strength = -1;
+      icon.className = multiLevel ? 'multi-level level0' : '';
     }
-    icon.classList.toggle('multi-level', multiLevel);
+
+    this.setIconBadges_(params);
+  },
+
+  /**
+   * Toggles icon classes based on strength and connecting properties.
+   * |this.networkState| is expected to be specified.
+   * @param {!IconParams} params The set of params describing the icon.
+   * @private
+   */
+  setMultiLevelIcon_: function(params) {
+    // Set the strength or connecting properties.
+    var networkState = this.networkState;
+
+    var connecting = false;
+    var strength = -1;
+    if (networkState.connecting()) {
+      strength = 0;
+      connecting = true;
+    } else if (networkState.connected() || !params.showDisconnected) {
+      strength = params.strength || 0;
+    }
+
+    var icon = this.$.icon;
+    icon.classList.toggle('multi-level', true);
+    icon.classList.toggle('connecting', connecting);
     icon.classList.toggle('level0', strength < 0);
     icon.classList.toggle('level1', strength >= 0 && strength <= 25);
     icon.classList.toggle('level2', strength > 25 && strength <= 50);
     icon.classList.toggle('level3', strength > 50 && strength <= 75);
     icon.classList.toggle('level4', strength > 75);
+  },
 
-    this.$.secure.hidden = !params.secure;
+  /**
+   * Sets the icon badge visibility properties: roaming, secure, technology.
+   * @param {!IconParams} params The set of params describing the icon.
+   * @private
+   */
+  setIconBadges_: function(params) {
+    var networkState = this.networkState;
+
+    var type =
+        (params.showBadges && networkState) ? networkState.data.Type : '';
+    if (type == CrOnc.Type.WIFI) {
+      this.roaming = false;
+      this.secure = networkState.getWiFiSecurity() != 'None';
+      this.technology = '';
+    } else if (type == CrOnc.Type.WIMAX) {
+      this.roaming = false;
+      this.secure = false;
+      this.technology = '4g';
+    } else if (type == CrOnc.Type.CELLULAR) {
+      this.roaming =
+          networkState.getCellularRoamingState() == CrOnc.RoamingState.ROAMING;
+      this.secure = false;
+      var oncTechnology = networkState.getCellularTechnology();
+      switch (oncTechnology) {
+        case CrOnc.NetworkTechnology.EDGE:
+          this.technology = 'edge';
+          break;
+        case CrOnc.NetworkTechnology.EVDO:
+          this.technology = 'evdo';
+          break;
+        case CrOnc.NetworkTechnology.GPRS:
+        case CrOnc.NetworkTechnology.GSM:
+          this.technology = 'gsm';
+          break;
+        case CrOnc.NetworkTechnology.HSPA:
+          this.technology = 'hspa';
+          break;
+        case CrOnc.NetworkTechnology.HSPA_PLUS:
+          this.technology = 'hspa_plus';
+          break;
+        case CrOnc.NetworkTechnology.LTE:
+          this.technology = 'lte';
+          break;
+        case CrOnc.NetworkTechnology.LTE_ADVANCED:
+          this.technology = 'lte_advanced';
+          break;
+        case CrOnc.NetworkTechnology.UMTS:
+          this.technology = '3g';
+          break;
+      }
+    } else {
+      this.roaming = false;
+      this.secure = false;
+      this.technology = '';
+    }
   },
 });
 })();
diff --git a/ui/webui/resources/cr_elements/cr_network_icon/mobile.png b/ui/webui/resources/cr_elements/cr_network_icon/mobile.png
index 548ef5f..9c2d026 100644
--- a/ui/webui/resources/cr_elements/cr_network_icon/mobile.png
+++ b/ui/webui/resources/cr_elements/cr_network_icon/mobile.png
Binary files differ
diff --git a/ui/webui/resources/cr_elements/cr_onc/cr_onc_data.js b/ui/webui/resources/cr_elements/cr_onc/cr_onc_data.js
index 4bca1d2..01b0f55 100644
--- a/ui/webui/resources/cr_elements/cr_onc/cr_onc_data.js
+++ b/ui/webui/resources/cr_elements/cr_onc/cr_onc_data.js
@@ -22,13 +22,22 @@
     data: null,
   },
 
+  /** @override */
   created: function() {
     this.data = /** @type {CrOnc.NetworkConfigType} */({});
   },
 
-  /**
-   * @return {number} The signal strength of the network.
-   */
+  /** @return {boolean} True if the network is connected. */
+  connected: function() {
+    return this.data.ConnectionState == CrOnc.ConnectionState.CONNECTED;
+  },
+
+  /** @return {boolean} True if the network is connecting. */
+  connecting: function() {
+    return this.data.ConnectionState == CrOnc.ConnectionState.CONNECTING;
+  },
+
+  /** @return {number} The signal strength of the network. */
   getStrength: function() {
     var type = this.data.Type;
     var strength = 0;
@@ -41,12 +50,21 @@
     return strength;
   },
 
-  /**
-   * Returns the WiFi security type. Undefined or empty defaults to 'None'.
-   * @return {string} The WiFi security type.
-   */
+  /** @return {CrOnc.Security} The ONC security type. */
   getWiFiSecurity: function() {
     return (this.data.WiFi && this.data.WiFi.Security) ?
-        this.data.WiFi.Security : 'None';
+        this.data.WiFi.Security : CrOnc.Security.NONE;
+  },
+
+  /** @return {CrOnc.RoamingState} The ONC roaming state. */
+  getCellularRoamingState: function() {
+    return (this.data.Cellular && this.data.Cellular.RoamingState) ?
+        this.data.Cellular.RoamingState : CrOnc.RoamingState.UNKNOWN;
+  },
+
+  /** @return {CrOnc.NetworkTechnology} The ONC network technology. */
+  getCellularTechnology: function() {
+    return (this.data.Cellular && this.data.Cellular.NetworkTechnology) ?
+        this.data.Cellular.NetworkTechnology : CrOnc.NetworkTechnology.UNKNOWN;
   }
 });
diff --git a/ui/webui/resources/cr_elements/cr_onc/cr_onc_types.js b/ui/webui/resources/cr_elements/cr_onc/cr_onc_types.js
index 8c010ac..714d4593 100644
--- a/ui/webui/resources/cr_elements/cr_onc/cr_onc_types.js
+++ b/ui/webui/resources/cr_elements/cr_onc/cr_onc_types.js
@@ -12,16 +12,67 @@
 
 var CrOnc = {};
 
+/** @enum {string} */
+CrOnc.Type = {
+  CELLULAR: 'Cellular',
+  ETHERNET: 'Ethernet',
+  VPN: 'VPN',
+  WIFI: 'WiFi',
+  WIMAX: 'WiMAX',
+};
+
+/** @enum {string} */
+CrOnc.ConnectionState = {
+  CONNECTED: 'Connected',
+  CONNECTING: 'Connecting',
+  NOT_CONNECTED: 'NotConnected',
+};
+
+/** @enum {string} */
+CrOnc.NetworkTechnology = {
+  EDGE: 'EDGE',
+  EVDO: 'EVDO',
+  GPRS: 'GPRS',
+  GSM: 'GSM',
+  HSPA: 'HSPA',
+  HSPA_PLUS: 'HSPA+',
+  LTE: 'LTE',
+  LTE_ADVANCED: 'LTE Advanced',
+  UMTS: 'UMTS',
+  UNKNOWN: 'Unknown',
+};
+
+/** @enum {string} */
+CrOnc.RoamingState = {
+  HOME: 'Home',
+  REQUIRED: 'Required',
+  ROAMING: 'Roaming',
+  UNKNOWN: 'Unknown',
+};
+
+/** @enum {string} */
+CrOnc.Security = {
+  NONE: 'None',
+  WEP_8021X: 'WEP-8021X',
+  WEP_PSK: 'WEP-PSK',
+  WPA_EAP: 'WPA-EAP',
+  WPA_PSK: 'WPA-PSK',
+};
+
 /** @typedef {string|!Object} */
 CrOnc.ManagedStringType;
 
 /**
- * @typedef {{NetworkTechnology: string, Strength: number}}
+ * @typedef {{
+ *   NetworkTechnology: CrOnc.NetworkTechnology,
+ *   RoamingState: CrOnc.RoamingState,
+ *   Strength: number
+ * }}
  */
 CrOnc.CellularType;
 
 /**
- * @typedef {{Security: string, Strength: number}}
+ * @typedef {{Security: CrOnc.Security, Strength: number}}
  */
 CrOnc.WiFiType;
 
@@ -30,22 +81,13 @@
  */
 CrOnc.WiMAXType;
 
-/** @enum {string} */
-CrOnc.Type = {
-  CELLULAR: "Cellular",
-  ETHERNET: "Ethernet",
-  VPN: "VPN",
-  WIFI: "WiFi",
-  WIMAX: "WiMAX",
-};
-
 /**
  * @typedef {{
  *   Cellular: CrOnc.CellularType,
- *   ConnectionState: string,
+ *   ConnectionState: CrOnc.ConnectionState,
  *   GUID: string,
  *   Name: CrOnc.ManagedStringType,
- *   Type: string,
+ *   Type: CrOnc.Type,
  *   WiFi: CrOnc.WiFiType,
  *   WiMAX: CrOnc.WiMAXType
  * }}
diff --git a/ui/webui/resources/cr_elements_images.grdp b/ui/webui/resources/cr_elements_images.grdp
index de2116d..46a3689 100644
--- a/ui/webui/resources/cr_elements_images.grdp
+++ b/ui/webui/resources/cr_elements_images.grdp
@@ -1,18 +1,48 @@
 <?xml version="1.0" encoding="utf-8"?>
 <grit-part>
+  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_3G"
+           file="cr_elements/cr_network_icon/badge_3g.png" 
+           type="BINDATA" />
+  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_4G"
+           file="cr_elements/cr_network_icon/badge_4g.png" 
+           type="BINDATA" />
+  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_EDGE"
+           file="cr_elements/cr_network_icon/badge_edge.png" 
+           type="BINDATA" />
+  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_EVDO"
+           file="cr_elements/cr_network_icon/badge_evdo.png" 
+           type="BINDATA" />
+  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_GPRS"
+           file="cr_elements/cr_network_icon/badge_gsm.png" 
+           type="BINDATA" />
+  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_HSPA"
+           file="cr_elements/cr_network_icon/badge_hspa.png" 
+           type="BINDATA" />
+  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_HSPA_PLUS"
+           file="cr_elements/cr_network_icon/badge_hspa_plus.png" 
+           type="BINDATA" />
+  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_LTE"
+           file="cr_elements/cr_network_icon/badge_lte.png" 
+           type="BINDATA" />
+  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_LTE_ADVANCED"
+           file="cr_elements/cr_network_icon/badge_lte_advanced.png" 
+           type="BINDATA" />
+  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_ROAMING"
+           file="cr_elements/cr_network_icon/badge_roaming.png" 
+           type="BINDATA" />
+  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_BADGE_SECURE"
+           file="cr_elements/cr_network_icon/badge_secure.png" 
+           type="BINDATA" />
   <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_ETHERNET"
            file="cr_elements/cr_network_icon/ethernet.png" 
            type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_WIFI"
-           file="cr_elements/cr_network_icon/wifi.png" 
-           type="BINDATA" />
   <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_MOBILE"
            file="cr_elements/cr_network_icon/mobile.png" 
            type="BINDATA" />
   <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_VPN"
            file="cr_elements/cr_network_icon/vpn.png" 
            type="BINDATA" />
-  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_SECURE"
-           file="cr_elements/cr_network_icon/secure.png" 
+  <include name="IDR_WEBUI_CR_ELEMENTS_NETWORK_ICON_WIFI"
+           file="cr_elements/cr_network_icon/wifi.png" 
            type="BINDATA" />
 </grit-part>