Resubmit CL with memory leaks patched. See 8429004.
BUG=chromium-os:19399
TEST=manual + try linux_chromeos_valgrind
Review URL: http://codereview.chromium.org/8734013

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112274 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/chromeos/cros/native_network_parser.cc b/chrome/browser/chromeos/cros/native_network_parser.cc
index 638336739..a6fb199 100644
--- a/chrome/browser/chromeos/cros/native_network_parser.cc
+++ b/chrome/browser/chromeos/cros/native_network_parser.cc
@@ -112,6 +112,7 @@
   { flimflam::kProxyConfigProperty, PROPERTY_INDEX_PROXY_CONFIG },
   { flimflam::kRoamingStateProperty, PROPERTY_INDEX_ROAMING_STATE },
   { flimflam::kSIMLockStatusProperty, PROPERTY_INDEX_SIM_LOCK },
+  { flimflam::kSSIDProperty, PROPERTY_INDEX_SSID },
   { flimflam::kSaveCredentialsProperty, PROPERTY_INDEX_SAVE_CREDENTIALS },
   { flimflam::kScanningProperty, PROPERTY_INDEX_SCANNING },
   { flimflam::kSecurityProperty, PROPERTY_INDEX_SECURITY },
@@ -139,6 +140,41 @@
   { flimflam::kWifiPhyMode, PROPERTY_INDEX_WIFI_PHY_MODE },
 };
 
+EnumMapper<ConnectionType>::Pair network_type_table[] = {
+  { flimflam::kTypeEthernet, TYPE_ETHERNET },
+  { flimflam::kTypeWifi, TYPE_WIFI },
+  { flimflam::kTypeWimax, TYPE_WIMAX },
+  { flimflam::kTypeBluetooth, TYPE_BLUETOOTH },
+  { flimflam::kTypeCellular, TYPE_CELLULAR },
+  { flimflam::kTypeVPN, TYPE_VPN },
+};
+
+EnumMapper<ConnectionSecurity>::Pair network_security_table[] = {
+  { flimflam::kSecurityNone, SECURITY_NONE },
+  { flimflam::kSecurityWep, SECURITY_WEP },
+  { flimflam::kSecurityWpa, SECURITY_WPA },
+  { flimflam::kSecurityRsn, SECURITY_RSN },
+  { flimflam::kSecurityPsk, SECURITY_PSK },
+  { flimflam::kSecurity8021x, SECURITY_8021X },
+};
+
+EnumMapper<EAPMethod>::Pair network_eap_method_table[] = {
+  { flimflam::kEapMethodPEAP, EAP_METHOD_PEAP },
+  { flimflam::kEapMethodTLS, EAP_METHOD_TLS },
+  { flimflam::kEapMethodTTLS, EAP_METHOD_TTLS },
+  { flimflam::kEapMethodLEAP, EAP_METHOD_LEAP },
+};
+
+EnumMapper<EAPPhase2Auth>::Pair network_eap_auth_table[] = {
+  { flimflam::kEapPhase2AuthPEAPMD5, EAP_PHASE_2_AUTH_MD5 },
+  { flimflam::kEapPhase2AuthPEAPMSCHAPV2, EAP_PHASE_2_AUTH_MSCHAPV2 },
+  { flimflam::kEapPhase2AuthTTLSMD5, EAP_PHASE_2_AUTH_MD5 },
+  { flimflam::kEapPhase2AuthTTLSMSCHAPV2, EAP_PHASE_2_AUTH_MSCHAPV2 },
+  { flimflam::kEapPhase2AuthTTLSMSCHAP, EAP_PHASE_2_AUTH_MSCHAP },
+  { flimflam::kEapPhase2AuthTTLSPAP, EAP_PHASE_2_AUTH_PAP },
+  { flimflam::kEapPhase2AuthTTLSCHAP, EAP_PHASE_2_AUTH_CHAP },
+};
+
 // Serve the singleton mapper instance.
 const EnumMapper<PropertyIndex>* get_native_mapper() {
   CR_DEFINE_STATIC_LOCAL(EnumMapper<PropertyIndex>, mapper,
@@ -148,20 +184,6 @@
   return &mapper;
 }
 
-ConnectionType ParseNetworkType(const std::string& type) {
-  static EnumMapper<ConnectionType>::Pair table[] = {
-    { flimflam::kTypeEthernet, TYPE_ETHERNET },
-    { flimflam::kTypeWifi, TYPE_WIFI },
-    { flimflam::kTypeWimax, TYPE_WIMAX },
-    { flimflam::kTypeBluetooth, TYPE_BLUETOOTH },
-    { flimflam::kTypeCellular, TYPE_CELLULAR },
-    { flimflam::kTypeVPN, TYPE_VPN },
-  };
-  CR_DEFINE_STATIC_LOCAL(EnumMapper<ConnectionType>, parser,
-      (table, arraysize(table), TYPE_UNKNOWN));
-  return parser.Get(type);
-}
-
 }  // namespace
 
 // -------------------- NativeNetworkDeviceParser --------------------
