network_state_handler.h 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#ifndef CHROMEOS_NETWORK_NETWORK_STATE_HANDLER_H_
6#define CHROMEOS_NETWORK_NETWORK_STATE_HANDLER_H_
7
8#include <map>
9#include <set>
10#include <string>
11#include <vector>
12
13#include "base/callback_forward.h"
14#include "base/gtest_prod_util.h"
15#include "base/memory/scoped_ptr.h"
16#include "base/memory/scoped_vector.h"
17#include "base/observer_list.h"
18#include "chromeos/chromeos_export.h"
19#include "chromeos/network/managed_state.h"
20#include "chromeos/network/network_handler.h"
21#include "chromeos/network/network_handler_callbacks.h"
22#include "chromeos/network/network_type_pattern.h"
23#include "chromeos/network/shill_property_handler.h"
24
25namespace base {
26class DictionaryValue;
27class ListValue;
28class Value;
29}
30
31namespace tracked_objects {
32class Location;
33}
34
35namespace chromeos {
36
37class DeviceState;
38class NetworkState;
39class NetworkStateHandlerObserver;
40class NetworkStateHandlerTest;
41
42// Class for tracking the list of visible networks and their properties.
43//
44// This class maps essential properties from the connection manager (Shill) for
45// each visible network. It is not used to change the properties of services or
46// devices, only global (manager) properties.
47//
48// All getters return the currently cached properties. This class is expected to
49// keep properties up to date by managing the appropriate Shill observers.
50// It will invoke its own more specific observer methods when the specified
51// changes occur.
52//
53// Some notes about NetworkState, FavoriteState, and GUIDs:
54// * A FavoriteState exists for all network services stored in a profile, and
55//   all "visible" networks (physically connected networks like ethernet and
56//   cellular or in-range wifi networks). If the network is stored in a profile,
57//   FavoriteState.IsInProfile() will return true.
58// * A NetworkState exists for "visible" networks only. There will always be a
59//   corresponding FavoriteState with the same service_path() property.
60// * All networks saved to a profile will have a saved GUID that is persistent
61//   across sessions.
62// * Networks that are not saved to a profile will have a GUID assigned when
63//   the initial properties are received. The GUID will be consistent for
64//   the duration of a session, even if the network drops out and returns.
65// * Both FavoriteState and NetworkState store the GUID. It will always be the
66//   same for the same network (i.e. entries with the same service_path()).
67
68class CHROMEOS_EXPORT NetworkStateHandler
69    : public internal::ShillPropertyHandler::Listener {
70 public:
71  typedef std::vector<ManagedState*> ManagedStateList;
72  typedef std::vector<const NetworkState*> NetworkStateList;
73  typedef std::vector<const DeviceState*> DeviceStateList;
74  typedef std::vector<const FavoriteState*> FavoriteStateList;
75
76  enum TechnologyState {
77    TECHNOLOGY_UNAVAILABLE,
78    TECHNOLOGY_AVAILABLE,
79    TECHNOLOGY_UNINITIALIZED,
80    TECHNOLOGY_ENABLING,
81    TECHNOLOGY_ENABLED
82  };
83
84  virtual ~NetworkStateHandler();
85
86  // Add/remove observers.
87  void AddObserver(NetworkStateHandlerObserver* observer,
88                   const tracked_objects::Location& from_here);
89  void RemoveObserver(NetworkStateHandlerObserver* observer,
90                      const tracked_objects::Location& from_here);
91
92  // Requests all Manager properties, specifically to update the complete
93  // list of services which determines the list of Favorites. This should be
94  // called any time a new service is configured or a Profile is loaded.
95  void UpdateManagerProperties();
96
97  // Returns the state for technology |type|. Only
98  // NetworkTypePattern::Primitive, ::Mobile and ::Ethernet are supported.
99  TechnologyState GetTechnologyState(const NetworkTypePattern& type) const;
100  bool IsTechnologyAvailable(const NetworkTypePattern& type) const {
101    return GetTechnologyState(type) != TECHNOLOGY_UNAVAILABLE;
102  }
103  bool IsTechnologyEnabled(const NetworkTypePattern& type) const {
104    return GetTechnologyState(type) == TECHNOLOGY_ENABLED;
105  }
106
107  // Asynchronously sets the technology enabled property for |type|. Only
108  // NetworkTypePattern::Primitive, ::Mobile and ::Ethernet are supported.
109  // Note: Modifies Manager state. Calls |error_callback| on failure.
110  void SetTechnologyEnabled(
111      const NetworkTypePattern& type,
112      bool enabled,
113      const network_handler::ErrorCallback& error_callback);
114
115  // Finds and returns a device state by |device_path| or NULL if not found.
116  const DeviceState* GetDeviceState(const std::string& device_path) const;
117
118  // Finds and returns a device state by |type|. Returns NULL if not found.
119  const DeviceState* GetDeviceStateByType(const NetworkTypePattern& type) const;
120
121  // Returns true if any device of |type| is scanning.
122  bool GetScanningByType(const NetworkTypePattern& type) const;
123
124  // Finds and returns a network state by |service_path| or NULL if not found.
125  // Note: NetworkState is frequently updated asynchronously, i.e. properties
126  // are not always updated all at once. This will contain the most recent
127  // value for each property. To receive notifications when a property changes,
128  // observe this class and implement NetworkPropertyChanged().
129  const NetworkState* GetNetworkState(const std::string& service_path) const;
130
131  // Returns the default network (which includes VPNs) based on the Shill
132  // Manager.DefaultNetwork property. Normally this is the same as
133  // ConnectedNetworkByType(NetworkTypePattern::Default()), but the timing might
134  // differ.
135  const NetworkState* DefaultNetwork() const;
136
137  // Returns the FavoriteState associated to DefaultNetwork. Returns NULL if,
138  // and only if, DefaultNetwork returns NULL.
139  const FavoriteState* DefaultFavoriteNetwork() const;
140
141  // Returns the primary connected network of matching |type|, otherwise NULL.
142  const NetworkState* ConnectedNetworkByType(
143      const NetworkTypePattern& type) const;
144
145  // Like ConnectedNetworkByType() but returns a connecting network or NULL.
146  const NetworkState* ConnectingNetworkByType(
147      const NetworkTypePattern& type) const;
148
149  // Like ConnectedNetworkByType() but returns any matching network or NULL.
150  // Mostly useful for mobile networks where there is generally only one
151  // network. Note: O(N).
152  const NetworkState* FirstNetworkByType(const NetworkTypePattern& type) const;
153
154  // Returns the aa:bb formatted hardware (MAC) address for the first connected
155  // network matching |type|, or an empty string if none is connected.
156  std::string FormattedHardwareAddressForType(
157      const NetworkTypePattern& type) const;
158
159  // Sets |list| to contain the list of networks.  The returned list contains
160  // a copy of NetworkState pointers which should not be stored or used beyond
161  // the scope of the calling function (i.e. they may later become invalid, but
162  // only on the UI thread).
163  void GetNetworkList(NetworkStateList* list) const;
164
165  // Like GetNetworkList() but only returns networks with matching |type|.
166  void GetNetworkListByType(const NetworkTypePattern& type,
167                            NetworkStateList* list) const;
168
169  // Sets |list| to contain the list of devices.  The returned list contains
170  // a copy of DeviceState pointers which should not be stored or used beyond
171  // the scope of the calling function (i.e. they may later become invalid, but
172  // only on the UI thread).
173  void GetDeviceList(DeviceStateList* list) const;
174
175  // Like GetDeviceList() but only returns networks with matching |type|.
176  void GetDeviceListByType(const NetworkTypePattern& type,
177                           DeviceStateList* list) const;
178
179  // Sets |list| to contain the list of favorite (aka "preferred") networks.
180  // See GetNetworkList() for usage, and notes for |favorite_list_|.
181  // Favorites that are visible have the same path() as the entries in
182  // GetNetworkList(), so GetNetworkState() can be used to determine if a
183  // favorite is visible and retrieve the complete properties (and vice-versa).
184  void GetFavoriteList(FavoriteStateList* list) const;
185
186  // Like GetFavoriteList() but only returns favorites with matching |type| and
187  // the following properties:
188  // |configured_only| - if true only include networks where IsInProfile is true
189  // |visible_only| - if true only include networks in the visible Services list
190  // |limit| - if > 0 limits the number of results.
191  void GetFavoriteListByType(const NetworkTypePattern& type,
192                             bool configured_only,
193                             bool visible_only,
194                             int limit,
195                             FavoriteStateList* list) const;
196
197  // Finds and returns the FavoriteState associated with |service_path| or NULL
198  // if not found. If |configured_only| is true, only returns saved entries
199  // (IsInProfile is true).
200  const FavoriteState* GetFavoriteStateFromServicePath(
201      const std::string& service_path,
202      bool configured_only) const;
203
204  // Finds and returns the FavoriteState associated with |guid| or NULL if not
205  // found. This returns all entries (IsInProfile() may be true or false).
206  const FavoriteState* GetFavoriteStateFromGuid(const std::string& guid) const;
207
208  // Requests a network scan. This may trigger updates to the network
209  // list, which will trigger the appropriate observer calls.
210  void RequestScan() const;
211
212  // Request a scan if not scanning and run |callback| when the Scanning state
213  // for any Device of network type |type| completes.
214  void WaitForScan(const std::string& type, const base::Closure& callback);
215
216  // Request a network scan then signal Shill to connect to the best available
217  // networks when completed.
218  void ConnectToBestWifiNetwork();
219
220  // Request an update for an existing NetworkState, e.g. after configuring
221  // a network. This is a no-op if an update request is already pending. To
222  // ensure that a change is picked up, this must be called after Shill
223  // acknowledged it (e.g. in the callback of a SetProperties).
224  // When the properties are received, NetworkPropertiesUpdated will be
225  // signaled for each member of |observers_|, regardless of whether any
226  // properties actually changed.
227  void RequestUpdateForNetwork(const std::string& service_path);
228
229  // Clear the last_error value for the NetworkState for |service_path|.
230  void ClearLastErrorForNetwork(const std::string& service_path);
231
232  // Set the list of devices on which portal check is enabled.
233  void SetCheckPortalList(const std::string& check_portal_list);
234
235  const std::string& GetCheckPortalListForTest() const {
236    return check_portal_list_;
237  }
238
239  // Returns the FavoriteState of the EthernetEAP service, which contains the
240  // EAP parameters used by the ethernet with |service_path|. If |service_path|
241  // doesn't refer to an ethernet service or if the ethernet service is not
242  // connected using EAP, returns NULL.
243  const FavoriteState* GetEAPForEthernet(const std::string& service_path) const;
244
245  // Construct and initialize an instance for testing.
246  static NetworkStateHandler* InitializeForTest();
247
248  // Default set of comma separated interfaces on which to enable
249  // portal checking.
250  static const char kDefaultCheckPortalList[];
251
252 protected:
253  friend class NetworkHandler;
254  NetworkStateHandler();
255
256  // ShillPropertyHandler::Listener overrides.
257
258  // This adds new entries to the managed list specified by |type| and deletes
259  // any entries that are no longer in the list.
260  virtual void UpdateManagedList(ManagedState::ManagedType type,
261                                 const base::ListValue& entries) OVERRIDE;
262
263  // The list of profiles changed (i.e. a user has logged in). Re-request
264  // properties for all services since they may have changed.
265  virtual void ProfileListChanged() OVERRIDE;
266
267  // Parses the properties for the network service or device. Mostly calls
268  // managed->PropertyChanged(key, value) for each dictionary entry.
269  virtual void UpdateManagedStateProperties(
270      ManagedState::ManagedType type,
271      const std::string& path,
272      const base::DictionaryValue& properties) OVERRIDE;
273
274  // Called by ShillPropertyHandler when a watched service property changes.
275  virtual void UpdateNetworkServiceProperty(
276      const std::string& service_path,
277      const std::string& key,
278      const base::Value& value) OVERRIDE;
279
280  // Called by ShillPropertyHandler when a watched device property changes.
281  virtual void UpdateDeviceProperty(
282      const std::string& device_path,
283      const std::string& key,
284      const base::Value& value) OVERRIDE;
285
286  // Called by ShillPropertyHandler when a watched network or device
287  // IPConfig property changes.
288  virtual void UpdateIPConfigProperties(
289      ManagedState::ManagedType type,
290      const std::string& path,
291      const std::string& ip_config_path,
292      const base::DictionaryValue& properties) OVERRIDE;
293
294  // Called by ShillPropertyHandler when the portal check list manager property
295  // changes.
296  virtual void CheckPortalListChanged(
297      const std::string& check_portal_list) OVERRIDE;
298
299  // Called by ShillPropertyHandler when a technology list changes.
300  virtual void TechnologyListChanged() OVERRIDE;
301
302  // Called by |shill_property_handler_| when the service or device list has
303  // changed and all entries have been updated. This updates the list and
304  // notifies observers. If |type| == TYPE_NETWORK this also calls
305  // CheckDefaultNetworkChanged().
306  virtual void ManagedStateListChanged(
307      ManagedState::ManagedType type) OVERRIDE;
308
309  // Called when the default network service changes. Sets default_network_path_
310  // and notifies listeners.
311  virtual void DefaultNetworkServiceChanged(
312      const std::string& service_path) OVERRIDE;
313
314  // Called after construction. Called explicitly by tests after adding
315  // test observers.
316  void InitShillPropertyHandler();
317
318 private:
319  typedef std::list<base::Closure> ScanCallbackList;
320  typedef std::map<std::string, ScanCallbackList> ScanCompleteCallbackMap;
321  typedef std::map<std::string, std::string> SpecifierGuidMap;
322  friend class NetworkStateHandlerTest;
323  FRIEND_TEST_ALL_PREFIXES(NetworkStateHandlerTest, NetworkStateHandlerStub);
324
325  // NetworkState specific method for UpdateManagedStateProperties which
326  // notifies observers.
327  void UpdateNetworkStateProperties(NetworkState* network,
328                                    const base::DictionaryValue& properties);
329
330  // Ensure a valid GUID for FavoriteState and update the NetworkState GUID from
331  // the corresponding FavoriteState if necessary.
332  void UpdateGuid(ManagedState* managed);
333
334  // Sends DeviceListChanged() to observers and logs an event.
335  void NotifyDeviceListChanged();
336
337  // Non-const getters for managed entries. These are const so that they can
338  // be called by Get[Network|Device]State, even though they return non-const
339  // pointers.
340  DeviceState* GetModifiableDeviceState(const std::string& device_path) const;
341  NetworkState* GetModifiableNetworkState(
342      const std::string& service_path) const;
343  FavoriteState* GetModifiableFavoriteState(
344      const std::string& service_path) const;
345  ManagedState* GetModifiableManagedState(const ManagedStateList* managed_list,
346                                          const std::string& path) const;
347
348  // Gets the list specified by |type|.
349  ManagedStateList* GetManagedList(ManagedState::ManagedType type);
350
351  // Helper function to notify observers. Calls CheckDefaultNetworkChanged().
352  void OnNetworkConnectionStateChanged(NetworkState* network);
353
354  // Notifies observers when the default network or its properties change.
355  void NotifyDefaultNetworkChanged(const NetworkState* default_network);
356
357  // Notifies observers about changes to |network|.
358  void NotifyNetworkPropertiesUpdated(const NetworkState* network);
359
360  // Called whenever Device.Scanning state transitions to false.
361  void ScanCompleted(const std::string& type);
362
363  // Returns one technology type for |type|. This technology will be the
364  // highest priority technology in the type pattern.
365  std::string GetTechnologyForType(const NetworkTypePattern& type) const;
366
367  // Returns all the technology types for |type|.
368  ScopedVector<std::string> GetTechnologiesForType(
369      const NetworkTypePattern& type) const;
370
371  // Shill property handler instance, owned by this class.
372  scoped_ptr<internal::ShillPropertyHandler> shill_property_handler_;
373
374  // Observer list
375  ObserverList<NetworkStateHandlerObserver> observers_;
376
377  // List of managed network states
378  ManagedStateList network_list_;
379
380  // List of managed favorite states; this list includes all entries in
381  // Manager.ServiceCompleteList, but only entries with a non-empty Profile
382  // property are returned in GetFavoriteList().
383  ManagedStateList favorite_list_;
384
385  // List of managed device states
386  ManagedStateList device_list_;
387
388  // Keeps track of the default network for notifying observers when it changes.
389  std::string default_network_path_;
390
391  // List of interfaces on which portal check is enabled.
392  std::string check_portal_list_;
393
394  // Callbacks to run when a scan for the technology type completes.
395  ScanCompleteCallbackMap scan_complete_callbacks_;
396
397  // Map of network specifiers to guids. Contains an entry for each
398  // FavoriteState that is not saved in a profile.
399  SpecifierGuidMap specifier_guid_map_;
400
401  DISALLOW_COPY_AND_ASSIGN(NetworkStateHandler);
402};
403
404}  // namespace chromeos
405
406#endif  // CHROMEOS_NETWORK_NETWORK_STATE_HANDLER_H_
407