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 "chromeos/network/device_state.h"
6
7 #include "base/logging.h"
8 #include "base/metrics/histogram.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/values.h"
11 #include "third_party/cros_system_api/dbus/service_constants.h"
12
13 namespace chromeos {
14
DeviceState(const std::string & path)15 DeviceState::DeviceState(const std::string& path)
16 : ManagedState(MANAGED_TYPE_DEVICE, path),
17 provider_requires_roaming_(false),
18 support_network_scan_(false),
19 scanning_(false),
20 sim_lock_enabled_(false),
21 sim_present_(true),
22 eap_authentication_completed_(false) {
23 }
24
~DeviceState()25 DeviceState::~DeviceState() {
26 }
27
PropertyChanged(const std::string & key,const base::Value & value)28 bool DeviceState::PropertyChanged(const std::string& key,
29 const base::Value& value) {
30 // All property values get stored in |properties_|.
31 properties_.SetWithoutPathExpansion(key, value.DeepCopy());
32
33 if (ManagedStatePropertyChanged(key, value))
34 return true;
35 if (key == shill::kAddressProperty) {
36 return GetStringValue(key, value, &mac_address_);
37 } else if (key == shill::kScanningProperty) {
38 return GetBooleanValue(key, value, &scanning_);
39 } else if (key == shill::kSupportNetworkScanProperty) {
40 return GetBooleanValue(key, value, &support_network_scan_);
41 } else if (key == shill::kProviderRequiresRoamingProperty) {
42 return GetBooleanValue(key, value, &provider_requires_roaming_);
43 } else if (key == shill::kHomeProviderProperty) {
44 const base::DictionaryValue* dict = NULL;
45 if (!value.GetAsDictionary(&dict))
46 return false;
47 std::string home_provider_country;
48 std::string home_provider_name;
49 dict->GetStringWithoutPathExpansion(shill::kOperatorCountryKey,
50 &home_provider_country);
51 dict->GetStringWithoutPathExpansion(shill::kOperatorNameKey,
52 &home_provider_name);
53 // Set home_provider_id_
54 if (!home_provider_name.empty() && !home_provider_country.empty()) {
55 home_provider_id_ = base::StringPrintf(
56 "%s (%s)",
57 home_provider_name.c_str(),
58 home_provider_country.c_str());
59 } else {
60 dict->GetStringWithoutPathExpansion(shill::kOperatorCodeKey,
61 &home_provider_id_);
62 LOG(WARNING) << "Carrier ID not defined, using code instead: "
63 << home_provider_id_;
64 }
65 return true;
66 } else if (key == shill::kTechnologyFamilyProperty) {
67 return GetStringValue(key, value, &technology_family_);
68 } else if (key == shill::kCarrierProperty) {
69 return GetStringValue(key, value, &carrier_);
70 } else if (key == shill::kFoundNetworksProperty) {
71 const base::ListValue* list = NULL;
72 if (!value.GetAsList(&list))
73 return false;
74 CellularScanResults parsed_results;
75 if (!network_util::ParseCellularScanResults(*list, &parsed_results))
76 return false;
77 scan_results_.swap(parsed_results);
78 return true;
79 } else if (key == shill::kSIMLockStatusProperty) {
80 const base::DictionaryValue* dict = NULL;
81 if (!value.GetAsDictionary(&dict))
82 return false;
83
84 // Return true if at least one of the property values changed.
85 bool property_changed = false;
86 const base::Value* out_value = NULL;
87 if (!dict->GetWithoutPathExpansion(shill::kSIMLockRetriesLeftProperty,
88 &out_value))
89 return false;
90 if (GetUInt32Value(shill::kSIMLockRetriesLeftProperty,
91 *out_value, &sim_retries_left_))
92 property_changed = true;
93
94 if (!dict->GetWithoutPathExpansion(shill::kSIMLockTypeProperty,
95 &out_value))
96 return false;
97 if (GetStringValue(shill::kSIMLockTypeProperty,
98 *out_value, &sim_lock_type_))
99 property_changed = true;
100
101 if (!dict->GetWithoutPathExpansion(shill::kSIMLockEnabledProperty,
102 &out_value))
103 return false;
104 if (GetBooleanValue(shill::kSIMLockEnabledProperty,
105 *out_value, &sim_lock_enabled_))
106 property_changed = true;
107
108 return property_changed;
109 } else if (key == shill::kMeidProperty) {
110 return GetStringValue(key, value, &meid_);
111 } else if (key == shill::kImeiProperty) {
112 return GetStringValue(key, value, &imei_);
113 } else if (key == shill::kIccidProperty) {
114 return GetStringValue(key, value, &iccid_);
115 } else if (key == shill::kMdnProperty) {
116 return GetStringValue(key, value, &mdn_);
117 } else if (key == shill::kSIMPresentProperty) {
118 return GetBooleanValue(key, value, &sim_present_);
119 } else if (key == shill::kEapAuthenticationCompletedProperty) {
120 return GetBooleanValue(key, value, &eap_authentication_completed_);
121 }
122 return false;
123 }
124
InitialPropertiesReceived(const base::DictionaryValue & properties)125 bool DeviceState::InitialPropertiesReceived(
126 const base::DictionaryValue& properties) {
127 // Update UMA stats.
128 if (sim_present_) {
129 bool locked = !sim_lock_type_.empty();
130 UMA_HISTOGRAM_BOOLEAN("Cellular.SIMLocked", locked);
131 }
132 return false;
133 }
134
GetFormattedMacAddress() const135 std::string DeviceState::GetFormattedMacAddress() const {
136 if (mac_address_.size() % 2 != 0)
137 return mac_address_;
138 std::string result;
139 for (size_t i = 0; i < mac_address_.size(); ++i) {
140 if ((i != 0) && (i % 2 == 0))
141 result.push_back(':');
142 result.push_back(mac_address_[i]);
143 }
144 return result;
145 }
146
IsSimAbsent() const147 bool DeviceState::IsSimAbsent() const {
148 return technology_family_ == shill::kTechnologyFamilyGsm && !sim_present_;
149 }
150
151 } // namespace chromeos
152