@@ -391,7 +413,7 @@
 }
 
 ConnectionType NativeNetworkDeviceParser::ParseType(const std::string& type) {
-  return ParseNetworkType(type);
+  return NativeNetworkParser::network_type_mapper()->Get(type);
 }
 
 bool NativeNetworkDeviceParser::ParseApnList(const ListValue& list,
@@ -505,9 +527,50 @@
   return get_native_mapper();
 }
 
+// static
+const EnumMapper<ConnectionType>* NativeNetworkParser::network_type_mapper() {
+  CR_DEFINE_STATIC_LOCAL(
+      EnumMapper<ConnectionType>,
+      network_type_mapper,
+      (network_type_table, arraysize(network_type_table), TYPE_UNKNOWN));
+  return &network_type_mapper;
+}
+
+// static
+const EnumMapper<ConnectionSecurity>*
+    NativeNetworkParser::network_security_mapper() {
+  CR_DEFINE_STATIC_LOCAL(
+      EnumMapper<ConnectionSecurity>,
+      network_security_mapper,
+      (network_security_table, arraysize(network_security_table),
+          SECURITY_UNKNOWN));
+  return &network_security_mapper;
+}
+
+// static
+const EnumMapper<EAPMethod>* NativeNetworkParser::network_eap_method_mapper() {
+  CR_DEFINE_STATIC_LOCAL(
+      EnumMapper<EAPMethod>,
+      network_eap_method_mapper,
+      (network_eap_method_table, arraysize(network_eap_method_table),
+          EAP_METHOD_UNKNOWN));
+  return &network_eap_method_mapper;
+}
+
+// static
+const EnumMapper<EAPPhase2Auth>*
+    NativeNetworkParser::network_eap_auth_mapper() {
+  CR_DEFINE_STATIC_LOCAL(
+      EnumMapper<EAPPhase2Auth>,
+      network_eap_auth_mapper,
+      (network_eap_auth_table, arraysize(network_eap_auth_table),
+          EAP_PHASE_2_AUTH_AUTO));
+  return &network_eap_auth_mapper;
+}
+
 const ConnectionType NativeNetworkParser::ParseConnectionType(
     const std::string& connection_type) {
-  return ParseNetworkType(connection_type);
+  return network_type_mapper()->Get(connection_type);
 }
 
 Network* NativeNetworkParser::CreateNewNetwork(
@@ -612,7 +675,7 @@
 }
 
 ConnectionType NativeNetworkParser::ParseType(const std::string& type) {
-  return ParseNetworkType(type);
+  return network_type_mapper()->Get(type);
 }
 
 ConnectionType NativeNetworkParser::ParseTypeFromDictionary(
@@ -1034,45 +1097,16 @@
 
 ConnectionSecurity NativeWifiNetworkParser::ParseSecurity(
     const std::string& security) {
-  static EnumMapper<ConnectionSecurity>::Pair table[] = {
-    { flimflam::kSecurityNone, SECURITY_NONE },
-    { flimflam::kSecurityWep, SECURITY_WEP },
-    { flimflam::kSecurityWpa, SECURITY_WPA },
-    { flimflam::kSecurityRsn, SECURITY_RSN },
-    { flimflam::kSecurityPsk, SECURITY_PSK },
-    { flimflam::kSecurity8021x, SECURITY_8021X },
-  };
-  CR_DEFINE_STATIC_LOCAL(EnumMapper<ConnectionSecurity>, parser,
-      (table, arraysize(table), SECURITY_UNKNOWN));
-  return parser.Get(security);
+  return network_security_mapper()->Get(security);
 }
 
 EAPMethod NativeWifiNetworkParser::ParseEAPMethod(const std::string& method) {
-  static EnumMapper<EAPMethod>::Pair table[] = {
-    { flimflam::kEapMethodPEAP, EAP_METHOD_PEAP },
-    { flimflam::kEapMethodTLS, EAP_METHOD_TLS },
-    { flimflam::kEapMethodTTLS, EAP_METHOD_TTLS },
-    { flimflam::kEapMethodLEAP, EAP_METHOD_LEAP },
-  };
-  CR_DEFINE_STATIC_LOCAL(EnumMapper<EAPMethod>, parser,
-      (table, arraysize(table), EAP_METHOD_UNKNOWN));
-  return parser.Get(method);
+  return network_eap_method_mapper()->Get(method);
 }
 
 EAPPhase2Auth NativeWifiNetworkParser::ParseEAPPhase2Auth(
     const std::string& auth) {
-  static EnumMapper<EAPPhase2Auth>::Pair table[] = {
-    { flimflam::kEapPhase2AuthPEAPMD5, EAP_PHASE_2_AUTH_MD5 },
-    { flimflam::kEapPhase2AuthPEAPMSCHAPV2, EAP_PHASE_2_AUTH_MSCHAPV2 },
-    { flimflam::kEapPhase2AuthTTLSMD5, EAP_PHASE_2_AUTH_MD5 },
-    { flimflam::kEapPhase2AuthTTLSMSCHAPV2, EAP_PHASE_2_AUTH_MSCHAPV2 },
-    { flimflam::kEapPhase2AuthTTLSMSCHAP, EAP_PHASE_2_AUTH_MSCHAP },
-    { flimflam::kEapPhase2AuthTTLSPAP, EAP_PHASE_2_AUTH_PAP },
-    { flimflam::kEapPhase2AuthTTLSCHAP, EAP_PHASE_2_AUTH_CHAP },
-  };
-  CR_DEFINE_STATIC_LOCAL(EnumMapper<EAPPhase2Auth>, parser,
-      (table, arraysize(table), EAP_PHASE_2_AUTH_AUTO));
-  return parser.Get(auth);
+  return network_eap_auth_mapper()->Get(auth);
 }
 
 // -------------------- NativeVirtualNetworkParser --------------------
diff --git a/chrome/browser/chromeos/cros/native_network_parser.h b/chrome/browser/chromeos/cros/native_network_parser.h
index b42892e..9d21bd92 100644
--- a/chrome/browser/chromeos/cros/native_network_parser.h
+++ b/chrome/browser/chromeos/cros/native_network_parser.h
@@ -61,6 +61,10 @@
   NativeNetworkParser();
   virtual ~NativeNetworkParser();
   static const EnumMapper<PropertyIndex>* property_mapper();
+  static const EnumMapper<ConnectionType>* network_type_mapper();
+  static const EnumMapper<ConnectionSecurity>* network_security_mapper();
+  static const EnumMapper<EAPMethod>* network_eap_method_mapper();
+  static const EnumMapper<EAPPhase2Auth>* network_eap_auth_mapper();
   static const ConnectionType ParseConnectionType(const std::string& type);
  protected:
   virtual Network* CreateNewNetwork(ConnectionType type,
diff --git a/chrome/browser/chromeos/cros/network_library.cc b/chrome/browser/chromeos/cros/network_library.cc
index fd2c9c2..b145bb4 100644
--- a/chrome/browser/chromeos/cros/network_library.cc
+++ b/chrome/browser/chromeos/cros/network_library.cc
@@ -18,6 +18,7 @@
 #include "base/i18n/icu_encoding_detection.h"
 #include "base/i18n/icu_string_conversions.h"
 #include "base/i18n/time_formatting.h"
+#include "base/json/json_writer.h"  // for debug output only.
 #include "base/metrics/histogram.h"
 #include "base/stl_util.h"
 #include "base/string_number_conversions.h"
@@ -315,6 +316,22 @@
   return new GValue();
 }
 
+GHashTable* ConvertDictionaryValueToGValueMap(const DictionaryValue* dict) {
+  GHashTable* ghash =
+      g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+  for (DictionaryValue::key_iterator it = dict->begin_keys();
+       it != dict->end_keys(); ++it) {
+    std::string key = *it;
+    Value* val = NULL;
+    if (dict->Get(key, &val)) {
+      g_hash_table_insert(ghash,
+                          g_strdup(const_cast<char*>(key.c_str())),
+                          ConvertValueToGValue(val));
+    }
+  }
+  return ghash;
+}
+
 }  // namespace
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -380,12 +397,30 @@
       type_(type) {
 }
 
