Split ModemManager into ModemManagerBase and ModemManagerClassic

This is in preparation for building ModemManager1 to support the MM0.6
interface.

BUG=chromium-os:27014
TEST=unit tests, ran shill across multiple cromo restarts

Change-Id: I718c9508d81e12481be44cdaf5453679e08b905e
Reviewed-on: https://gerrit.chromium.org/gerrit/17249
Commit-Ready: David Rochberg <rochberg@chromium.org>
Reviewed-by: David Rochberg <rochberg@chromium.org>
Tested-by: David Rochberg <rochberg@chromium.org>
diff --git a/modem_info.cc b/modem_info.cc
index 51bb9d1..d2ab343 100644
--- a/modem_info.cc
+++ b/modem_info.cc
@@ -61,14 +61,14 @@
 
 void ModemInfo::RegisterModemManager(const string &service,
                                      const string &path) {
-  ModemManager *manager = new ModemManager(service,
-                                           path,
-                                           control_interface_,
-                                           dispatcher_,
-                                           metrics_,
-                                           manager_,
-                                           glib_,
-                                           provider_db_);
+  ModemManager *manager = new ModemManagerClassic(service,
+                                                  path,
+                                                  control_interface_,
+                                                  dispatcher_,
+                                                  metrics_,
+                                                  manager_,
+                                                  glib_,
+                                                  provider_db_);
   modem_managers_.push_back(manager);  // Passes ownership.
   manager->Start();
 }
