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_SHILL_PROPERTY_HANDLER_H_
6#define CHROMEOS_NETWORK_SHILL_PROPERTY_HANDLER_H_
7
8#include <list>
9#include <map>
10#include <set>
11#include <string>
12
13#include "base/memory/weak_ptr.h"
14#include "chromeos/dbus/dbus_method_call_status.h"
15#include "chromeos/dbus/shill_property_changed_observer.h"
16#include "chromeos/network/managed_state.h"
17#include "chromeos/network/network_handler_callbacks.h"
18
19namespace base {
20class DictionaryValue;
21class ListValue;
22class Value;
23}
24
25namespace chromeos {
26
27class ShillManagerClient;
28
29namespace internal {
30
31class ShillPropertyObserver;
32
33// This class handles Shill calls and observers to reflect the state of the
34// Shill Manager and its services and devices. It observes Shill.Manager and
35// requests properties for new devices/networks. It takes a Listener in its
36// constructor (e.g. NetworkStateHandler) that it calls when properties change
37// (including once to set their initial state after Init() gets called).
38// It also observes Shill.Service for all services in Manager.ServiceWatchList.
39// This class must not outlive the ShillManagerClient instance.
40class CHROMEOS_EXPORT ShillPropertyHandler
41    : public ShillPropertyChangedObserver,
42      public base::SupportsWeakPtr<ShillPropertyHandler> {
43 public:
44  typedef std::map<std::string, ShillPropertyObserver*>
45      ShillPropertyObserverMap;
46
47  class CHROMEOS_EXPORT Listener {
48   public:
49    // Called when the entries in a managed list have changed.
50    virtual void UpdateManagedList(ManagedState::ManagedType type,
51                                   const base::ListValue& entries) = 0;
52
53    // Called when the properties for a managed state have changed.
54    virtual void UpdateManagedStateProperties(
55        ManagedState::ManagedType type,
56        const std::string& path,
57        const base::DictionaryValue& properties) = 0;
58
59    // Called when the list of profiles changes.
60    virtual void ProfileListChanged() = 0;
61
62    // Called when a property for a watched network service has changed.
63    virtual void UpdateNetworkServiceProperty(
64        const std::string& service_path,
65        const std::string& key,
66        const base::Value& value) = 0;
67
68    // Called when a property for a watched device has changed.
69    virtual void UpdateDeviceProperty(
70        const std::string& device_path,
71        const std::string& key,
72        const base::Value& value) = 0;
73
74    // Called when a watched network or device IPConfig property changes.
75    virtual void UpdateIPConfigProperties(
76        ManagedState::ManagedType type,
77        const std::string& path,
78        const std::string& ip_config_path,
79        const base::DictionaryValue& properties) = 0;
80
81    // Called when the list of devices with portal check enabled changes.
82    virtual void CheckPortalListChanged(
83         const std::string& check_portal_list) = 0;
84
85    // Called when a technology list changes.
86    virtual void TechnologyListChanged() = 0;
87
88    // Called when a managed state list has changed, after properties for any
89    // new entries in the list have been received and
90    // UpdateManagedStateProperties has been called for each new entry.
91    virtual void ManagedStateListChanged(ManagedState::ManagedType type) = 0;
92
93    // Called when the default network service changes.
94    virtual void DefaultNetworkServiceChanged(
95        const std::string& service_path) = 0;
96
97   protected:
98    virtual ~Listener() {}
99  };
100
101  explicit ShillPropertyHandler(Listener* listener);
102  virtual ~ShillPropertyHandler();
103
104  // Sets up the observer and calls UpdateManagerProperties().
105  void Init();
106
107  // Requests all Manager properties. Called from Init() and any time
108  // properties that do not signal changes might have been updated (e.g.
109  // ServiceCompleteList).
110  void UpdateManagerProperties();
111
112  // Returns true if |technology| is available, enabled, etc.
113  bool IsTechnologyAvailable(const std::string& technology) const;
114  bool IsTechnologyEnabled(const std::string& technology) const;
115  bool IsTechnologyEnabling(const std::string& technology) const;
116  bool IsTechnologyUninitialized(const std::string& technology) const;
117
118  // Asynchronously sets the enabled state for |technology|.
119  // Note: Modifies Manager state. Calls |error_callback| on failure.
120  void SetTechnologyEnabled(
121      const std::string& technology,
122      bool enabled,
123      const network_handler::ErrorCallback& error_callback);
124
125  // Sets the list of devices on which portal check is enabled.
126  void SetCheckPortalList(const std::string& check_portal_list);
127
128  // Requests an immediate network scan.
129  void RequestScan() const;
130
131  // Calls Manager.ConnectToBestServices().
132  void ConnectToBestServices() const;
133
134  // Requests all properties for the service or device (called for new items).
135  void RequestProperties(ManagedState::ManagedType type,
136                         const std::string& path);
137
138  // ShillPropertyChangedObserver overrides
139  virtual void OnPropertyChanged(const std::string& key,
140                                 const base::Value& value) OVERRIDE;
141
142 private:
143  typedef std::map<ManagedState::ManagedType, std::set<std::string> >
144      TypeRequestMap;
145
146  // Callback for dbus method fetching properties.
147  void ManagerPropertiesCallback(DBusMethodCallStatus call_status,
148                                 const base::DictionaryValue& properties);
149
150  // Notifies the listener when a ManagedStateList has changed and all pending
151  // updates have been received. |key| can either identify the list that
152  // has changed or an empty string if multiple lists may have changed.
153  void CheckPendingStateListUpdates(const std::string& key);
154
155  // Called form OnPropertyChanged() and ManagerPropertiesCallback().
156  void ManagerPropertyChanged(const std::string& key,
157                              const base::Value& value);
158
159  // Requests properties for new entries in the list for |type|.
160  void UpdateProperties(ManagedState::ManagedType type,
161                        const base::ListValue& entries);
162
163  // Updates the Shill property observers to observe any entries for |type|.
164  void UpdateObserved(ManagedState::ManagedType type,
165                      const base::ListValue& entries);
166
167
168  // Sets |*_technologies_| to contain only entries in |technologies|.
169  void UpdateAvailableTechnologies(const base::ListValue& technologies);
170  void UpdateEnabledTechnologies(const base::ListValue& technologies);
171  void UpdateUninitializedTechnologies(const base::ListValue& technologies);
172
173  void EnableTechnologyFailed(
174      const std::string& technology,
175      const network_handler::ErrorCallback& error_callback,
176      const std::string& dbus_error_name,
177      const std::string& dbus_error_message);
178
179  // Called when Shill returns the properties for a service or device.
180  void GetPropertiesCallback(ManagedState::ManagedType type,
181                             const std::string& path,
182                             DBusMethodCallStatus call_status,
183                             const base::DictionaryValue& properties);
184
185  // Callback invoked when a watched property changes. Calls appropriate
186  // handlers and signals observers.
187  void PropertyChangedCallback(ManagedState::ManagedType type,
188                               const std::string& path,
189                               const std::string& key,
190                               const base::Value& value);
191
192  // Request a single IPConfig object corresponding to |ip_config_path_value|
193  // from Shill.IPConfigClient and trigger a call to UpdateIPConfigProperties
194  // for the network or device corresponding to |type| and |path|.
195  void RequestIPConfig(ManagedState::ManagedType type,
196                       const std::string& path,
197                       const base::Value& ip_config_path_value);
198
199  // Request the IPConfig objects corresponding to entries in
200  // |ip_config_list_value| from Shill.IPConfigClient and trigger a call to
201  // UpdateIPConfigProperties with each object for the network or device
202  // corresponding to |type| and |path|.
203  void RequestIPConfigsList(ManagedState::ManagedType type,
204                            const std::string& path,
205                            const base::Value& ip_config_list_value);
206
207  // Callback for getting the IPConfig property of a network or device. Handled
208  // here instead of in NetworkState so that all asynchronous requests are done
209  // in a single place (also simplifies NetworkState considerably).
210  void GetIPConfigCallback(ManagedState::ManagedType type,
211                           const std::string& path,
212                           const std::string& ip_config_path,
213                           DBusMethodCallStatus call_status,
214                           const base::DictionaryValue& properties);
215
216  // Pointer to containing class (owns this)
217  Listener* listener_;
218
219  // Convenience pointer for ShillManagerClient
220  ShillManagerClient* shill_manager_;
221
222  // Pending update list for each managed state type
223  TypeRequestMap pending_updates_;
224
225  // List of states for which properties have been requested, for each managed
226  // state type
227  TypeRequestMap requested_updates_;
228
229  // List of network services with Shill property changed observers
230  ShillPropertyObserverMap observed_networks_;
231
232  // List of network devices with Shill property changed observers
233  ShillPropertyObserverMap observed_devices_;
234
235  // Lists of available / enabled / uninitialized technologies
236  std::set<std::string> available_technologies_;
237  std::set<std::string> enabled_technologies_;
238  std::set<std::string> enabling_technologies_;
239  std::set<std::string> uninitialized_technologies_;
240
241  DISALLOW_COPY_AND_ASSIGN(ShillPropertyHandler);
242};
243
244}  // namespace internal
245}  // namespace chromeos
246
247#endif  // CHROMEOS_NETWORK_SHILL_PROPERTY_HANDLER_H_
248