shill: On Service::Connect, connect the modem device to the network.

Also, uncouple the DBusProperties signal callbacks from Modem to make the proxy
implementation more consistent with the other proxies.

BUG=chromium-os:18727
TEST=unit tests

Change-Id: Icdddea8d2a30803150f2a159fdc5a719e960f95d
Reviewed-on: http://gerrit.chromium.org/gerrit/5444
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Chris Masone <cmasone@chromium.org>
diff --git a/cellular.cc b/cellular.cc
index 5a26d75..2c56b9d 100644
--- a/cellular.cc
+++ b/cellular.cc
@@ -18,8 +18,6 @@
 #include "shill/device.h"
 #include "shill/device_info.h"
 #include "shill/manager.h"
-#include "shill/modem_cdma_proxy_interface.h"
-#include "shill/modem_proxy_interface.h"
 #include "shill/modem_simple_proxy_interface.h"
 #include "shill/profile.h"
 #include "shill/property_accessor.h"
@@ -32,6 +30,10 @@
 
 namespace shill {
 
+const char Cellular::kConnectPropertyPhoneNumber[] = "number";
+const char Cellular::kPhoneNumberCDMA[] = "#777";
+const char Cellular::kPhoneNumberGSM[] = "*99#";
+
 Cellular::Network::Network() {
   dict_[flimflam::kStatusProperty] = "";
   dict_[flimflam::kNetworkIdProperty] = "";
@@ -109,6 +111,7 @@
       dbus_owner_(owner),
       dbus_path_(path),
       service_registered_(false),
+      task_factory_(this),
       allow_roaming_(false),
       prl_version_(0),
       scanning_(false),
@@ -194,7 +197,7 @@
 
 void Cellular::InitProxies() {
   proxy_.reset(
-      ProxyFactory::factory()->CreateModemProxy(dbus_path_, dbus_owner_));
+      ProxyFactory::factory()->CreateModemProxy(this, dbus_path_, dbus_owner_));
   simple_proxy_.reset(
       ProxyFactory::factory()->CreateModemSimpleProxy(
           dbus_path_, dbus_owner_));
@@ -373,6 +376,36 @@
   return type == Device::kCellular;
 }
 
+void Cellular::Connect() {
+  VLOG(2) << __func__;
+  if (state_ == kStateConnected) {
+    return;
+  }
+  CHECK_EQ(kStateRegistered, state_);
+  DBusPropertiesMap properties;
+  const char *phone_number = NULL;
+  switch (type_) {
+    case kTypeGSM:
+      phone_number = kPhoneNumberGSM;
+      break;
+    case kTypeCDMA:
+      phone_number = kPhoneNumberCDMA;
+      break;
+    default: NOTREACHED();
+  }
+  properties[kConnectPropertyPhoneNumber].writer().append_string(phone_number);
+  // TODO(petkov): Setup apn and "home_only".
+
+  // Defer connect because we may be in a dbus-c++ callback.
+  dispatcher_->PostTask(
+      task_factory_.NewRunnableMethod(&Cellular::ConnectTask, properties));
+}
+
+void Cellular::ConnectTask(const DBusPropertiesMap &properties) {
+  VLOG(2) << __func__;
+  simple_proxy_->Connect(properties);
+}
+
 void Cellular::OnCDMARegistrationStateChanged(uint32 state_1x,
                                               uint32 state_evdo) {
   CHECK_EQ(kTypeCDMA, type_);
@@ -386,6 +419,13 @@
   HandleNewSignalQuality(strength);
 }
 
+void Cellular::OnModemStateChanged(uint32 old_state,
+                                   uint32 new_state,
+                                   uint32 reason) {
+  // TODO(petkov): Implement this.
+  NOTIMPLEMENTED();
+}
+
 Stringmaps Cellular::EnumerateNetworks() {
   Stringmaps to_return;
   for (vector<Network>::const_iterator it = found_networks_.begin();
diff --git a/cellular.h b/cellular.h
index 4f8efbf..dc9b00b 100644
--- a/cellular.h
+++ b/cellular.h
@@ -8,20 +8,23 @@
 #include <string>
 
 #include <base/basictypes.h>
+#include <base/task.h>
 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
 
+#include "shill/dbus_properties.h"
 #include "shill/device.h"
 #include "shill/modem_cdma_proxy_interface.h"
+#include "shill/modem_proxy_interface.h"
 #include "shill/refptr_types.h"
 #include "shill/shill_event.h"
 
 namespace shill {
 
-class ModemProxyInterface;
 class ModemSimpleProxyInterface;
 
 class Cellular : public Device,
-                 public ModemCDMAProxyListener {
+                 public ModemCDMAProxyListener,
+                 public ModemProxyListener {
  public:
   enum Type {
     kTypeGSM,
@@ -79,6 +82,8 @@
     uint32 retries_left;
   };
 
+  static const char kConnectPropertyPhoneNumber[];
+
   // |owner| is the ModemManager DBus service owner (e.g., ":1.17"). |path| is
   // the ModemManager.Modem DBus object path (e.g.,
   // "/org/chromium/ModemManager/Gobi/0").
@@ -92,12 +97,19 @@
            const std::string &path);
   virtual ~Cellular();
 
+  // Asynchronously connects the modem to the network.
+  void Connect();
+
   // Inherited from Device.
   virtual void Start();
   virtual void Stop();
   virtual bool TechnologyIs(Technology type);
 
  private:
+  static const char kPhoneNumberCDMA[];
+  static const char kPhoneNumberGSM[];
+
+  FRIEND_TEST(CellularTest, Connect);
   FRIEND_TEST(CellularTest, GetCDMARegistrationState);
   FRIEND_TEST(CellularTest, GetCDMASignalQuality);
   FRIEND_TEST(CellularTest, GetModemInfo);
@@ -108,6 +120,8 @@
   FRIEND_TEST(CellularTest, InitProxiesGSM);
   FRIEND_TEST(CellularTest, Start);
 
+  void ConnectTask(const DBusPropertiesMap &properties);
+
   Stringmaps EnumerateNetworks();
   StrIntPair SimLockStatusToProperty();
   void HelpRegisterDerivedStringmaps(const std::string &name,
@@ -155,11 +169,16 @@
   // device |state_|.
   bool IsModemRegistered();
 
-  // Signal callbacks from ModemCDMAProxyListener.
+  // Signal callbacks inherited from ModemCDMAProxyListener.
   virtual void OnCDMARegistrationStateChanged(uint32 state_1x,
                                               uint32 state_evdo);
   virtual void OnCDMASignalQualityChanged(uint32 strength);
 
+  // Signal callbacks inherited from ModemProxyListener.
+  virtual void OnModemStateChanged(uint32 old_state,
+                                   uint32 new_state,
+                                   uint32 reason);
+
   Type type_;
   State state_;
 
@@ -174,6 +193,8 @@
   CellularServiceRefPtr service_;
   bool service_registered_;
 
+  ScopedRunnableMethodFactory<Cellular> task_factory_;
+
   // Properties
   bool allow_roaming_;
   std::string carrier_;
diff --git a/cellular_service.cc b/cellular_service.cc
index 3685ccd..cbe9e02 100644
--- a/cellular_service.cc
+++ b/cellular_service.cc
@@ -10,15 +10,11 @@
 #include <chromeos/dbus/service_constants.h>
 
 #include "shill/cellular.h"
-#include "shill/control_interface.h"
-#include "shill/device.h"
-#include "shill/device_info.h"
-#include "shill/manager.h"
-#include "shill/shill_event.h"
 
 using std::string;
 
 namespace shill {
+
 CellularService::CellularService(ControlInterface *control_interface,
                                  EventDispatcher *dispatcher,
                                  Manager *manager,
@@ -48,7 +44,9 @@
 
 CellularService::~CellularService() { }
 
-void CellularService::Connect() { }
+void CellularService::Connect() {
+  cellular_->Connect();
+}
 
 void CellularService::Disconnect() { }
 
diff --git a/cellular_service.h b/cellular_service.h
index ad39dab..f1b2c0a 100644
--- a/cellular_service.h
+++ b/cellular_service.h
@@ -11,7 +11,6 @@
 #include <base/basictypes.h>
 
 #include "shill/refptr_types.h"
-#include "shill/shill_event.h"
 #include "shill/service.h"
 
 namespace shill {
diff --git a/cellular_unittest.cc b/cellular_unittest.cc
index 26f9eec..0e5e0f3 100644
--- a/cellular_unittest.cc
+++ b/cellular_unittest.cc
@@ -29,7 +29,7 @@
         cdma_proxy_(new MockModemCDMAProxy()),
         proxy_factory_(this),
         device_(new Cellular(&control_interface_,
-                             NULL,
+                             &dispatcher_,
                              &manager_,
                              "usb0",
                              3,
@@ -52,7 +52,8 @@
    public:
     TestProxyFactory(CellularTest *test) : test_(test) {}
 
-    virtual ModemProxyInterface *CreateModemProxy(const string &path,
+    virtual ModemProxyInterface *CreateModemProxy(ModemProxyListener *listener,
+                                                  const string &path,
                                                   const string &service) {
       return test_->proxy_.release();
     }
@@ -247,4 +248,28 @@
   EXPECT_EQ(kStrength, device_->service_->strength());
 }
 
+namespace {
+
+MATCHER(ContainsPhoneNumber, "") {
+  return ContainsKey(arg, Cellular::kConnectPropertyPhoneNumber);
+}
+
+}  // namespace {}
+
+TEST_F(CellularTest, Connect) {
+  device_->state_ = Cellular::kStateConnected;
+  device_->Connect();
+
+  device_->state_ = Cellular::kStateRegistered;
+  device_->Connect();
+  ASSERT_FALSE(device_->task_factory_.empty());
+
+  DBusPropertiesMap properties;
+  properties[Cellular::kConnectPropertyPhoneNumber].writer().append_string(
+      Cellular::kPhoneNumberGSM);
+  EXPECT_CALL(*simple_proxy_, Connect(ContainsPhoneNumber())).Times(1);
+  device_->simple_proxy_.reset(simple_proxy_.release());
+  dispatcher_.DispatchPendingEvents();
+}
+
 }  // namespace shill
diff --git a/dbus_properties_proxy.cc b/dbus_properties_proxy.cc
index 6f43fbc..c8a19e3 100644
--- a/dbus_properties_proxy.cc
+++ b/dbus_properties_proxy.cc
@@ -6,18 +6,16 @@
 
 #include <base/logging.h>
 
-#include "shill/modem.h"
-
 namespace shill {
 
 using std::string;
 using std::vector;
 
-DBusPropertiesProxy::DBusPropertiesProxy(DBus::Connection *connection,
-                                         Modem *modem,
+DBusPropertiesProxy::DBusPropertiesProxy(DBusPropertiesProxyListener *listener,
+                                         DBus::Connection *connection,
                                          const string &path,
                                          const string &service)
-    : proxy_(connection, modem, path, service) {}
+    : proxy_(listener, connection, path, service) {}
 
 DBusPropertiesProxy::~DBusPropertiesProxy() {}
 
@@ -25,26 +23,29 @@
   return proxy_.GetAll(interface_name);
 }
 
-DBusPropertiesProxy::Proxy::Proxy(DBus::Connection *connection,
-                                  Modem *modem,
+DBusPropertiesProxy::Proxy::Proxy(DBusPropertiesProxyListener *listener,
+                                  DBus::Connection *connection,
                                   const string &path,
                                   const string &service)
     : DBus::ObjectProxy(*connection, path, service.c_str()),
-      modem_(modem) {}
+      listener_(listener) {}
 
 DBusPropertiesProxy::Proxy::~Proxy() {}
 
 void DBusPropertiesProxy::Proxy::MmPropertiesChanged(
     const string &interface,
     const DBusPropertiesMap &properties) {
-  LOG(INFO) << "MmPropertiesChanged: " << interface;
+  VLOG(2) << __func__ << "(" << interface << ")";
+  listener_->OnModemManagerPropertiesChanged(interface, properties);
 }
 
 void DBusPropertiesProxy::Proxy::PropertiesChanged(
     const string &interface,
     const DBusPropertiesMap &changed_properties,
     const vector<string> &invalidated_properties) {
-  LOG(INFO) << "PropertiesChanged: " << interface;
+  VLOG(2) << __func__ << "(" << interface << ")";
+  listener_->OnDBusPropertiesChanged(
+      interface, changed_properties, invalidated_properties);
 }
 
 }  // namespace shill
diff --git a/dbus_properties_proxy.h b/dbus_properties_proxy.h
index f3ab239..8bf474b 100644
--- a/dbus_properties_proxy.h
+++ b/dbus_properties_proxy.h
@@ -12,12 +12,10 @@
 
 namespace shill {
 
-class Modem;
-
 class DBusPropertiesProxy : public DBusPropertiesProxyInterface {
  public:
-  DBusPropertiesProxy(DBus::Connection *connection,
-                      Modem *modem,
+  DBusPropertiesProxy(DBusPropertiesProxyListener *listener,
+                      DBus::Connection *connection,
                       const std::string &path,
                       const std::string &service);
   virtual ~DBusPropertiesProxy();
@@ -29,8 +27,8 @@
   class Proxy : public org::freedesktop::DBus::Properties_proxy,
                 public DBus::ObjectProxy {
    public:
-    Proxy(DBus::Connection *connection,
-          Modem *modem,
+    Proxy(DBusPropertiesProxyListener *listener,
+          DBus::Connection *connection,
           const std::string &path,
           const std::string &service);
     virtual ~Proxy();
@@ -45,7 +43,7 @@
         const DBusPropertiesMap &changed_properties,
         const std::vector<std::string> &invalidated_properties);
 
-    Modem *modem_;
+    DBusPropertiesProxyListener *listener_;
 
     DISALLOW_COPY_AND_ASSIGN(Proxy);
   };
diff --git a/dbus_properties_proxy_interface.h b/dbus_properties_proxy_interface.h
index 7aeea03..93320dc 100644
--- a/dbus_properties_proxy_interface.h
+++ b/dbus_properties_proxy_interface.h
@@ -5,6 +5,8 @@
 #ifndef SHILL_DBUS_PROPERTIES_PROXY_INTERFACE_
 #define SHILL_DBUS_PROPERTIES_PROXY_INTERFACE_
 
+#include <vector>
+
 #include "shill/dbus_properties.h"
 
 namespace shill {
@@ -18,6 +20,21 @@
   virtual DBusPropertiesMap GetAll(const std::string &interface_name) = 0;
 };
 
+// DBus.Properties signal listener to be associated with the proxy.
+class DBusPropertiesProxyListener {
+ public:
+  virtual ~DBusPropertiesProxyListener() {}
+
+  virtual void OnDBusPropertiesChanged(
+      const std::string &interface,
+      const DBusPropertiesMap &changed_properties,
+      const std::vector<std::string> &invalidated_properties) = 0;
+
+  virtual void OnModemManagerPropertiesChanged(
+      const std::string &interface,
+      const DBusPropertiesMap &properties) = 0;
+};
+
 }  // namespace shill
 
 #endif  // SHILL_DBUS_PROPERTIES_PROXY_INTERFACE_
diff --git a/mock_modem_simple_proxy.h b/mock_modem_simple_proxy.h
index f0ba0a2..b5877df 100644
--- a/mock_modem_simple_proxy.h
+++ b/mock_modem_simple_proxy.h
@@ -14,6 +14,7 @@
 class MockModemSimpleProxy : public ModemSimpleProxyInterface {
  public:
   MOCK_METHOD0(GetStatus, DBusPropertiesMap());
+  MOCK_METHOD1(Connect, void(const DBusPropertiesMap &properties));
 };
 
 }  // namespace shill
diff --git a/modem.cc b/modem.cc
index 87e3d3e..8e15156 100644
--- a/modem.cc
+++ b/modem.cc
@@ -13,6 +13,7 @@
 #include "shill/rtnl_handler.h"
 
 using std::string;
+using std::vector;
 
 namespace shill {
 
@@ -122,4 +123,18 @@
   }
 }
 
+void Modem::OnDBusPropertiesChanged(
+    const string &interface,
+    const DBusPropertiesMap &changed_properties,
+    const vector<string> &invalidated_properties) {
+  // Ignored.
+}
+
+void Modem::OnModemManagerPropertiesChanged(
+    const string &interface,
+    const DBusPropertiesMap &properties) {
+  // TODO(petkov): Implement this.
+  NOTIMPLEMENTED();
+}
+
 }  // namespace shill
diff --git a/modem.h b/modem.h
index e3e5f67..78a1e97 100644
--- a/modem.h
+++ b/modem.h
@@ -23,7 +23,7 @@
 
 // Handles an instance of ModemManager.Modem and an instance of a Cellular
 // device.
-class Modem {
+class Modem : public DBusPropertiesProxyListener {
  public:
   // |owner| is the ModemManager DBus service owner (e.g., ":1.17"). |path| is
   // the ModemManager.Modem DBus object path (e.g.,
@@ -35,7 +35,8 @@
         Manager *manager);
   ~Modem();
 
-  // Initializes support for the modem, possibly constructing a Cellular device.
+  // Asynchronously initializes support for the modem, possibly constructing a
+  // Cellular device.
   void Init();
 
  private:
@@ -59,6 +60,15 @@
   // properties are invalid.
   void CreateCellularDevice(const DBusPropertiesMap &properties);
 
+  // Signal callbacks inherited from DBusPropertiesProxyListener.
+  virtual void OnDBusPropertiesChanged(
+      const std::string &interface,
+      const DBusPropertiesMap &changed_properties,
+      const std::vector<std::string> &invalidated_properties);
+  virtual void OnModemManagerPropertiesChanged(
+      const std::string &interface,
+      const DBusPropertiesMap &properties);
+
   // A proxy to the org.freedesktop.DBus.Properties interface used to obtain
   // ModemManager.Modem properties and watch for property changes.
   scoped_ptr<DBusPropertiesProxyInterface> dbus_properties_proxy_;
diff --git a/modem_proxy.cc b/modem_proxy.cc
index 3328667..1eb1b0c 100644
--- a/modem_proxy.cc
+++ b/modem_proxy.cc
@@ -10,10 +10,11 @@
 
 namespace shill {
 
-ModemProxy::ModemProxy(DBus::Connection *connection,
+ModemProxy::ModemProxy(ModemProxyListener *listener,
+                       DBus::Connection *connection,
                        const string &path,
                        const string &service)
-    : proxy_(connection, path, service) {}
+    : proxy_(listener, connection, path, service) {}
 
 ModemProxy::~ModemProxy() {}
 
@@ -25,19 +26,20 @@
   return proxy_.GetInfo();
 }
 
-ModemProxy::Proxy::Proxy(DBus::Connection *connection,
+ModemProxy::Proxy::Proxy(ModemProxyListener *listener,
+                         DBus::Connection *connection,
                          const string &path,
                          const string &service)
-    : DBus::ObjectProxy(*connection, path, service.c_str()) {}
+    : DBus::ObjectProxy(*connection, path, service.c_str()),
+      listener_(listener) {}
 
 ModemProxy::Proxy::~Proxy() {}
 
 void ModemProxy::Proxy::StateChanged(const uint32 &old,
                                      const uint32 &_new,
                                      const uint32 &reason) {
-  VLOG(2) << __func__;
-  // TODO(petkov): Implement this.
-  NOTIMPLEMENTED();
+  VLOG(2) << __func__ << "(" << old << ", " << _new << ", " << reason << ")";
+  listener_->OnModemStateChanged(old, _new, reason);
 }
 
 }  // namespace shill
diff --git a/modem_proxy.h b/modem_proxy.h
index a1300b8..4a1a40d 100644
--- a/modem_proxy.h
+++ b/modem_proxy.h
@@ -12,11 +12,13 @@
 
 namespace shill {
 
-// There's a single proxy per ModemManager.Modem service identified by its DBus
-// |path| and owner name |service|.
+// A proxy to ModemManager.Modem.
 class ModemProxy : public ModemProxyInterface {
  public:
-  ModemProxy(DBus::Connection *connection,
+  // Constructs a ModemManager.Modem DBus object proxy at |path| owned by
+  // |service|. Caught signals will be dispatched to |listener|.
+  ModemProxy(ModemProxyListener *listener,
+             DBus::Connection *connection,
              const std::string &path,
              const std::string &service);
   virtual ~ModemProxy();
@@ -29,7 +31,8 @@
   class Proxy : public org::freedesktop::ModemManager::Modem_proxy,
                 public DBus::ObjectProxy {
    public:
-    Proxy(DBus::Connection *connection,
+    Proxy(ModemProxyListener *listener,
+          DBus::Connection *connection,
           const std::string &path,
           const std::string &service);
     virtual ~Proxy();
@@ -40,6 +43,8 @@
                               const uint32 &_new,
                               const uint32 &reason);
 
+    ModemProxyListener *listener_;
+
     DISALLOW_COPY_AND_ASSIGN(Proxy);
   };
 
diff --git a/modem_proxy_interface.h b/modem_proxy_interface.h
index 52e2d48..2616dea 100644
--- a/modem_proxy_interface.h
+++ b/modem_proxy_interface.h
@@ -21,6 +21,16 @@
   virtual Info GetInfo() = 0;
 };
 
+// ModemManager.Modem signal listener to be associated with the proxy.
+class ModemProxyListener {
+ public:
+  virtual ~ModemProxyListener() {}
+
+  virtual void OnModemStateChanged(uint32 old_state,
+                                   uint32 new_state,
+                                   uint32 reason) = 0;
+};
+
 }  // namespace shill
 
 #endif  // SHILL_MODEM_PROXY_INTERFACE_
diff --git a/modem_simple_proxy.cc b/modem_simple_proxy.cc
index a8b48b1..37c9c83 100644
--- a/modem_simple_proxy.cc
+++ b/modem_simple_proxy.cc
@@ -19,6 +19,10 @@
   return proxy_.GetStatus();
 }
 
+void ModemSimpleProxy::Connect(const DBusPropertiesMap &properties) {
+  proxy_.Connect(properties);
+}
+
 ModemSimpleProxy::Proxy::Proxy(DBus::Connection *connection,
                                const string &path,
                                const string &service)
diff --git a/modem_simple_proxy.h b/modem_simple_proxy.h
index 91fccd2..9d62ead 100644
--- a/modem_simple_proxy.h
+++ b/modem_simple_proxy.h
@@ -22,6 +22,7 @@
 
   // Inherited from ModemSimpleProxyInterface.
   virtual DBusPropertiesMap GetStatus();
+  virtual void Connect(const DBusPropertiesMap &properties);
 
  private:
   class Proxy : public org::freedesktop::ModemManager::Modem::Simple_proxy,
diff --git a/modem_simple_proxy_interface.h b/modem_simple_proxy_interface.h
index 9d0c248..fbf32c6 100644
--- a/modem_simple_proxy_interface.h
+++ b/modem_simple_proxy_interface.h
@@ -16,6 +16,7 @@
   virtual ~ModemSimpleProxyInterface() {}
 
   virtual DBusPropertiesMap GetStatus() = 0;
+  virtual void Connect(const DBusPropertiesMap &properties) = 0;
 };
 
 }  // namespace shill
diff --git a/modem_unittest.cc b/modem_unittest.cc
index 4a4b23d..963365c 100644
--- a/modem_unittest.cc
+++ b/modem_unittest.cc
@@ -60,7 +60,7 @@
     TestProxyFactory(ModemTest *test) : test_(test) {}
 
     virtual DBusPropertiesProxyInterface *CreateDBusPropertiesProxy(
-        Modem *modem,
+        DBusPropertiesProxyListener *listener,
         const string &path,
         const string &service) {
       return test_->proxy_.release();
diff --git a/proxy_factory.cc b/proxy_factory.cc
index 2e90348..c5191c6 100644
--- a/proxy_factory.cc
+++ b/proxy_factory.cc
@@ -32,10 +32,10 @@
 }
 
 DBusPropertiesProxyInterface *ProxyFactory::CreateDBusPropertiesProxy(
-    Modem *modem,
+    DBusPropertiesProxyListener *listener,
     const string &path,
     const string &service) {
-  return new DBusPropertiesProxy(connection(), modem, path, service);
+  return new DBusPropertiesProxy(listener, connection(), path, service);
 }
 
 ModemManagerProxyInterface *ProxyFactory::CreateModemManagerProxy(
@@ -45,9 +45,11 @@
   return new ModemManagerProxy(connection(), manager, path, service);
 }
 
-ModemProxyInterface *ProxyFactory::CreateModemProxy(const string &path,
-                                                    const string &service) {
-  return new ModemProxy(connection(), path, service);
+ModemProxyInterface *ProxyFactory::CreateModemProxy(
+    ModemProxyListener *listener,
+    const string &path,
+    const string &service) {
+  return new ModemProxy(listener, connection(), path, service);
 }
 
 ModemSimpleProxyInterface *ProxyFactory::CreateModemSimpleProxy(
diff --git a/proxy_factory.h b/proxy_factory.h
index 0fc1cbd..777051a 100644
--- a/proxy_factory.h
+++ b/proxy_factory.h
@@ -16,13 +16,14 @@
 namespace shill {
 
 class DBusPropertiesProxyInterface;
+class DBusPropertiesProxyListener;
 class DHCPProxyInterface;
-class Modem;
 class ModemCDMAProxyInterface;
 class ModemCDMAProxyListener;
 class ModemManager;
 class ModemManagerProxyInterface;
 class ModemProxyInterface;
+class ModemProxyListener;
 class ModemSimpleProxyInterface;
 class SupplicantInterfaceProxyInterface;
 class SupplicantProcessProxyInterface;
@@ -36,7 +37,7 @@
   void Init();
 
   virtual DBusPropertiesProxyInterface *CreateDBusPropertiesProxy(
-      Modem *modem,
+      DBusPropertiesProxyListener *listener,
       const std::string &path,
       const std::string &service);
 
@@ -45,7 +46,8 @@
       const std::string &path,
       const std::string &service);
 
-  virtual ModemProxyInterface *CreateModemProxy(const std::string &path,
+  virtual ModemProxyInterface *CreateModemProxy(ModemProxyListener *listener,
+                                                const std::string &path,
                                                 const std::string &service);
 
   virtual ModemSimpleProxyInterface *CreateModemSimpleProxy(