shill: Implement GetSignalQuality() and watch for changes

BUG=None
TEST=Arrange for signal quality to change substantially over a 30s
interval (MM's default polling interval), check for PropertyChanged
message with dbus-monitor, and watch for log message from from
cellular.cc (Or monitor the strength on the service, if one exists).

Change-Id: Iba6237f7e4204a26db3080d7f81baeed8f36a8fc
Reviewed-on: https://gerrit.chromium.org/gerrit/20400
Reviewed-by: Jason Glasgow <jglasgow@chromium.org>
Tested-by: Nathan J. Williams <njw@chromium.org>
Commit-Ready: Nathan J. Williams <njw@chromium.org>
diff --git a/cellular_capability_universal.cc b/cellular_capability_universal.cc
index 1061b75..c9b8547 100644
--- a/cellular_capability_universal.cc
+++ b/cellular_capability_universal.cc
@@ -843,8 +843,10 @@
 }
 
 void CellularCapabilityUniversal::GetSignalQuality() {
-  // TODO(jglasgow): implement
-  NOTIMPLEMENTED();
+  // TODO(njw): Switch to asynchronous calls (crosbug.com/17583).
+  const DBus::Struct<unsigned int, bool> quality =
+      modem_proxy_->SignalQuality();
+  OnSignalQualityChanged(quality._1);
 }
 
 void CellularCapabilityUniversal::OnModemPropertiesChanged(
@@ -861,6 +863,15 @@
                                 &access_technologies)) {
     SetAccessTechnologies(access_technologies);
   }
+
+  DBusPropertiesMap::const_iterator it =
+    properties.find(MM_MODEM_PROPERTY_SIGNALQUALITY);
+  if (it != properties.end()) {
+    DBus::Struct<unsigned int, bool> quality =
+      static_cast<DBus::Variant>(it->second);
+    OnSignalQualityChanged(quality._1);
+  }
+
   // Unlockrequired and SimLock
   bool emit = false;