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 "chromeos/network/network_event_log.h" 12 #include "chromeos/network/shill_property_util.h" 13 #include "third_party/cros_system_api/dbus/service_constants.h" 14 15 namespace chromeos { 16 17 DeviceState::DeviceState(const std::string& path) 18 : ManagedState(MANAGED_TYPE_DEVICE, path), 19 allow_roaming_(false), 20 provider_requires_roaming_(false), 21 support_network_scan_(false), 22 scanning_(false), 23 sim_retries_left_(0), 24 sim_lock_enabled_(false), 25 sim_present_(true), 26 eap_authentication_completed_(false) { 27 } 28 29 DeviceState::~DeviceState() { 30 } 31 32 bool DeviceState::PropertyChanged(const std::string& key, 33 const base::Value& value) { 34 // All property values get stored in |properties_|. 35 properties_.SetWithoutPathExpansion(key, value.DeepCopy()); 36 37 if (ManagedStatePropertyChanged(key, value)) 38 return true; 39 if (key == shill::kAddressProperty) { 40 return GetStringValue(key, value, &mac_address_); 41 } else if (key == shill::kScanningProperty) { 42 return GetBooleanValue(key, value, &scanning_); 43 } else if (key == shill::kSupportNetworkScanProperty) { 44 return GetBooleanValue(key, value, &support_network_scan_); 45 } else if (key == shill::kCellularAllowRoamingProperty) { 46 return GetBooleanValue(key, value, &allow_roaming_); 47 } else if (key == shill::kProviderRequiresRoamingProperty) { 48 return GetBooleanValue(key, value, &provider_requires_roaming_); 49 } else if (key == shill::kHomeProviderProperty) { 50 return shill_property_util::GetHomeProviderFromProperty( 51 value, &home_provider_id_); 52 } else if (key == shill::kTechnologyFamilyProperty) { 53 return GetStringValue(key, value, &technology_family_); 54 } else if (key == shill::kCarrierProperty) { 55 return GetStringValue(key, value, &carrier_); 56 } else if (key == shill::kFoundNetworksProperty) { 57 const base::ListValue* list = NULL; 58 if (!value.GetAsList(&list)) 59 return false; 60 CellularScanResults parsed_results; 61 if (!network_util::ParseCellularScanResults(*list, &parsed_results)) 62 return false; 63 scan_results_.swap(parsed_results); 64 return true; 65 } else if (key == shill::kSIMLockStatusProperty) { 66 const base::DictionaryValue* dict = NULL; 67 if (!value.GetAsDictionary(&dict)) 68 return false; 69 70 // Return true if at least one of the property values changed. 71 bool property_changed = false; 72 const base::Value* out_value = NULL; 73 if (!dict->GetWithoutPathExpansion(shill::kSIMLockRetriesLeftProperty, 74 &out_value)) 75 return false; 76 if (GetUInt32Value(shill::kSIMLockRetriesLeftProperty, 77 *out_value, &sim_retries_left_)) 78 property_changed = true; 79 80 if (!dict->GetWithoutPathExpansion(shill::kSIMLockTypeProperty, 81 &out_value)) 82 return false; 83 if (GetStringValue(shill::kSIMLockTypeProperty, 84 *out_value, &sim_lock_type_)) 85 property_changed = true; 86 87 if (!dict->GetWithoutPathExpansion(shill::kSIMLockEnabledProperty, 88 &out_value)) 89 return false; 90 if (GetBooleanValue(shill::kSIMLockEnabledProperty, 91 *out_value, &sim_lock_enabled_)) 92 property_changed = true; 93 94 return property_changed; 95 } else if (key == shill::kMeidProperty) { 96 return GetStringValue(key, value, &meid_); 97 } else if (key == shill::kImeiProperty) { 98 return GetStringValue(key, value, &imei_); 99 } else if (key == shill::kIccidProperty) { 100 return GetStringValue(key, value, &iccid_); 101 } else if (key == shill::kMdnProperty) { 102 return GetStringValue(key, value, &mdn_); 103 } else if (key == shill::kSIMPresentProperty) { 104 return GetBooleanValue(key, value, &sim_present_); 105 } else if (key == shill::kEapAuthenticationCompletedProperty) { 106 return GetBooleanValue(key, value, &eap_authentication_completed_); 107 } else if (key == shill::kIPConfigsProperty) { 108 // If kIPConfigsProperty changes, clear any previous ip_configs_. 109 // ShillPropertyhandler will request the IPConfig objects which will trigger 110 // calls to IPConfigPropertiesChanged. 111 ip_configs_.Clear(); 112 return false; // No actual state change. 113 } 114 return false; 115 } 116 117 bool DeviceState::InitialPropertiesReceived( 118 const base::DictionaryValue& properties) { 119 // Update UMA stats. 120 if (sim_present_) { 121 bool locked = !sim_lock_type_.empty(); 122 UMA_HISTOGRAM_BOOLEAN("Cellular.SIMLocked", locked); 123 } 124 return false; 125 } 126 127 void DeviceState::IPConfigPropertiesChanged( 128 const std::string& ip_config_path, 129 const base::DictionaryValue& properties) { 130 base::DictionaryValue* ip_config = NULL; 131 if (ip_configs_.GetDictionaryWithoutPathExpansion( 132 ip_config_path, &ip_config)) { 133 NET_LOG_EVENT("IPConfig Updated: " + ip_config_path, path()); 134 ip_config->Clear(); 135 } else { 136 NET_LOG_EVENT("IPConfig Added: " + ip_config_path, path()); 137 ip_config = new base::DictionaryValue; 138 ip_configs_.SetWithoutPathExpansion(ip_config_path, ip_config); 139 } 140 ip_config->MergeDictionary(&properties); 141 } 142 143 bool DeviceState::IsSimAbsent() const { 144 return technology_family_ == shill::kTechnologyFamilyGsm && !sim_present_; 145 } 146 147 } // namespace chromeos 148