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_DBUS_SHILL_CLIENT_HELPER_H_
6#define CHROMEOS_DBUS_SHILL_CLIENT_HELPER_H_
7
8#include <string>
9
10#include "base/basictypes.h"
11#include "base/callback.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/memory/weak_ptr.h"
14#include "base/observer_list.h"
15#include "base/values.h"
16#include "chromeos/dbus/dbus_method_call_status.h"
17#include "chromeos/dbus/shill_property_changed_observer.h"
18
19namespace base {
20
21class Value;
22class DictionaryValue;
23
24}  // namespace base
25
26namespace dbus {
27
28class Bus;
29class ErrorResponse;
30class MessageWriter;
31class MethodCall;
32class ObjectPath;
33class ObjectProxy;
34class Response;
35class Signal;
36
37}  // namespace dbus
38
39namespace chromeos {
40
41// A class to help implement Shill clients.
42class ShillClientHelper {
43 public:
44  class RefHolder;
45
46  // A callback to handle PropertyChanged signals.
47  typedef base::Callback<void(const std::string& name,
48                              const base::Value& value)> PropertyChangedHandler;
49
50  // A callback to handle responses for methods with DictionaryValue results.
51  typedef base::Callback<void(
52      DBusMethodCallStatus call_status,
53      const base::DictionaryValue& result)> DictionaryValueCallback;
54
55  // A callback to handle responses for methods with DictionaryValue results.
56  // This is used by CallDictionaryValueMethodWithErrorCallback.
57  typedef base::Callback<void(const base::DictionaryValue& result)>
58      DictionaryValueCallbackWithoutStatus;
59
60  // A callback to handle responses of methods returning a ListValue.
61  typedef base::Callback<void(const base::ListValue& result)> ListValueCallback;
62
63  // A callback to handle errors for method call.
64  typedef base::Callback<void(const std::string& error_name,
65                              const std::string& error_message)> ErrorCallback;
66
67  // A callback that handles responses for methods with string results.
68  typedef base::Callback<void(const std::string& result)> StringCallback;
69
70  // A callback that handles responses for methods with boolean results.
71  typedef base::Callback<void(bool result)> BooleanCallback;
72
73  // Callback used to notify owner when this can be safely released.
74  typedef base::Callback<void(ShillClientHelper* helper)> ReleasedCallback;
75
76  explicit ShillClientHelper(dbus::ObjectProxy* proxy);
77
78  virtual ~ShillClientHelper();
79
80  // Sets |released_callback_|. This is optional and should only be called at
81  // most once.
82  void SetReleasedCallback(ReleasedCallback callback);
83
84  // Adds an |observer| of the PropertyChanged signal.
85  void AddPropertyChangedObserver(ShillPropertyChangedObserver* observer);
86
87  // Removes an |observer| of the PropertyChanged signal.
88  void RemovePropertyChangedObserver(ShillPropertyChangedObserver* observer);
89
90  // Starts monitoring PropertyChanged signal. If there aren't observers for the
91  // PropertyChanged signal, the actual monitoring will be delayed until the
92  // first observer is added.
93  void MonitorPropertyChanged(const std::string& interface_name);
94
95  // Calls a method without results.
96  void CallVoidMethod(dbus::MethodCall* method_call,
97                      const VoidDBusMethodCallback& callback);
98
99  // Calls a method with an object path result.
100  void CallObjectPathMethod(dbus::MethodCall* method_call,
101                            const ObjectPathDBusMethodCallback& callback);
102
103  // Calls a method with an object path result where there is an error callback.
104  void CallObjectPathMethodWithErrorCallback(
105      dbus::MethodCall* method_call,
106      const ObjectPathCallback& callback,
107      const ErrorCallback& error_callback);
108
109  // Calls a method with a dictionary value result.
110  void CallDictionaryValueMethod(dbus::MethodCall* method_call,
111                                 const DictionaryValueCallback& callback);
112
113  // Calls a method without results with error callback.
114  void CallVoidMethodWithErrorCallback(dbus::MethodCall* method_call,
115                                       const base::Closure& callback,
116                                       const ErrorCallback& error_callback);
117
118  // Calls a method with a boolean result with error callback.
119  void CallBooleanMethodWithErrorCallback(
120      dbus::MethodCall* method_call,
121      const BooleanCallback& callback,
122      const ErrorCallback& error_callback);
123
124  // Calls a method with a string result with error callback.
125  void CallStringMethodWithErrorCallback(dbus::MethodCall* method_call,
126                                         const StringCallback& callback,
127                                         const ErrorCallback& error_callback);
128
129
130  // Calls a method with a dictionary value result with error callback.
131  void CallDictionaryValueMethodWithErrorCallback(
132      dbus::MethodCall* method_call,
133      const DictionaryValueCallbackWithoutStatus& callback,
134      const ErrorCallback& error_callback);
135
136  // Calls a method with a boolean array result with error callback.
137  void CallListValueMethodWithErrorCallback(
138      dbus::MethodCall* method_call,
139      const ListValueCallback& callback,
140      const ErrorCallback& error_callback);
141
142  const dbus::ObjectProxy* object_proxy() const { return proxy_; }
143
144  // Appends the value (basic types and string-to-string dictionary) to the
145  // writer as a variant.
146  static void AppendValueDataAsVariant(dbus::MessageWriter* writer,
147                                       const base::Value& value);
148
149  // Appends a string-to-variant dictionary to the writer.
150  static void AppendServicePropertiesDictionary(
151      dbus::MessageWriter* writer,
152      const base::DictionaryValue& dictionary);
153
154 protected:
155  // Reference / Ownership management. If the number of active refs (observers
156  // + in-progress method calls) becomes 0, |released_callback_| (if set) will
157  // be called.
158  void AddRef();
159  void Release();
160
161 private:
162  // Starts monitoring PropertyChanged signal.
163  void MonitorPropertyChangedInternal(const std::string& interface_name);
164
165  // Handles the result of signal connection setup.
166  void OnSignalConnected(const std::string& interface,
167                         const std::string& signal,
168                         bool success);
169
170  // Handles PropertyChanged signal.
171  void OnPropertyChanged(dbus::Signal* signal);
172
173  dbus::ObjectProxy* proxy_;
174  ReleasedCallback released_callback_;
175  int active_refs_;
176  PropertyChangedHandler property_changed_handler_;
177  ObserverList<ShillPropertyChangedObserver, true /* check_empty */>
178      observer_list_;
179  std::vector<std::string> interfaces_to_be_monitored_;
180
181  // Note: This should remain the last member so it'll be destroyed and
182  // invalidate its weak pointers before any other members are destroyed.
183  base::WeakPtrFactory<ShillClientHelper> weak_ptr_factory_;
184
185  DISALLOW_COPY_AND_ASSIGN(ShillClientHelper);
186};
187
188}  // namespace chromeos
189
190#endif  // CHROMEOS_DBUS_SHILL_CLIENT_HELPER_H_
191