-Network::~Network() {}
+Network::~Network() {
+  for (PropertyMap::const_iterator props = property_map_.begin();
+       props != property_map_.end(); ++props) {
+     delete props->second;
+  }
+}
 
 void Network::SetNetworkParser(NetworkParser* parser) {
   network_parser_.reset(parser);
 }
 
+void Network::UpdatePropertyMap(PropertyIndex index, const base::Value& value) {
+  // Add the property to property_map_.  Delete previous value if necessary.
+  Value*& entry = property_map_[index];
+  delete entry;
+  entry = value.DeepCopy();
+  if (VLOG_IS_ON(2)) {
+    std::string value_json;
+    base::JSONWriter::Write(&value, true, &value_json);
+    VLOG(2) << "Updated property map on network: "
+            << unique_id() << "[" << index << "] = " << value_json;
+  }
+}
+
 void Network::SetState(ConnectionState new_state) {
   if (new_state == state_)
     return;
@@ -1463,6 +1498,10 @@
       const std::string& service_name,
       const std::string& server_hostname,
       ProviderType provider_type) = 0;
+  // Call to configure a wifi service. The identifier is either a service_path
+  // or a GUID. |info| is a dictionary of property values.
+  virtual void CallConfigureService(const std::string& identifier,
+                                    const DictionaryValue* info) = 0;
   // Called from NetworkConnectStart.
   // Calls NetworkConnectCompleted when the connection attept completes.
   virtual void CallConnectToNetwork(Network* network) = 0;
