device_state.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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}
23
24DeviceState::~DeviceState() {
25}
26
27bool DeviceState::PropertyChanged(const std::string& key,
28                                  const base::Value& value) {
29  // All property values get stored in |properties_|.
30  properties_.SetWithoutPathExpansion(key, value.DeepCopy());
31
32  if (ManagedStatePropertyChanged(key, value))
33    return true;
34  if (key == shill::kAddressProperty) {
35    return GetStringValue(key, value, &mac_address_);
36  } else if (key == shill::kScanningProperty) {
37    return GetBooleanValue(key, value, &scanning_);
38  } else if (key == shill::kSupportNetworkScanProperty) {
39    return GetBooleanValue(key, value, &support_network_scan_);
40  } else if (key == shill::kProviderRequiresRoamingProperty) {
41    return GetBooleanValue(key, value, &provider_requires_roaming_);
42  } else if (key == shill::kHomeProviderProperty) {
43    const base::DictionaryValue* dict = NULL;
44    if (!value.GetAsDictionary(&dict))
45      return false;
46    std::string home_provider_country;
47    std::string home_provider_name;
48    dict->GetStringWithoutPathExpansion(shill::kOperatorCountryKey,
49                                        &home_provider_country);
50    dict->GetStringWithoutPathExpansion(shill::kOperatorNameKey,
51                                        &home_provider_name);
52    // Set home_provider_id_
53    if (!home_provider_name.empty() && !home_provider_country.empty()) {
54      home_provider_id_ = base::StringPrintf(
55          "%s (%s)",
56          home_provider_name.c_str(),
57          home_provider_country.c_str());
58    } else {
59      dict->GetStringWithoutPathExpansion(shill::kOperatorCodeKey,
60                                          &home_provider_id_);
61      LOG(WARNING) << "Carrier ID not defined, using code instead: "
62                   << home_provider_id_;
63    }
64    return true;
65  } else if (key == shill::kTechnologyFamilyProperty) {
66    return GetStringValue(key, value, &technology_family_);
67  } else if (key == shill::kCarrierProperty) {
68    return GetStringValue(key, value, &carrier_);
69  } else if (key == shill::kFoundNetworksProperty) {
70    const base::ListValue* list = NULL;
71    if (!value.GetAsList(&list))
72      return false;
73    CellularScanResults parsed_results;
74    if (!network_util::ParseCellularScanResults(*list, &parsed_results))
75      return false;
76    scan_results_.swap(parsed_results);
77    return true;
78  } else if (key == shill::kSIMLockStatusProperty) {
79    const base::DictionaryValue* dict = NULL;
80    if (!value.GetAsDictionary(&dict))
81      return false;
82
83    // Return true if at least one of the property values changed.
84    bool property_changed = false;
85    const base::Value* out_value = NULL;
86    if (!dict->GetWithoutPathExpansion(shill::kSIMLockRetriesLeftProperty,
87                                       &out_value))
88      return false;
89    if (GetUInt32Value(shill::kSIMLockRetriesLeftProperty,
90                       *out_value, &sim_retries_left_))
91      property_changed = true;
92
93    if (!dict->GetWithoutPathExpansion(shill::kSIMLockTypeProperty,
94                                       &out_value))
95      return false;
96    if (GetStringValue(shill::kSIMLockTypeProperty,
97                       *out_value, &sim_lock_type_))
98      property_changed = true;
99
100    if (!dict->GetWithoutPathExpansion(shill::kSIMLockEnabledProperty,
101                                       &out_value))
102      return false;
103    if (GetBooleanValue(shill::kSIMLockEnabledProperty,
104                        *out_value, &sim_lock_enabled_))
105      property_changed = true;
106
107    return property_changed;
108  } else if (key == shill::kMeidProperty) {
109    return GetStringValue(key, value, &meid_);
110  } else if (key == shill::kImeiProperty) {
111    return GetStringValue(key, value, &imei_);
112  } else if (key == shill::kIccidProperty) {
113    return GetStringValue(key, value, &iccid_);
114  } else if (key == shill::kMdnProperty) {
115    return GetStringValue(key, value, &mdn_);
116  } else if (key == shill::kSIMPresentProperty) {
117    return GetBooleanValue(key, value, &sim_present_);
118  }
119  return false;
120}
121
122bool DeviceState::InitialPropertiesReceived(
123    const base::DictionaryValue& properties) {
124  // Update UMA stats.
125  if (sim_present_) {
126    bool locked = !sim_lock_type_.empty();
127    UMA_HISTOGRAM_BOOLEAN("Cellular.SIMLocked", locked);
128  }
129  return false;
130}
131
132bool DeviceState::IsSimAbsent() const {
133  return technology_family_ == shill::kTechnologyFamilyGsm && !sim_present_;
134}
135
136}  // namespace chromeos
137