blob: e769a82943924816753c1b24f65a927a74f076a4 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/cros/network_parser.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h" // for debug output only.
#include "base/strings/stringprintf.h"
#include "base/values.h"
// Needed only for debug output (ConnectionTypeToString).
#include "chrome/browser/chromeos/cros/native_network_constants.h"
namespace chromeos {
NetworkDeviceParser::NetworkDeviceParser(
const EnumMapper<PropertyIndex>* mapper) : mapper_(mapper) {
CHECK(mapper);
}
NetworkDeviceParser::~NetworkDeviceParser() {
}
NetworkDevice* NetworkDeviceParser::CreateDeviceFromInfo(
const std::string& device_path,
const DictionaryValue& info) {
scoped_ptr<NetworkDevice> device(CreateNewNetworkDevice(device_path));
if (!UpdateDeviceFromInfo(info, device.get())) {
NOTREACHED() << "Unable to create new device";
return NULL;
}
VLOG(2) << "Created device for path " << device_path;
return device.release();
}
bool NetworkDeviceParser::UpdateDeviceFromInfo(const DictionaryValue& info,
NetworkDevice* device) {
for (DictionaryValue::Iterator iter(info); !iter.IsAtEnd(); iter.Advance())
UpdateStatus(iter.key(), iter.value(), device, NULL);
if (VLOG_IS_ON(2)) {
std::string json;
base::JSONWriter::WriteWithOptions(&info,
base::JSONWriter::OPTIONS_PRETTY_PRINT,
&json);
VLOG(2) << "Updated device for path "
<< device->device_path() << ": " << json;
}
return true;
}
bool NetworkDeviceParser::UpdateStatus(const std::string& key,
const base::Value& value,
NetworkDevice* device,
PropertyIndex* index) {
PropertyIndex found_index = mapper().Get(key);
if (index)
*index = found_index;
if (!ParseValue(found_index, value, device)) {
VLOG(3) << "NetworkDeviceParser: Unhandled key: " << key;
return false;
}
if (VLOG_IS_ON(3)) {
std::string value_json;
base::JSONWriter::WriteWithOptions(&value,
base::JSONWriter::OPTIONS_PRETTY_PRINT,
&value_json);
VLOG(3) << "Updated value on device: "
<< device->device_path() << "[" << key << "] = " << value_json;
}
return true;
}
NetworkDevice* NetworkDeviceParser::CreateNewNetworkDevice(
const std::string&device_path) {
return new NetworkDevice(device_path);
}
//----------- Network Parser -----------------
NetworkParser::NetworkParser(const EnumMapper<PropertyIndex>* mapper)
: mapper_(mapper) {
CHECK(mapper);
}
NetworkParser::~NetworkParser() {
}
Network* NetworkParser::CreateNetworkFromInfo(
const std::string& service_path,
const DictionaryValue& info) {
ConnectionType type = ParseTypeFromDictionary(info);
if (type == TYPE_UNKNOWN) // Return NULL if cannot parse network type.
return NULL;
scoped_ptr<Network> network(CreateNewNetwork(type, service_path));
UpdateNetworkFromInfo(info, network.get());
VLOG(2) << "Created Network '" << network->name()
<< "' from info. Path:" << service_path
<< " Type:" << ConnectionTypeToString(type);
return network.release();
}
bool NetworkParser::UpdateNetworkFromInfo(const DictionaryValue& info,
Network* network) {
network->set_unique_id("");
for (DictionaryValue::Iterator iter(info); !iter.IsAtEnd(); iter.Advance())
network->UpdateStatus(iter.key(), iter.value(), NULL);
if (network->unique_id().empty())
network->CalculateUniqueId();
VLOG(2) << "Updated network '" << network->name()
<< "' Path:" << network->service_path() << " Type:"
<< ConnectionTypeToString(network->type());
return true;
}
bool NetworkParser::UpdateStatus(const std::string& key,
const base::Value& value,
Network* network,
PropertyIndex* index) {
PropertyIndex found_index = mapper().Get(key);
if (index)
*index = found_index;
if (!ParseValue(found_index, value, network)) {
VLOG(3) << "Unhandled key '" << key << "' in Network: " << network->name()
<< " ID: " << network->unique_id()
<< " Type: " << ConnectionTypeToString(network->type());
return false;
}
if (VLOG_IS_ON(3)) {
std::string value_json;
base::JSONWriter::WriteWithOptions(&value,
base::JSONWriter::OPTIONS_PRETTY_PRINT,
&value_json);
VLOG(3) << "Updated value on network: "
<< network->unique_id() << "[" << key << "] = " << value_json;
}
return true;
}
Network* NetworkParser::CreateNewNetwork(
ConnectionType type, const std::string& service_path) {
switch (type) {
case TYPE_ETHERNET: {
EthernetNetwork* ethernet = new EthernetNetwork(service_path);
return ethernet;
}
case TYPE_WIFI: {
WifiNetwork* wifi = new WifiNetwork(service_path);
return wifi;
}
case TYPE_WIMAX: {
WimaxNetwork* wifi = new WimaxNetwork(service_path);
return wifi;
}
case TYPE_CELLULAR: {
CellularNetwork* cellular = new CellularNetwork(service_path);
return cellular;
}
case TYPE_VPN: {
VirtualNetwork* vpn = new VirtualNetwork(service_path);
return vpn;
}
default: {
// If we try and create a service for which we have an unknown
// type, then that's a bug, and we will crash.
LOG(FATAL) << "Unknown service type: " << type;
return NULL;
}
}
}
bool NetworkParser::ParseValue(PropertyIndex index,
const base::Value& value,
Network* network) {
switch (index) {
case PROPERTY_INDEX_NAME: {
std::string name;
if (!value.GetAsString(&name))
return false;
network->SetName(name);
return true;
}
case PROPERTY_INDEX_GUID: {
std::string unique_id;
if (!value.GetAsString(&unique_id))
return false;
network->set_unique_id(unique_id);
return true;
}
case PROPERTY_INDEX_AUTO_CONNECT: {
bool auto_connect;
if (!value.GetAsBoolean(&auto_connect))
return false;
network->set_auto_connect(auto_connect);
return true;
}
case PROPERTY_INDEX_UI_DATA: {
network->set_ui_data(NetworkUIData());
std::string ui_data_json;
if (!value.GetAsString(&ui_data_json))
return false;
scoped_ptr<base::Value> ui_data_value(
base::JSONReader::Read(ui_data_json));
base::DictionaryValue* ui_data_dict = NULL;
if (!ui_data_value.get() ||
!ui_data_value->GetAsDictionary(&ui_data_dict))
return false;
network->set_ui_data(NetworkUIData(*ui_data_dict));
return true;
}
default:
break;
}
return false;
}
} // namespace chromeos