@@ -2791,13 +2830,23 @@
 
   for (int i = 0; i < parser.GetNetworkConfigsSize(); i++) {
     // Parse Open Network Configuration blob into a temporary Network object.
-    Network* network = parser.ParseNetwork(i);
-    if (!network) {
+    scoped_ptr<Network> network(parser.ParseNetwork(i));
+    if (!network.get()) {
       DLOG(WARNING) << "Cannot parse networks in ONC file";
       return false;
     }
 
-    // TODO(chocobo): Pass parsed network values to flimflam update network.
+    DictionaryValue dict;
+    for (Network::PropertyMap::const_iterator props =
+             network->property_map_.begin();
+         props != network->property_map_.end(); ++props) {
+      std::string key =
+          NativeNetworkParser::property_mapper()->GetKey(props->first);
+      if (!key.empty())
+        dict.SetWithoutPathExpansion(key, props->second->DeepCopy());
+    }
+
+    CallConfigureService(network->unique_id(), &dict);
   }
   return parser.GetNetworkConfigsSize() != 0;
 }
@@ -3296,6 +3345,8 @@
   virtual void MonitorNetworkDeviceStop(
       const std::string& device_path) OVERRIDE;
 
+  virtual void CallConfigureService(const std::string& identifier,
+                                    const DictionaryValue* info) OVERRIDE;
   virtual void CallConnectToNetwork(Network* network) OVERRIDE;
   virtual void CallRequestWifiNetworkAndConnect(
       const std::string& ssid, ConnectionSecurity security) OVERRIDE;
