Home | History | Annotate | Download | only in cros
      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