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.
5 #include "chromeos/network/device_state.h"
7 #include "base/logging.h"
8 #include "base/metrics/histogram.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/values.h"
11 #include "chromeos/network/network_event_log.h"
12 #include "third_party/cros_system_api/dbus/service_constants.h"
16 DeviceState::DeviceState(const std::string& path)
17 : ManagedState(MANAGED_TYPE_DEVICE, path),
18 allow_roaming_(false),
19 provider_requires_roaming_(false),
20 support_network_scan_(false),
22 sim_lock_enabled_(false),
24 eap_authentication_completed_(false) {
27 DeviceState::~DeviceState() {
30 bool DeviceState::PropertyChanged(const std::string& key,
31 const base::Value& value) {
32 // All property values get stored in |properties_|.
33 properties_.SetWithoutPathExpansion(key, value.DeepCopy());
35 if (ManagedStatePropertyChanged(key, value))
37 if (key == shill::kAddressProperty) {
38 return GetStringValue(key, value, &mac_address_);
39 } else if (key == shill::kScanningProperty) {
40 return GetBooleanValue(key, value, &scanning_);
41 } else if (key == shill::kSupportNetworkScanProperty) {
42 return GetBooleanValue(key, value, &support_network_scan_);
43 } else if (key == shill::kCellularAllowRoamingProperty) {
44 return GetBooleanValue(key, value, &allow_roaming_);
45 } else if (key == shill::kProviderRequiresRoamingProperty) {
46 return GetBooleanValue(key, value, &provider_requires_roaming_);
47 } else if (key == shill::kHomeProviderProperty) {
48 const base::DictionaryValue* dict = NULL;
49 if (!value.GetAsDictionary(&dict))
51 std::string home_provider_country;
52 std::string home_provider_name;
53 dict->GetStringWithoutPathExpansion(shill::kOperatorCountryKey,
54 &home_provider_country);
55 dict->GetStringWithoutPathExpansion(shill::kOperatorNameKey,
57 // Set home_provider_id_
58 if (!home_provider_name.empty() && !home_provider_country.empty()) {
59 home_provider_id_ = base::StringPrintf(
61 home_provider_name.c_str(),
62 home_provider_country.c_str());
64 dict->GetStringWithoutPathExpansion(shill::kOperatorCodeKey,
66 LOG(WARNING) << "Carrier ID not defined, using code instead: "
70 } else if (key == shill::kTechnologyFamilyProperty) {
71 return GetStringValue(key, value, &technology_family_);
72 } else if (key == shill::kCarrierProperty) {
73 return GetStringValue(key, value, &carrier_);
74 } else if (key == shill::kFoundNetworksProperty) {
75 const base::ListValue* list = NULL;
76 if (!value.GetAsList(&list))
78 CellularScanResults parsed_results;
79 if (!network_util::ParseCellularScanResults(*list, &parsed_results))
81 scan_results_.swap(parsed_results);
83 } else if (key == shill::kSIMLockStatusProperty) {
84 const base::DictionaryValue* dict = NULL;
85 if (!value.GetAsDictionary(&dict))
88 // Return true if at least one of the property values changed.
89 bool property_changed = false;
90 const base::Value* out_value = NULL;
91 if (!dict->GetWithoutPathExpansion(shill::kSIMLockRetriesLeftProperty,
94 if (GetUInt32Value(shill::kSIMLockRetriesLeftProperty,
95 *out_value, &sim_retries_left_))
96 property_changed = true;
98 if (!dict->GetWithoutPathExpansion(shill::kSIMLockTypeProperty,
101 if (GetStringValue(shill::kSIMLockTypeProperty,
102 *out_value, &sim_lock_type_))
103 property_changed = true;
105 if (!dict->GetWithoutPathExpansion(shill::kSIMLockEnabledProperty,
108 if (GetBooleanValue(shill::kSIMLockEnabledProperty,
109 *out_value, &sim_lock_enabled_))
110 property_changed = true;
112 return property_changed;
113 } else if (key == shill::kMeidProperty) {
114 return GetStringValue(key, value, &meid_);
115 } else if (key == shill::kImeiProperty) {
116 return GetStringValue(key, value, &imei_);
117 } else if (key == shill::kIccidProperty) {
118 return GetStringValue(key, value, &iccid_);
119 } else if (key == shill::kMdnProperty) {
120 return GetStringValue(key, value, &mdn_);
121 } else if (key == shill::kSIMPresentProperty) {
122 return GetBooleanValue(key, value, &sim_present_);
123 } else if (key == shill::kEapAuthenticationCompletedProperty) {
124 return GetBooleanValue(key, value, &eap_authentication_completed_);
125 } else if (key == shill::kIPConfigsProperty) {
126 // If kIPConfigsProperty changes, clear any previous ip_configs_.
127 // ShillPropertyhandler will request the IPConfig objects which will trigger
128 // calls to IPConfigPropertiesChanged.
130 return false; // No actual state change.
135 bool DeviceState::InitialPropertiesReceived(
136 const base::DictionaryValue& properties) {
139 bool locked = !sim_lock_type_.empty();
140 UMA_HISTOGRAM_BOOLEAN("Cellular.SIMLocked", locked);
145 void DeviceState::IPConfigPropertiesChanged(
146 const std::string& ip_config_path,
147 const base::DictionaryValue& properties) {
148 base::DictionaryValue* ip_config = NULL;
149 if (ip_configs_.GetDictionaryWithoutPathExpansion(
150 ip_config_path, &ip_config)) {
151 NET_LOG_EVENT("IPConfig Updated: " + ip_config_path, path());
154 NET_LOG_EVENT("IPConfig Added: " + ip_config_path, path());
155 ip_config = new base::DictionaryValue;
156 ip_configs_.SetWithoutPathExpansion(ip_config_path, ip_config);
158 ip_config->MergeDictionary(&properties);
161 std::string DeviceState::GetFormattedMacAddress() const {
162 if (mac_address_.size() % 2 != 0)
165 for (size_t i = 0; i < mac_address_.size(); ++i) {
166 if ((i != 0) && (i % 2 == 0))
167 result.push_back(':');
168 result.push_back(mac_address_[i]);
173 bool DeviceState::IsSimAbsent() const {
174 return technology_family_ == shill::kTechnologyFamilyGsm && !sim_present_;
177 } // namespace chromeos