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