@@ -3359,6 +3410,11 @@
                                        NetworkMethodErrorType error,
                                        const char* error_message);
 
+  static void ConfigureServiceCallback(void* object,
+                                       const char* service_path,
+                                       NetworkMethodErrorType error,
+                                       const char* error_message);
+
   static void NetworkConnectCallback(void* object,
                                      const char* service_path,
                                      NetworkMethodErrorType error,
@@ -3617,6 +3673,26 @@
 // NetworkLibraryImplBase connect implementation.
 
 // static callback
+void NetworkLibraryImplCros::ConfigureServiceCallback(
+    void* object,
+    const char* service_path,
+    NetworkMethodErrorType error,
+    const char* error_message) {
+  if (error != NETWORK_METHOD_ERROR_NONE) {
+    LOG(WARNING) << "Error from ConfigureService callback for: "
+                 << service_path
+                 << " Error: " << error << " Message: " << error_message;
+  }
+}
+
+void NetworkLibraryImplCros::CallConfigureService(const std::string& identifier,
+                                                  const DictionaryValue* info) {
+  GHashTable* ghash = ConvertDictionaryValueToGValueMap(info);
+  chromeos::ConfigureService(identifier.c_str(), ghash,
+                             ConfigureServiceCallback, this);
+}
+
+// static callback
 void NetworkLibraryImplCros::NetworkConnectCallback(
     void* object,
     const char* service_path,
@@ -4703,6 +4779,8 @@
   virtual void MonitorNetworkDeviceStop(
       const std::string& device_path) OVERRIDE {}
 
+  virtual void CallConfigureService(const std::string& identifier,
+                                    const DictionaryValue* info) OVERRIDE {}
   virtual void CallConnectToNetwork(Network* network) OVERRIDE;
   virtual void CallRequestWifiNetworkAndConnect(
       const std::string& ssid, ConnectionSecurity security) OVERRIDE;
@@ -4919,6 +4997,22 @@
   // autotest browser_tests sometimes conclude the device is offline.
   CHECK(active_network()->connected());
   CHECK(connected_network()->is_active());
+
+  std::string test_blob(
+        "{"
+        "  \"NetworkConfigurations\": ["
+        "    {"
+        "      \"GUID\": \"guid\","
+        "      \"Type\": \"WiFi\","
+        "      \"WiFi\": {"
+        "        \"Security\": \"WEP\","
+        "        \"SSID\": \"MySSID\","
+        "      }"
+        "    }"
+        "  ],"
+        "  \"Certificates\": []"
+        "}");
+  LoadOncNetworks(test_blob);
 }
 
 ////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/chromeos/cros/network_library.h b/chrome/browser/chromeos/cros/network_library.h
index aa1945d..28e33f7 100644
--- a/chrome/browser/chromeos/cros/network_library.h
+++ b/chrome/browser/chromeos/cros/network_library.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_CHROMEOS_CROS_NETWORK_LIBRARY_H_
 #pragma once
 
+#include <map>
 #include <string>
 #include <vector>
 
@@ -131,6 +132,7 @@
   PROPERTY_INDEX_SERVING_OPERATOR,
   PROPERTY_INDEX_SIGNAL_STRENGTH,
   PROPERTY_INDEX_SIM_LOCK,
+  PROPERTY_INDEX_SSID,
   PROPERTY_INDEX_STATE,
   PROPERTY_INDEX_SUPPORT_NETWORK_SCAN,
   PROPERTY_INDEX_TECHNOLOGY_FAMILY,
@@ -673,6 +675,9 @@
   NetworkParser* network_parser() { return network_parser_.get(); }
   void SetNetworkParser(NetworkParser* parser);
 
+  // Updates property_map_ for the corresponding property index.
+  void UpdatePropertyMap(PropertyIndex index, const base::Value& value);
+
   // Set the state and update flags if necessary.
   void SetState(ConnectionState state);
 
@@ -702,6 +707,8 @@
   DictionaryValue* ui_data() { return &ui_data_; }
 
  private:
+  typedef std::map<PropertyIndex, base::Value*> PropertyMap;
+
   // This allows NetworkParser and its subclasses access to device
   // privates so that they can be reconstituted during parsing.  The
   // parsers only access things through the private set_ functions so
@@ -796,6 +803,10 @@
   // network layer.
   scoped_ptr<NetworkParser> network_parser_;
 
+  // This map stores the set of properties for the network.
+  // Not all properties in this map are exposed via get methods.
+  PropertyMap property_map_;
+
   DISALLOW_COPY_AND_ASSIGN(Network);
 };
 
