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);
 };