shill: Add CellularCapabilityUniversal

Add the CellularCapabilityUniversal class so that shill can talk to a
ModemManager1 DBUS interface.  Ensure that a modems can be created
with either the new or the old modem manager running.

Register to receive DBus property changes from ModemManager1

BUG=chromium-os:28596, chromium-os:26650
TEST=Run unit tests, test that modem is created with Y3300

Change-Id: I8717318e944589bc85e763bd7234336559256dbc
Reviewed-on: https://gerrit.chromium.org/gerrit/19888
Commit-Ready: Jason Glasgow <jglasgow@chromium.org>
Reviewed-by: Jason Glasgow <jglasgow@chromium.org>
Tested-by: Jason Glasgow <jglasgow@chromium.org>
diff --git a/modem.cc b/modem.cc
index 899918a..a9f2e55 100644
--- a/modem.cc
+++ b/modem.cc
@@ -40,7 +40,8 @@
       provider_db_(provider_db),
       type_(Cellular::kTypeInvalid),
       pending_device_info_(false),
-      rtnl_handler_(RTNLHandler::GetInstance()) {
+      rtnl_handler_(RTNLHandler::GetInstance()),
+      proxy_factory_(ProxyFactory::GetInstance()) {
   LOG(INFO) << "Modem created: " << owner << " at " << path;
 }
 
@@ -52,9 +53,7 @@
 
 void Modem::Init() {
   dbus_properties_proxy_.reset(
-      ProxyFactory::GetInstance()->CreateDBusPropertiesProxy(this,
-                                                             path(),
-                                                             owner()));
+      proxy_factory_->CreateDBusPropertiesProxy(this, path(), owner()));
 }
 
 void Modem::OnDeviceInfoAvailable(const string &link_name) {
@@ -121,17 +120,18 @@
     return;
   }
 
-  if (type_ == Cellular::kTypeUniversal) {
-    // TODO(rochberg):
-    LOG(ERROR) << "Cannot construct Cellular object for MM1";
-    return;
-  }
-
   string address = address_bytes.HexEncode();
   device_ = ConstructCellular(link_name_, address, interface_index);
 
-  uint32 modem_state = Cellular::kModemStateUnknown;
-  DBusProperties::GetUint32(modem_properties, kPropertyState, &modem_state);
+  // Note: 0 happens to map to Cellular::kModemStateUnknown for all
+  // types of modems
+  uint32 modem_state = 0;
+  // TODO(jglasgow): refactor to avoid explicit if on modem type.  The
+  // ModemManager1 interface type is an "i" not a "u".  Handle that
+  // during refactoring.
+  if (type_ != Cellular::kTypeUniversal)
+    DBusProperties::GetUint32(modem_properties, kPropertyState, &modem_state);
+
   device_->set_modem_state(ConvertMmToCellularModemState(modem_state));
 
   // Give the device a chance to extract any capability-specific properties.
@@ -141,10 +141,14 @@
 }
 
 void Modem::OnDBusPropertiesChanged(
-    const string &/*interface*/,
-    const DBusPropertiesMap &/*changed_properties*/,
-    const vector<string> &/*invalidated_properties*/) {
-  // Ignored.
+    const string &interface,
+    const DBusPropertiesMap &changed_properties,
+    const vector<string> &invalidated_properties) {
+  if (device().get()) {
+    device()->OnDBusPropertiesChanged(interface,
+                                      changed_properties,
+                                      invalidated_properties);
+  }
 }
 
 void Modem::OnModemManagerPropertiesChanged(