diff --git a/chrome/browser/chromeos/cros/network_parser.cc b/chrome/browser/chromeos/cros/network_parser.cc
index c657662d..8cd898e 100644
--- a/chrome/browser/chromeos/cros/network_parser.cc
+++ b/chrome/browser/chromeos/cros/network_parser.cc
@@ -129,6 +129,7 @@
   PropertyIndex found_index = mapper().Get(key);
   if (index)
     *index = found_index;
+  network->UpdatePropertyMap(found_index, value);
   if (!ParseValue(found_index, value, network)) {
     VLOG(1) << "Unhandled key '" << key << "' in Network: " << network->name()
             << " ID: " << network->unique_id()
diff --git a/chrome/browser/chromeos/cros/network_parser.h b/chrome/browser/chromeos/cros/network_parser.h
index 510e96a..a1a53e21 100644
--- a/chrome/browser/chromeos/cros/network_parser.h
+++ b/chrome/browser/chromeos/cros/network_parser.h
@@ -52,8 +52,10 @@
 
   EnumMapper(const Pair* list, size_t num_entries, EnumType unknown)
       : unknown_value_(unknown) {
-    for (size_t i = 0; i < num_entries; ++i, ++list)
+    for (size_t i = 0; i < num_entries; ++i, ++list) {
       enum_map_[list->key] = list->value;
+      inverse_enum_map_[list->value] = list->key;
+    }
   }
 
   EnumType Get(const std::string& type) const {
@@ -63,10 +65,20 @@
     return unknown_value_;
   }
 
+  std::string GetKey(EnumType type) const {
+    InverseEnumMapConstIter iter = inverse_enum_map_.find(type);
+    if (iter != inverse_enum_map_.end())
+      return iter->second;
+    return std::string();
+  }
+
  private:
   typedef typename std::map<std::string, EnumType> EnumMap;
+  typedef typename std::map<EnumType, std::string> InverseEnumMap;
   typedef typename EnumMap::const_iterator EnumMapConstIter;
+  typedef typename InverseEnumMap::const_iterator InverseEnumMapConstIter;
   EnumMap enum_map_;
+  InverseEnumMap inverse_enum_map_;
   EnumType unknown_value_;
   DISALLOW_COPY_AND_ASSIGN(EnumMapper);
 };
@@ -121,19 +133,24 @@
  public:
   virtual ~NetworkParser();
 
-  // Called when a new network is encountered.  Returns NULL upon failure.
+  // Called when a new network is encountered.  In addition to setting the
+  // members on the Network object, the Network's property_map_ variable
+  // will include all the property and corresponding value in |info|.
+  // Returns NULL upon failure.
   virtual Network* CreateNetworkFromInfo(const std::string& service_path,
                                          const base::DictionaryValue& info);
 
   // Called when an existing network is has new information that needs