diff --git a/modem_manager.cc b/modem_manager.cc
index 5292522..009dea1 100644
--- a/modem_manager.cc
+++ b/modem_manager.cc
@@ -63,21 +63,14 @@
 }
 
 void ModemManager::Connect(const string &owner) {
+  // Inheriting classes call this superclass method.
   owner_ = owner;
-  proxy_.reset(proxy_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() {
+  // Inheriting classes call this superclass method.
   modems_.clear();
   owner_.clear();
-  proxy_.reset();
 }
 
 void ModemManager::OnAppear(GDBusConnection */*connection*/,
@@ -112,7 +105,7 @@
                                     manager_,
                                     provider_db_));
   modems_[path] = modem;
-  modem->Init();
+  InitModem(modem);
 }
 
 void ModemManager::RemoveModem(const string &path) {
@@ -122,9 +115,50 @@
 }
 
 void ModemManager::OnDeviceInfoAvailable(const string &link_name) {
-  for (Modems::iterator it = modems_.begin(); it != modems_.end(); ++it) {
+  for (Modems::const_iterator it = modems_.begin(); it != modems_.end(); ++it) {
     it->second->OnDeviceInfoAvailable(link_name);
   }
 }
 
+// ModemManagerClassic
+ModemManagerClassic::ModemManagerClassic(const std::string &service,
+                                         const std::string &path,
+                                         ControlInterface *control_interface,
+                                         EventDispatcher *dispatcher,
+                                         Metrics *metrics,
+                                         Manager *manager,
+                                         GLib *glib,
+                                         mobile_provider_db *provider_db) :
+    ModemManager(service,
+                 path,
+                 control_interface,
+                 dispatcher,
+                 metrics,
+                 manager,
+                 glib,
+                 provider_db) {}
+
+ModemManagerClassic::~ModemManagerClassic() {}
+
+void ModemManagerClassic::Connect(const string &supplied_owner) {
+  ModemManager::Connect(supplied_owner);
+  proxy_.reset(proxy_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 ModemManagerClassic::Disconnect() {
+  ModemManager::Disconnect();
+  proxy_.reset();
+}
+
+void ModemManagerClassic::InitModem(shared_ptr<Modem> modem) {
+  modem->Init();
+}
+
 }  // namespace shill
diff --git a/modem_manager.h b/modem_manager.h
index 8947798..793a6ef 100644
--- a/modem_manager.h
+++ b/modem_manager.h
@@ -55,6 +55,20 @@
 
   void OnDeviceInfoAvailable(const std::string &link_name);
 
+ protected:
+  typedef std::map<std::string, std::tr1::shared_ptr<Modem> > Modems;
+
+  const std::string &owner() const { return owner_; }
+  const Modems &modems() const { return modems_; }
+  const std::string &path() const { return path_; }
+  ProxyFactory *proxy_factory() const { return proxy_factory_; }
+
+  // Connect/Disconnect to a modem manager service.
+  // Inheriting classes must call this superclass method.
+  virtual void Connect(const std::string &owner);
+  // Inheriting classes must call this superclass method.
+  virtual void Disconnect();
+
  private:
   friend class ModemManagerTest;
   FRIEND_TEST(ModemInfoTest, RegisterModemManager);
@@ -66,14 +80,6 @@
   FRIEND_TEST(ModemManagerTest, Start);
   FRIEND_TEST(ModemManagerTest, Stop);
 
-  typedef std::map<std::string, std::tr1::shared_ptr<Modem> > Modems;
-
-  // Connects a newly appeared modem manager service.
-  void Connect(const std::string &owner);
-
-  // Disconnects a vanished modem manager service.
-  void Disconnect();
-
   // DBus service watcher callbacks.
   static void OnAppear(GDBusConnection *connection,
                        const gchar *name,
@@ -83,6 +89,11 @@
                        const gchar *name,
                        gpointer user_data);
 
+  // Starts the process of bringing up the modem so that shill can
+  // talk to it.  Called after modem has been added to the
+  // ModemManager's internal data structures.
+  virtual void InitModem(std::tr1::shared_ptr<Modem> modem) = 0;
+
   // Store cached copies of singletons for speed/ease of testing.
   ProxyFactory *proxy_factory_;
 
@@ -91,7 +102,6 @@
   guint watcher_id_;
 
   std::string owner_;  // DBus service owner.
-  scoped_ptr<ModemManagerProxyInterface> proxy_;  // DBus service proxy.
 
   Modems modems_;  // Maps a modem |path| to a modem instance.
 
@@ -105,6 +115,34 @@
   DISALLOW_COPY_AND_ASSIGN(ModemManager);
 };
 
+class ModemManagerClassic : public ModemManager {
+ public:
+  ModemManagerClassic(const std::string &service,
+                      const std::string &path,
+                      ControlInterface *control_interface,
+                      EventDispatcher *dispatcher,
+                      Metrics *metrics,
+                      Manager *manager,
+                      GLib *glib,
+                      mobile_provider_db *provider_db);
+
+  virtual ~ModemManagerClassic();
+
+ protected:
+  virtual void Connect(const std::string &owner);
+  virtual void Disconnect();
+  virtual void InitModem(std::tr1::shared_ptr<Modem> modem);
+
+ private:
+  scoped_ptr<ModemManagerProxyInterface> proxy_;  // DBus service proxy
+
+  FRIEND_TEST(ModemManagerTest, Connect);
+  FRIEND_TEST(ModemManagerTest, Disconnect);
+  FRIEND_TEST(ModemManagerTest, OnAppear);
+  FRIEND_TEST(ModemManagerTest, OnVanish);
+
+  DISALLOW_COPY_AND_ASSIGN(ModemManagerClassic);
+};
 }  // namespace shill
 
 #endif  // SHILL_MODEM_MANAGER_
diff --git a/modem_manager_proxy.cc b/modem_manager_proxy.cc
index a64678e..7aa2ae3 100644
--- a/modem_manager_proxy.cc
+++ b/modem_manager_proxy.cc
@@ -14,7 +14,7 @@
 namespace shill {
 
 ModemManagerProxy::ModemManagerProxy(DBus::Connection *connection,
-                                     ModemManager *manager,
+                                     ModemManagerClassic *manager,
                                      const string &path,
                                      const string &service)
     : proxy_(connection, manager, path, service) {}
@@ -26,7 +26,7 @@
 }
 
 ModemManagerProxy::Proxy::Proxy(DBus::Connection *connection,
-                                ModemManager *manager,
+                                ModemManagerClassic *manager,
                                 const string &path,
                                 const string &service)
     : DBus::ObjectProxy(*connection, path, service.c_str()),
