device_state.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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
13namespace chromeos {
14
15DeviceState::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
25DeviceState::~DeviceState() {
26}
27
28bool 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
125bool 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
135std::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
147bool DeviceState::IsSimAbsent() const {
148  return technology_family_ == shill::kTechnologyFamilyGsm && !sim_present_;
149}
150
151}  // namespace chromeos
152