shill: Fix a crash on creation of Cellular device.

Main fix is that DeviceInfo doesn't create/manage kCellular devices thus
avoiding D-Bus path collisions. Also, create the Cellular device in a delayed
task because the WiFi comments say that D-Bus objects can't be registered in
signal callbacks.

Fixes bad dispatcher_ member initialization and missing manager_ initialization.

Adds a DispatchPendingEvents method to the event dispatcher useful for testing.

BUG=chromium-os:18228
TEST=unit tests, tested on device

Change-Id: Ib8859dfe59f7a3fd7b3978793dc8f38f22609db5
Reviewed-on: http://gerrit.chromium.org/gerrit/4771
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: mukesh agrawal <quiche@chromium.org>
diff --git a/device_info.cc b/device_info.cc
index 9e61026..5a368ef 100644
--- a/device_info.cc
+++ b/device_info.cc
@@ -159,18 +159,23 @@
     }
 
     switch (technology) {
-    case Device::kEthernet:
-      device = new Ethernet(control_interface_, dispatcher_, manager_,
-                            link_name, dev_index);
-      break;
-    case Device::kWifi:
-      device = new WiFi(control_interface_, dispatcher_, manager_,
-                        link_name, dev_index);
-      break;
-    default:
-      device = new DeviceStub(control_interface_, dispatcher_, manager_,
-                              link_name, dev_index, technology);
-      is_stub = true;
+      case Device::kCellular:
+        // Cellular devices are managed by ModemInfo.
+        VLOG(2) << "Cellular link " << link_name << " at index " << dev_index
+                << " ignored.";
+        return;
+      case Device::kEthernet:
+        device = new Ethernet(control_interface_, dispatcher_, manager_,
+                              link_name, dev_index);
+        break;
+      case Device::kWifi:
+        device = new WiFi(control_interface_, dispatcher_, manager_,
+                          link_name, dev_index);
+        break;
+      default:
+        device = new DeviceStub(control_interface_, dispatcher_, manager_,
+                                link_name, dev_index, technology);
+        is_stub = true;
     }
 
     devices_[dev_index] = device;
@@ -186,14 +191,15 @@
 
 void DeviceInfo::DelLinkMsgHandler(struct nlmsghdr *hdr) {
   struct ifinfomsg *msg = reinterpret_cast<struct ifinfomsg *>(NLMSG_DATA(hdr));
-  base::hash_map<int, DeviceRefPtr>::iterator ndev =
-      devices_.find(msg->ifi_index);
-  int dev_index = msg->ifi_index;
-  DeviceRefPtr device;
+  RemoveDevice(msg->ifi_index);
+}
 
+void DeviceInfo::RemoveDevice(int interface_index) {
+  base::hash_map<int, DeviceRefPtr>::iterator ndev =
+      devices_.find(interface_index);
   if (ndev != devices_.end()) {
-    device = ndev->second;
-    manager_->DeregisterDevice(device.get());
+    VLOG(2) << "Removing device index: " << interface_index;
+    manager_->DeregisterDevice(ndev->second);
     devices_.erase(ndev);
   }
 }