1 // Copyright (c) 2012 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. 4 5 #include "chrome/browser/chromeos/cros/network_parser.h" 6 7 #include "base/json/json_reader.h" 8 #include "base/json/json_writer.h" // for debug output only. 9 #include "base/strings/stringprintf.h" 10 #include "base/values.h" 11 // Needed only for debug output (ConnectionTypeToString). 12 #include "chrome/browser/chromeos/cros/native_network_constants.h" 13 14 namespace chromeos { 15 16 NetworkDeviceParser::NetworkDeviceParser( 17 const EnumMapper<PropertyIndex>* mapper) : mapper_(mapper) { 18 CHECK(mapper); 19 } 20 21 NetworkDeviceParser::~NetworkDeviceParser() { 22 } 23 24 NetworkDevice* NetworkDeviceParser::CreateDeviceFromInfo( 25 const std::string& device_path, 26 const DictionaryValue& info) { 27 scoped_ptr<NetworkDevice> device(CreateNewNetworkDevice(device_path)); 28 if (!UpdateDeviceFromInfo(info, device.get())) { 29 NOTREACHED() << "Unable to create new device"; 30 return NULL; 31 } 32 VLOG(2) << "Created device for path " << device_path; 33 return device.release(); 34 } 35 36 bool NetworkDeviceParser::UpdateDeviceFromInfo(const DictionaryValue& info, 37 NetworkDevice* device) { 38 for (DictionaryValue::Iterator iter(info); !iter.IsAtEnd(); iter.Advance()) 39 UpdateStatus(iter.key(), iter.value(), device, NULL); 40 41 if (VLOG_IS_ON(2)) { 42 std::string json; 43 base::JSONWriter::WriteWithOptions(&info, 44 base::JSONWriter::OPTIONS_PRETTY_PRINT, 45 &json); 46 VLOG(2) << "Updated device for path " 47 << device->device_path() << ": " << json; 48 } 49 return true; 50 } 51 52 bool NetworkDeviceParser::UpdateStatus(const std::string& key, 53 const base::Value& value, 54 NetworkDevice* device, 55 PropertyIndex* index) { 56 PropertyIndex found_index = mapper().Get(key); 57 if (index) 58 *index = found_index; 59 if (!ParseValue(found_index, value, device)) { 60 VLOG(3) << "NetworkDeviceParser: Unhandled key: " << key; 61 return false; 62 } 63 if (VLOG_IS_ON(3)) { 64 std::string value_json; 65 base::JSONWriter::WriteWithOptions(&value, 66 base::JSONWriter::OPTIONS_PRETTY_PRINT, 67 &value_json); 68 VLOG(3) << "Updated value on device: " 69 << device->device_path() << "[" << key << "] = " << value_json; 70 } 71 return true; 72 } 73 74 NetworkDevice* NetworkDeviceParser::CreateNewNetworkDevice( 75 const std::string&device_path) { 76 return new NetworkDevice(device_path); 77 } 78 79 //----------- Network Parser ----------------- 80 81 NetworkParser::NetworkParser(const EnumMapper<PropertyIndex>* mapper) 82 : mapper_(mapper) { 83 CHECK(mapper); 84 } 85 86 NetworkParser::~NetworkParser() { 87 } 88 89 Network* NetworkParser::CreateNetworkFromInfo( 90 const std::string& service_path, 91 const DictionaryValue& info) { 92 ConnectionType type = ParseTypeFromDictionary(info); 93 if (type == TYPE_UNKNOWN) // Return NULL if cannot parse network type. 94 return NULL; 95 scoped_ptr<Network> network(CreateNewNetwork(type, service_path)); 96 UpdateNetworkFromInfo(info, network.get()); 97 VLOG(2) << "Created Network '" << network->name() 98 << "' from info. Path:" << service_path 99 << " Type:" << ConnectionTypeToString(type); 100 return network.release(); 101 } 102 103 bool NetworkParser::UpdateNetworkFromInfo(const DictionaryValue& info, 104 Network* network) { 105 network->set_unique_id(""); 106 for (DictionaryValue::Iterator iter(info); !iter.IsAtEnd(); iter.Advance()) 107 network->UpdateStatus(iter.key(), iter.value(), NULL); 108 109 if (network->unique_id().empty()) 110 network->CalculateUniqueId(); 111 VLOG(2) << "Updated network '" << network->name() 112 << "' Path:" << network->service_path() << " Type:" 113 << ConnectionTypeToString(network->type()); 114 return true; 115 } 116 117 bool NetworkParser::UpdateStatus(const std::string& key, 118 const base::Value& value, 119 Network* network, 120 PropertyIndex* index) { 121 PropertyIndex found_index = mapper().Get(key); 122 if (index) 123 *index = found_index; 124 if (!ParseValue(found_index, value, network)) { 125 VLOG(3) << "Unhandled key '" << key << "' in Network: " << network->name() 126 << " ID: " << network->unique_id() 127 << " Type: " << ConnectionTypeToString(network->type()); 128 return false; 129 } 130 if (VLOG_IS_ON(3)) { 131 std::string value_json; 132 base::JSONWriter::WriteWithOptions(&value, 133 base::JSONWriter::OPTIONS_PRETTY_PRINT, 134 &value_json); 135 VLOG(3) << "Updated value on network: " 136 << network->unique_id() << "[" << key << "] = " << value_json; 137 } 138 return true; 139 } 140 141 Network* NetworkParser::CreateNewNetwork( 142 ConnectionType type, const std::string& service_path) { 143 switch (type) { 144 case TYPE_ETHERNET: { 145 EthernetNetwork* ethernet = new EthernetNetwork(service_path); 146 return ethernet; 147 } 148 case TYPE_WIFI: { 149 WifiNetwork* wifi = new WifiNetwork(service_path); 150 return wifi; 151 } 152 case TYPE_WIMAX: { 153 WimaxNetwork* wifi = new WimaxNetwork(service_path); 154 return wifi; 155 } 156 case TYPE_CELLULAR: { 157 CellularNetwork* cellular = new CellularNetwork(service_path); 158 return cellular; 159 } 160 case TYPE_VPN: { 161 VirtualNetwork* vpn = new VirtualNetwork(service_path); 162 return vpn; 163 } 164 default: { 165 // If we try and create a service for which we have an unknown 166 // type, then that's a bug, and we will crash. 167 LOG(FATAL) << "Unknown service type: " << type; 168 return NULL; 169 } 170 } 171 } 172 173 bool NetworkParser::ParseValue(PropertyIndex index, 174 const base::Value& value, 175 Network* network) { 176 switch (index) { 177 case PROPERTY_INDEX_NAME: { 178 std::string name; 179 if (!value.GetAsString(&name)) 180 return false; 181 network->SetName(name); 182 return true; 183 } 184 case PROPERTY_INDEX_GUID: { 185 std::string unique_id; 186 if (!value.GetAsString(&unique_id)) 187 return false; 188 network->set_unique_id(unique_id); 189 return true; 190 } 191 case PROPERTY_INDEX_AUTO_CONNECT: { 192 bool auto_connect; 193 if (!value.GetAsBoolean(&auto_connect)) 194 return false; 195 network->set_auto_connect(auto_connect); 196 return true; 197 } 198 case PROPERTY_INDEX_UI_DATA: { 199 network->set_ui_data(NetworkUIData()); 200 std::string ui_data_json; 201 if (!value.GetAsString(&ui_data_json)) 202 return false; 203 scoped_ptr<base::Value> ui_data_value( 204 base::JSONReader::Read(ui_data_json)); 205 base::DictionaryValue* ui_data_dict = NULL; 206 if (!ui_data_value.get() || 207 !ui_data_value->GetAsDictionary(&ui_data_dict)) 208 return false; 209 network->set_ui_data(NetworkUIData(*ui_data_dict)); 210 return true; 211 } 212 default: 213 break; 214 } 215 return false; 216 } 217 218 } // namespace chromeos 219