diff --git a/modem_manager_proxy.h b/modem_manager_proxy.h
index 348dabf..2b261a6 100644
--- a/modem_manager_proxy.h
+++ b/modem_manager_proxy.h
@@ -15,14 +15,14 @@
 
 namespace shill {
 
-class ModemManager;
+class ModemManagerClassic;
 
 // There's a single proxy per ModemManager service identified by its DBus |path|
 // and owner name |service|.
 class ModemManagerProxy : public ModemManagerProxyInterface {
  public:
   ModemManagerProxy(DBus::Connection *connection,
-                    ModemManager *manager,
+                    ModemManagerClassic *manager,
                     const std::string &path,
                     const std::string &service);
   virtual ~ModemManagerProxy();
@@ -35,7 +35,7 @@
                 public DBus::ObjectProxy {
    public:
     Proxy(DBus::Connection *connection,
-          ModemManager *manager,
+          ModemManagerClassic *manager,
           const std::string &path,
           const std::string &service);
     virtual ~Proxy();
@@ -49,7 +49,7 @@
     // [None]
 
     // The owner of this proxy.
-    ModemManager *manager_;
+    ModemManagerClassic *manager_;
 
     DISALLOW_COPY_AND_ASSIGN(Proxy);
   };
diff --git a/modem_manager_unittest.cc b/modem_manager_unittest.cc
index c2362cf..46f2fdc 100644
--- a/modem_manager_unittest.cc
+++ b/modem_manager_unittest.cc
@@ -50,7 +50,7 @@
     explicit TestProxyFactory(ModemManagerTest *test) : test_(test) {}
 
     virtual ModemManagerProxyInterface *CreateModemManagerProxy(
-        ModemManager */*manager*/,
+        ModemManagerClassic */*manager*/,
         const string &/*path*/,
         const string &/*service*/) {
       return test_->proxy_.release();
@@ -70,7 +70,7 @@
   EventDispatcher dispatcher_;
   MockMetrics metrics_;
   MockManager manager_;
-  ModemManager modem_manager_;
+  ModemManagerClassic modem_manager_;
   scoped_ptr<MockModemManagerProxy> proxy_;
   TestProxyFactory proxy_factory_;
 };
diff --git a/proxy_factory.cc b/proxy_factory.cc
index 4b70018..20d030e 100644
--- a/proxy_factory.cc
+++ b/proxy_factory.cc
@@ -56,7 +56,7 @@
 }
 
 ModemManagerProxyInterface *ProxyFactory::CreateModemManagerProxy(
-    ModemManager *manager,
+    ModemManagerClassic *manager,
     const string &path,
     const string &service) {
   return new ModemManagerProxy(connection(), manager, path, service);
diff --git a/proxy_factory.h b/proxy_factory.h
index 34bc8bc..790a68d 100644
--- a/proxy_factory.h
+++ b/proxy_factory.h
@@ -27,7 +27,7 @@
 class ModemGSMCardProxyInterface;
 class ModemGSMNetworkProxyDelegate;
 class ModemGSMNetworkProxyInterface;
-class ModemManager;
+class ModemManagerClassic;
 class ModemManagerProxyInterface;
 class ModemProxyDelegate;
 class ModemProxyInterface;
@@ -60,7 +60,7 @@
       const std::string &service);
 
   virtual ModemManagerProxyInterface *CreateModemManagerProxy(
-      ModemManager *manager,
+      ModemManagerClassic *manager,
       const std::string &path,
       const std::string &service);