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 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 25 DeviceState::~DeviceState() { 26 } 27 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 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 135 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 147 bool DeviceState::IsSimAbsent() const { 148 return technology_family_ == shill::kTechnologyFamilyGsm && !sim_present_; 149 } 150 151 } // namespace chromeos 152