-  // to be updated.  Returns false upon failure.
+  // to be updated.  Network's property_map_ variable will be updated.
+  // Returns false upon failure.
   virtual bool UpdateNetworkFromInfo(const base::DictionaryValue& info,
                                      Network* network);
 
   // Called when an individual attribute of an existing network has
   // changed.  |index| is a return value that supplies the appropriate
   // property index for the given key.  |index| is filled in even if
-  // the update fails.  Returns false upon failure.
+  // the update fails.  Network's property_map_ variable will be updated.
+  // Returns false upon failure.
   virtual bool UpdateStatus(const std::string& key,
                             const base::Value& value,
                             Network* network,
diff --git a/chrome/browser/chromeos/cros/onc_network_parser.cc b/chrome/browser/chromeos/cros/onc_network_parser.cc
index 40beafb8..94a56641 100644
--- a/chrome/browser/chromeos/cros/onc_network_parser.cc
+++ b/chrome/browser/chromeos/cros/onc_network_parser.cc
@@ -9,6 +9,7 @@
 #include "base/stringprintf.h"
 #include "base/values.h"
 #include "chrome/browser/chromeos/cros/native_network_constants.h"
+#include "chrome/browser/chromeos/cros/native_network_parser.h"
 #include "chrome/browser/chromeos/cros/network_library.h"
 #include "net/base/cert_database.h"
 #include "net/base/crypto_module.h"
@@ -27,7 +28,7 @@
     { "Remove", PROPERTY_INDEX_REMOVE },
     { "ProxyURL", PROPERTY_INDEX_PROXY_CONFIG },
     { "Type", PROPERTY_INDEX_TYPE },
-    { "SSID", PROPERTY_INDEX_NAME },
+    { "SSID", PROPERTY_INDEX_SSID },
     { "Passphrase", PROPERTY_INDEX_PASSPHRASE },
     { "AutoConnect", PROPERTY_INDEX_AUTO_CONNECT },
     { "HiddenSSID", PROPERTY_INDEX_HIDDEN_SSID },
@@ -149,7 +150,6 @@
 }
 
 Network* OncNetworkParser::ParseNetwork(int n) {
-  // TODO(chocobo): Change this to parse network into a dictionary.
   if (!network_configs_)
     return NULL;
   DictionaryValue* info = NULL;
@@ -166,6 +166,10 @@
   if (type == TYPE_UNKNOWN)  // Return NULL if cannot parse network type.
     return NULL;
   scoped_ptr<Network> network(CreateNewNetwork(type, service_path));
+  // Update property with native value for type.
+  std::string str = NativeNetworkParser::network_type_mapper()->GetKey(type);
+  scoped_ptr<StringValue> val(Value::CreateStringValue(str));
+  network->UpdatePropertyMap(PROPERTY_INDEX_TYPE, *val.get());
 
   // Get the child dictionary with properties for the network.
   // And copy all the values from this network type dictionary to parent.
@@ -173,6 +177,9 @@
   if (!info.GetDictionary(GetTypeFromDictionary(info), &dict))
     return NULL;
 
+  // Add GUID from the parent dictionary.
+  dict->SetString("GUID", GetGuidFromDictionary(info));
+
   UpdateNetworkFromInfo(*dict, network.get());
   VLOG(2) << "Created Network '" << network->name()
           << "' from info. Path:" << service_path
@@ -208,6 +215,13 @@
   return type_string;
 }
 
