PM: Shift to signal-based inference of network connection.
Instead of making DBus calls to shill on-demand, and estimating the time
a connection has changed, the RealShillProvider now listens to the
appropriate DBus signal and update its internal state accordingly. Note
that checking for the connection type still requires a DBus call, if the
connection has changed since its type was last checked.
In order to pass all unit tests (including those of PolicyManager and
RealState), there's a substantial portion of DBus mock set up code that
was added. This code will be removed very soon, once we begin injecting
providers into RealState, instead of low-level DBus and/or clock
interfaces.
BUG=chromium:338585
TEST=Unit tests.
Change-Id: Ia7a2f9db18f905f1b7a2cc1234acb31eaa60009e
Reviewed-on: https://chromium-review.googlesource.com/189692
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 80b4802..ba24234 100644
--- a/policy_manager/real_shill_provider.h
+++ b/policy_manager/real_shill_provider.h
@@ -22,55 +22,40 @@
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.
+// A DBus connector for making all shill related calls.
class ShillConnector {
public:
- ShillConnector(DBusWrapperInterface* dbus) : dbus_(dbus) {}
+ // Expected type for the PropertyChanged signal handler.
+ typedef void (*PropertyChangedHandler)(DBusGProxy*, const char*, GValue*,
+ void*);
- ~ShillConnector() {
- if (manager_proxy_)
- dbus_->ProxyUnref(manager_proxy_);
- }
+ ShillConnector(DBusWrapperInterface* dbus,
+ PropertyChangedHandler signal_handler, void* signal_data)
+ : dbus_(dbus), signal_handler_(signal_handler),
+ signal_data_(signal_data) {}
+
+ ~ShillConnector();
// 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);
+ // Issues a GetProperties call to shill's manager interface, storing the
+ // result to |*result_p|. Returns |true| on success.
+ bool GetManagerProperties(GHashTable** result_p) {
+ return GetProperties(manager_proxy_, result_p);
+ }
+
private:
+ // 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);
+
typedef struct {
const char *str;
ShillConnType type;
@@ -79,21 +64,24 @@
// A mapping from shill connection type strings to enum values.
static const ConnStrToType shill_conn_str_to_type[];
+ // An initialization flag.
+ bool is_init_ = false;
+
// The DBus interface and connection, and a shill manager proxy.
DBusWrapperInterface* dbus_;
DBusGConnection* connection_ = NULL;
DBusGProxy* manager_proxy_ = NULL;
+ // The shill manager signal handler credentials.
+ PropertyChangedHandler signal_handler_ = NULL;
+ void* signal_data_ = 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);
};
@@ -101,17 +89,37 @@
class RealShillProvider : public ShillProvider {
public:
RealShillProvider(DBusWrapperInterface* dbus, ClockInterface* clock)
- : conn_last_changed_(clock->GetWallclockTime()),
- dbus_(dbus), clock_(clock),
- is_connected_tracker_(clock, false, &conn_last_changed_) {}
+ : dbus_(dbus), clock_(clock) {}
protected:
virtual bool DoInit();
private:
+ // Process a default connection value, update last change time as needed.
+ bool ProcessDefaultService(GValue* value);
+
+ // A handler for manager PropertyChanged signal, and a static version.
+ void HandlePropertyChanged(DBusGProxy* proxy, const char *name,
+ GValue* value);
+ static void HandlePropertyChangedStatic(DBusGProxy* proxy, const char* name,
+ GValue* value, void* data);
+
+
// The time when the connection type last changed.
base::Time conn_last_changed_;
+ // The current connection status.
+ bool is_connected_;
+
+ // The current default service path, if connected.
+ std::string default_service_path_;
+
+ // The last known type of the default connection.
+ ShillConnType conn_type_ = kShillConnTypeUnknown;
+
+ // Whether the last known connection type is valid.
+ bool is_conn_type_valid_ = false;
+
// A shill DBus connector.
scoped_ptr<ShillConnector> connector_;
@@ -121,9 +129,7 @@
// A clock abstraction (mockable).
ClockInterface* const clock_;
- // Tracker for the latest connection status.
- LastValueTracker<bool> is_connected_tracker_;
-
+ friend class ConnTypeVariable;
DISALLOW_COPY_AND_ASSIGN(RealShillProvider);
};