shill: Create Modem instances for ModemManager.Modem paths.

Each Modem instance will manage a single ModemManager.Modem and a single
Cellular device.

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

Change-Id: I4798224f0bc824bd6d1177e6a6b89f65ca4725ba
Reviewed-on: http://gerrit.chromium.org/gerrit/4356
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Chris Masone <cmasone@chromium.org>
diff --git a/modem_manager.cc b/modem_manager.cc
index 94536fb..2e151cd 100644
--- a/modem_manager.cc
+++ b/modem_manager.cc
@@ -5,11 +5,15 @@
 #include "shill/modem_manager.h"
 
 #include <base/logging.h>
+#include <base/stl_util-inl.h>
 
+#include "shill/modem.h"
 #include "shill/modem_manager_proxy.h"
 #include "shill/proxy_factory.h"
 
 using std::string;
+using std::tr1::shared_ptr;
+using std::vector;
 
 namespace shill {
 
@@ -56,9 +60,17 @@
   owner_ = owner;
   proxy_.reset(
       ProxyFactory::factory()->CreateModemManagerProxy(this, path_, owner_));
+
+  // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
+  vector<DBus::Path> devices = proxy_->EnumerateDevices();
+  for (vector<DBus::Path>::const_iterator it = devices.begin();
+       it != devices.end(); ++it) {
+    AddModem(*it);
+  }
 }
 
 void ModemManager::Disconnect() {
+  modems_.clear();
   owner_.clear();
   proxy_.reset();
 }
@@ -80,4 +92,25 @@
   manager->Disconnect();
 }
 
+void ModemManager::AddModem(const std::string &path) {
+  LOG(INFO) << "Add modem: " << path;
+  CHECK(!owner_.empty());
+  if (ContainsKey(modems_, path)) {
+    LOG(INFO) << "Modem already exists; ignored.";
+    return;
+  }
+  shared_ptr<Modem> modem(new Modem(owner_,
+                                    path,
+                                    control_interface_,
+                                    dispatcher_,
+                                    manager_));
+  modems_[path] = modem;
+}
+
+void ModemManager::RemoveModem(const std::string &path) {
+  LOG(INFO) << "Remove modem: " << path;
+  CHECK(!owner_.empty());
+  modems_.erase(path);
+}
+
 }  // namespace shill