+std::string OncNetworkParser::GetGuidFromDictionary(
+    const base::DictionaryValue& info) {
+  std::string guid_string;
+  info.GetString("GUID", &guid_string);
+  return guid_string;
+}
+
 bool OncNetworkParser::ParseServerOrCaCertificate(
     int cert_index,
     const std::string& cert_type,
@@ -339,8 +353,12 @@
   DCHECK_EQ(TYPE_WIFI, network->type());
   WifiNetwork* wifi_network = static_cast<WifiNetwork*>(network);
   switch (index) {
-    case PROPERTY_INDEX_NAME: {
-      return OncWirelessNetworkParser::ParseValue(index, value, network);
+    case PROPERTY_INDEX_SSID: {
+      std::string ssid;
+      if (!value.GetAsString(&ssid))
+        break;
+      wifi_network->SetName(ssid);
+      return true;
     }
     case PROPERTY_INDEX_GUID: {
       std::string unique_id;
@@ -353,7 +371,13 @@
       std::string security_string;
       if (!value.GetAsString(&security_string))
         break;
-      wifi_network->set_encryption(ParseSecurity(security_string));
+      ConnectionSecurity security = ParseSecurity(security_string);
+      wifi_network->set_encryption(security);
+      // Also update property with native value for security.
+      std::string str =
+          NativeNetworkParser::network_security_mapper()->GetKey(security);
+      scoped_ptr<StringValue> val(Value::CreateStringValue(str));
+      wifi_network->UpdatePropertyMap(index, *val.get());
       return true;
     }
     case PROPERTY_INDEX_PASSPHRASE: {
@@ -381,6 +405,7 @@
         DCHECK(res);
         if (res) {
           PropertyIndex index = mapper().Get(key);
+          wifi_network->UpdatePropertyMap(index, *eap_value);
           if (!ParseEAPValue(index, *eap_value, wifi_network))
             VLOG(1) << network->name() << ": EAP unhandled key: " << key
                     << " Type: " << eap_value->GetType();
@@ -407,17 +432,29 @@
       return true;
     }
     case PROPERTY_INDEX_EAP_METHOD: {
-      std::string eap_method;
-      if (!value.GetAsString(&eap_method))
+      std::string eap_method_str;
+      if (!value.GetAsString(&eap_method_str))
         break;
-      wifi_network->set_eap_method(ParseEAPMethod(eap_method));
+      EAPMethod eap_method = ParseEAPMethod(eap_method_str);
+      wifi_network->set_eap_method(eap_method);
+      // Also update property with native value for EAP method.
+      std::string str =
+          NativeNetworkParser::network_eap_method_mapper()->GetKey(eap_method);
+      scoped_ptr<StringValue> val(Value::CreateStringValue(str));
+      wifi_network->UpdatePropertyMap(index, *val.get());
       return true;
     }
     case PROPERTY_INDEX_EAP_PHASE_2_AUTH: {
-      std::string eap_phase_2_auth;
-      if (!value.GetAsString(&eap_phase_2_auth))
+      std::string eap_phase_2_auth_str;
+      if (!value.GetAsString(&eap_phase_2_auth_str))
         break;
-      wifi_network->set_eap_phase_2_auth(ParseEAPPhase2Auth(eap_phase_2_auth));
+      EAPPhase2Auth eap_phase_2_auth = ParseEAPPhase2Auth(eap_phase_2_auth_str);
+      wifi_network->set_eap_phase_2_auth(eap_phase_2_auth);
+      // Also update property with native value for EAP phase 2 auth.
+      std::string str = NativeNetworkParser::network_eap_auth_mapper()->GetKey(
+          eap_phase_2_auth);
+      scoped_ptr<StringValue> val(Value::CreateStringValue(str));
+      wifi_network->UpdatePropertyMap(index, *val.get());
       return true;
     }
     case PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY: {
diff --git a/chrome/browser/chromeos/cros/onc_network_parser.h b/chrome/browser/chromeos/cros/onc_network_parser.h
index 66d382e4..2c717ae 100644
--- a/chrome/browser/chromeos/cros/onc_network_parser.h
+++ b/chrome/browser/chromeos/cros/onc_network_parser.h
@@ -63,6 +63,9 @@
   // Returns the type string from the dictionary of network values.
   std::string GetTypeFromDictionary(const base::DictionaryValue& info);
 
+  // Returns the GUID string from the dictionary of network values.
+  std::string GetGuidFromDictionary(const base::DictionaryValue& info);
+
  private:
   bool ParseServerOrCaCertificate(
     int cert_index,