PM: Add a DBus backend to the shill provider.
This change integrates the necessary logic for the shill provider to
actually talk to shill over DBus.
* RealShillProviders now takes a DbusInterface object. PolicyManager and
RealState were extended to propagate this object, accordingly.
* New provider_utils and general glib_utils modules.
* Minor touch-ups: removal of redundant includes and unwarranted 'using'
clauses.
BUG=chromium:338585
TEST=Unit tests.
Change-Id: I4082b845557eff2a02a928c60c348dde0e784a2c
Reviewed-on: https://chromium-review.googlesource.com/189045
Reviewed-by: Gilad Arnold <garnold@chromium.org>
Commit-Queue: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
diff --git a/policy_manager/real_shill_provider.h b/policy_manager/real_shill_provider.h
index 1a120b7..26de44f 100644
--- a/policy_manager/real_shill_provider.h
+++ b/policy_manager/real_shill_provider.h
@@ -5,36 +5,124 @@
#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_REAL_SHILL_PROVIDER_H
#define CHROMEOS_PLATFORM_UPDATE_ENGINE_POLICY_MANAGER_REAL_SHILL_PROVIDER_H
+// TODO(garnold) Much of the functionality in this module was adapted from the
+// update engine's connection_manager. We need to make sure to deprecate use of
+// connection manager when the time comes.
+
+#include <string>
+
+#include <base/time.h>
+
+#include "update_engine/clock_interface.h"
+#include "update_engine/dbus_wrapper_interface.h"
#include "update_engine/policy_manager/shill_provider.h"
-using base::Time;
+using chromeos_update_engine::ClockInterface;
+using chromeos_update_engine::DBusWrapperInterface;
namespace chromeos_policy_manager {
+// A tracker for the last reported value. Whenever Update() is called with a new
+// value, the current time is written to a pointed time object.
+template<typename T>
+class LastValueTracker {
+ public:
+ LastValueTracker(ClockInterface* clock, T init_val, base::Time* time_p)
+ : clock_(clock), last_val_(init_val), time_p_(time_p) {}
+
+ const T& Update(const T& curr_val) {
+ if (curr_val != last_val_) {
+ last_val_ = curr_val;
+ *time_p_ = clock_->GetWallclockTime();
+ }
+ return curr_val;
+ }
+
+ private:
+ ClockInterface* const clock_;
+ T last_val_;
+ base::Time* time_p_;
+};
+
+// A DBus connector for making shill queries.
+class ShillConnector {
+ public:
+ ShillConnector(DBusWrapperInterface* dbus) : dbus_(dbus) {}
+
+ ~ShillConnector() {
+ if (manager_proxy_)
+ dbus_->ProxyUnref(manager_proxy_);
+ }
+
+ // Initializes the DBus connector. Returns |true| on success.
+ bool Init();
+
+ // Obtains the default network connection, storing the connection status to
+ // |*is_connected_p| and (if connected) the service path for the default
+ // connection in |*default_service_path_p|. Returns |true| on success; |false|
+ // on failure, in which case no values are written.
+ bool GetDefaultConnection(bool* is_connected_p,
+ std::string* default_service_path_p);
+
+ // Obtains the type of a network connection described by |service_path|,
+ // storing it to |*conn_type_p|. Returns |true| on success; |false| on
+ // failure, in which case no value is written.
+ bool GetConnectionType(const std::string& service_path,
+ ShillConnType* conn_type_p);
+
+ private:
+ typedef struct {
+ const char *str;
+ ShillConnType type;
+ } ConnStrToType;
+
+ // A mapping from shill connection type strings to enum values.
+ static const ConnStrToType shill_conn_str_to_type[];
+
+ // The DBus interface and connection, and a shill manager proxy.
+ DBusWrapperInterface* dbus_;
+ DBusGConnection* connection_ = NULL;
+ DBusGProxy* manager_proxy_ = NULL;
+
+ // Return a DBus proxy for a given |path| and |interface| within shill.
+ DBusGProxy* GetProxy(const char* path, const char* interface);
+
+ // Converts a shill connection type string into a symbolic value.
+ ShillConnType ParseConnType(const char* str);
+
+ // Issues a GetProperties call through a given |proxy|, storing the result to
+ // |*result_p|. Returns |true| on success.
+ bool GetProperties(DBusGProxy* proxy, GHashTable** result_p);
+
+ DISALLOW_COPY_AND_ASSIGN(ShillConnector);
+};
+
// ShillProvider concrete implementation.
-//
-// TODO(garnold) Much of the functionality in this module was adapted from
-// connection_manager, with slight changes (annotated inline). We need to make
-// sure to deprecate use of connection manager when the time comes.
class RealShillProvider : public ShillProvider {
public:
- // TODO(garnold) This should take a DBus object for communicating with shill.
- RealShillProvider()
- : is_connected_(false), conn_type_(kShillConnTypeUnknown),
- conn_last_changed_(Time::Now()) {}
+ RealShillProvider(DBusWrapperInterface* dbus, ClockInterface* clock)
+ : conn_last_changed_(clock->GetWallclockTime()),
+ dbus_(dbus), clock_(clock),
+ is_connected_tracker_(clock, false, &conn_last_changed_) {}
protected:
virtual bool DoInit();
private:
- // Whether we have network connectivity.
- bool is_connected_;
-
- // The current network connection type as reported by shill.
- ShillConnType conn_type_;
-
// The time when the connection type last changed.
- Time conn_last_changed_;
+ base::Time conn_last_changed_;
+
+ // A shill DBus connector.
+ scoped_ptr<ShillConnector> connector_;
+
+ // The DBus interface object (mockable).
+ DBusWrapperInterface* const dbus_;
+
+ // A clock abstraction (mockable).
+ ClockInterface* const clock_;
+
+ // Tracker for the latest connection status.
+ LastValueTracker<bool> is_connected_tracker_;
DISALLOW_COPY_AND_ASSIGN(RealShillProvider);
};