shill: cellular: make enable and disable for universal modems

Make enable and disable for universal modems.

BUG=chromium-os:28700
TEST=run unit tests, enable and disable a Y3300

Change-Id: Icaaa72b976bed0f597dac2c46140172a8d901913
Reviewed-on: https://gerrit.chromium.org/gerrit/19913
Commit-Ready: Jason Glasgow <jglasgow@chromium.org>
Reviewed-by: Jason Glasgow <jglasgow@chromium.org>
Tested-by: Jason Glasgow <jglasgow@chromium.org>
diff --git a/Makefile b/Makefile
index f6ef921..33ff8a7 100644
--- a/Makefile
+++ b/Makefile
@@ -216,6 +216,7 @@
 	cellular_capability_cdma_unittest.o \
 	cellular_capability_classic_unittest.o \
 	cellular_capability_gsm_unittest.o \
+	cellular_capability_universal_unittest.o \
 	cellular_service_unittest.o \
 	cellular_unittest.o \
 	crypto_des_cbc_unittest.o \
@@ -261,6 +262,11 @@
 	mock_ipconfig.o \
 	mock_manager.o \
 	mock_metrics.o \
+	mock_mm1_modem_modemcdma_proxy.o \
+	mock_mm1_modem_modem3gpp_proxy.o \
+	mock_mm1_modem_proxy.o \
+	mock_mm1_modem_simple_proxy.o \
+	mock_mm1_sim_proxy.o \
 	mock_modem.o \
 	mock_modem_cdma_proxy.o \
 	mock_modem_gsm_card_proxy.o \
diff --git a/cellular.h b/cellular.h
index 472fa48..1a2375b 100644
--- a/cellular.h
+++ b/cellular.h
@@ -186,6 +186,7 @@
   friend class CellularCapabilityTest;
   friend class CellularCapabilityCDMATest;
   friend class CellularCapabilityGSMTest;
+  friend class CellularCapabilityUniversalTest;
   friend class CellularServiceTest;
   friend class ModemTest;
   FRIEND_TEST(CellularCapabilityCDMATest, CreateFriendlyServiceName);
diff --git a/cellular_capability.h b/cellular_capability.h
index 52b7b08..d4cf969 100644
--- a/cellular_capability.h
+++ b/cellular_capability.h
@@ -198,6 +198,7 @@
  private:
   friend class CellularCapabilityGSMTest;
   friend class CellularCapabilityTest;
+  friend class CellularCapabilityUniversalTest;
   friend class CellularTest;
   FRIEND_TEST(CellularCapabilityTest, AllowRoaming);
   FRIEND_TEST(CellularTest, Connect);
diff --git a/cellular_capability_universal.cc b/cellular_capability_universal.cc
index 85956b3..8d8f44d 100644
--- a/cellular_capability_universal.cc
+++ b/cellular_capability_universal.cc
@@ -43,6 +43,8 @@
 #define MM_MODEM_SIMPLE_CONNECT_RM_PROTOCOL "rm-protocol"
 
 using base::Bind;
+using base::Callback;
+using base::Closure;
 using std::string;
 using std::vector;
 
@@ -161,18 +163,117 @@
                                                  cellular()->dbus_owner()));
   // Do not create a SIM proxy until the device is enabled because we
   // do not yet know the object path of the sim object.
-
   // TODO(jglasgow): register callbacks
 }
 
 void CellularCapabilityUniversal::StartModem(Error *error,
-                                       const ResultCallback &callback) {
-  OnUnsupportedOperation(__func__, error);
+                                             const ResultCallback &callback) {
+  VLOG(2) << __func__;
+
+  InitProxies();
+
+  // Start by trying to enable the modem
+  CHECK(!callback.is_null());
+  modem_proxy_->Enable(
+      true,
+      error,
+      Bind(&CellularCapabilityUniversal::Start_EnableModemCompleted,
+           weak_ptr_factory_.GetWeakPtr(), callback),
+      kTimeoutEnable);
+  if (error->IsFailure())
+    callback.Run(*error);
+}
+
+void CellularCapabilityUniversal::Start_EnableModemCompleted(
+    const ResultCallback &callback, const Error &error) {
+  if (error.IsFailure()) {
+    callback.Run(error);
+    return;
+  }
+
+  // After modem is enabled, it should be possible to get properties
+  // TODO(jglasgow): handle errors from GetProperties
+  GetProperties();
+
+  // Try to register
+  Error local_error;
+  modem_3gpp_proxy_->Register(
+      selected_network_, &local_error,
+      Bind(&CellularCapabilityUniversal::Start_RegisterCompleted,
+           weak_ptr_factory_.GetWeakPtr(), callback),
+      kTimeoutRegister);
+  if (local_error.IsFailure()) {
+    callback.Run(local_error);
+    return;
+  }
+}
+
+void CellularCapabilityUniversal::Start_RegisterCompleted(
+    const ResultCallback &callback, const Error &error) {
+  if (error.IsSuccess()) {
+    // If registered, get the registration state and signal quality.
+    GetRegistrationState();
+    GetSignalQuality();
+  } else {
+    LOG(ERROR) << "registration failed: " << error;
+  }
+
+  // Ignore registration errors, because that just means there is no signal.
+  callback.Run(Error());
 }
 
 void CellularCapabilityUniversal::StopModem(Error *error,
                                       const ResultCallback &callback) {
-  OnUnsupportedOperation(__func__, error);
+  VLOG(2) << __func__;
+  CHECK(!callback.is_null());
+  CHECK(error);
+  bool connected = false;
+  string all_bearers("/");  // Represents all bearers for disconnect operations
+
+  if (connected) {
+    modem_simple_proxy_->Disconnect(
+        all_bearers,
+        error,
+        Bind(&CellularCapabilityUniversal::Stop_DisconnectCompleted,
+             weak_ptr_factory_.GetWeakPtr(), callback),
+        kTimeoutDefault);
+    if (error->IsFailure())
+      callback.Run(*error);
+  } else {
+    Error error;
+    Closure task = Bind(&CellularCapabilityUniversal::Stop_Disable,
+                        weak_ptr_factory_.GetWeakPtr(),
+                        callback);
+    cellular()->dispatcher()->PostTask(task);
+  }
+}
+
+void CellularCapabilityUniversal::Stop_DisconnectCompleted(
+    const ResultCallback &callback, const Error &error) {
+  VLOG(2) << __func__;
+
+  LOG_IF(ERROR, error.IsFailure()) << "Disconnect failed.  Ignoring.";
+  Stop_Disable(callback);
+}
+
+void CellularCapabilityUniversal::Stop_Disable(const ResultCallback &callback) {
+  Error error;
+  modem_proxy_->Enable(
+      false, &error,
+      Bind(&CellularCapabilityUniversal::Stop_DisableCompleted,
+           weak_ptr_factory_.GetWeakPtr(), callback),
+      kTimeoutDefault);
+  if (error.IsFailure())
+    callback.Run(error);
+}
+
+void CellularCapabilityUniversal::Stop_DisableCompleted(
+    const ResultCallback &callback, const Error &error) {
+  VLOG(2) << __func__;
+
+  if (error.IsSuccess())
+    ReleaseProxies();
+  callback.Run(error);
 }
 
 void CellularCapabilityUniversal::Connect(const DBusPropertiesMap &properties,
@@ -327,8 +428,7 @@
   On3GPPRegistrationChanged(state, operator_code, operator_name);
 }
 
-void CellularCapabilityUniversal::GetProperties(
-    const ResultCallback &callback) {
+void CellularCapabilityUniversal::GetProperties() {
   VLOG(2) << __func__;
 
   // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
@@ -351,19 +451,23 @@
   if (imei_.empty()) {
     imei_ = modem_3gpp_proxy_->Imei();
   }
-  if (imsi_.empty()) {
-    imsi_ = sim_proxy_->Imsi();
-  }
-  if (spn_.empty()) {
-    spn_ = sim_proxy_->OperatorName();
-    // TODO(jglasgow): May eventually want to get SPDI, etc
+
+  string sim_path = modem_proxy_->Sim();
+  OnSimPathChanged(sim_path);
+
+  if (sim_proxy_.get()) {
+    if (imsi_.empty()) {
+      imsi_ = sim_proxy_->Imsi();
+    }
+    if (spn_.empty()) {
+      spn_ = sim_proxy_->OperatorName();
+      // TODO(jglasgow): May eventually want to get SPDI, etc
+    }
   }
   if (mdn_.empty()) {
     // TODO(jglasgow): use OwnNumbers()
   }
   GetRegistrationState();
-
-  callback.Run(Error());
 }
 
 string CellularCapabilityUniversal::CreateFriendlyServiceName() {
@@ -759,8 +863,14 @@
     const string &interface,
     const DBusPropertiesMap &changed_properties,
     const vector<std::string> &invalidated_properties) {
-  // TODO(jglasgow): implement properties changed handling
-  NOTIMPLEMENTED();
+  if (interface == MM_DBUS_INTERFACE_MODEM) {
+    string value;
+    if (DBusProperties::GetString(changed_properties,
+                                  MM_MODEM_PROPERTY_SIM, &value))
+      OnSimPathChanged(value);
+    // TODO(jglasgow): handle additional properties on the modem interface
+  }
+  // TODO(jglasgow): handle additional interfaces
 }
 
 void CellularCapabilityUniversal::OnModem3GPPPropertiesChanged(
@@ -803,4 +913,17 @@
   cellular()->HandleNewSignalQuality(quality);
 }
 
+void CellularCapabilityUniversal::OnSimPathChanged(
+    const string &sim_path) {
+  if (sim_path == sim_path_)
+    return;
+
+  mm1::SimProxyInterface *proxy = NULL;
+  if (!sim_path.empty())
+    proxy = proxy_factory()->CreateSimProxy(sim_path,
+                                            cellular()->dbus_owner());
+  sim_path_ = sim_path;
+  sim_proxy_.reset(proxy);
+}
+
 }  // namespace shill
diff --git a/cellular_capability_universal.h b/cellular_capability_universal.h
index 5592f05..47d3c59 100644
--- a/cellular_capability_universal.h
+++ b/cellular_capability_universal.h
@@ -51,7 +51,7 @@
   virtual void UpdateStatus(const DBusPropertiesMap &properties);
   virtual void SetupConnectProperties(DBusPropertiesMap *properties);
   virtual void GetRegistrationState();
-  virtual void GetProperties(const ResultCallback &callback);
+  virtual void GetProperties();
   virtual void Register(const ResultCallback &callback);
 
   virtual void RegisterOnNetwork(const std::string &network_id,
@@ -125,6 +125,19 @@
   FRIEND_TEST(CellularTest, StartUniversalRegister);
   FRIEND_TEST(ModemTest, CreateDeviceFromProperties);
 
+  // Methods used in starting a modem
+  void Start_EnableModemCompleted(const ResultCallback &callback,
+                                  const Error &error);
+  void Start_RegisterCompleted(const ResultCallback &callback,
+                               const Error &error);
+
+  // Methods used in stopping a modem
+  void Stop_DisconnectCompleted(const ResultCallback &callback,
+                               const Error &error);
+  void Stop_Disable(const ResultCallback &callback);
+  void Stop_DisableCompleted(const ResultCallback &callback,
+                             const Error &error);
+
   // TOOD(jglasgow): document what this does!!!!!
   void SetAccessTechnologies(uint32 access_technologies);
 
@@ -165,6 +178,10 @@
                                         const std::string &operator_name);
   virtual void OnSignalQualityChanged(uint32 quality);
 
+  // Updates the sim_path_ variable and creates a new proxy to the
+  // DBUS ModemManager1.Sim interface
+  virtual void OnSimPathChanged(const std::string &sim_path);
+
   // Method callbacks
   virtual void OnRegisterReply(const ResultCallback &callback,
                                const Error &error);
@@ -208,6 +225,7 @@
   uint16 scan_interval_;
   SimLockStatus sim_lock_status_;
   Stringmaps apn_list_;
+  std::string sim_path_;
 
   static unsigned int friendly_service_name_id_;
 
diff --git a/cellular_capability_universal_unittest.cc b/cellular_capability_universal_unittest.cc
new file mode 100644
index 0000000..c19f14c
--- /dev/null
+++ b/cellular_capability_universal_unittest.cc
@@ -0,0 +1,203 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "shill/cellular_capability_universal.h"
+
+#include <base/bind.h>
+#include <chromeos/dbus/service_constants.h>
+#include <gtest/gtest.h>
+#include <mobile_provider.h>
+
+#include "shill/cellular.h"
+#include "shill/cellular_service.h"
+#include "shill/error.h"
+#include "shill/event_dispatcher.h"
+#include "shill/mock_adaptors.h"
+#include "shill/mock_glib.h"
+#include "shill/mock_manager.h"
+#include "shill/mock_metrics.h"
+#include "shill/mock_mm1_modem_modem3gpp_proxy.h"
+#include "shill/mock_mm1_modem_modemcdma_proxy.h"
+#include "shill/mock_mm1_modem_proxy.h"
+#include "shill/mock_mm1_modem_simple_proxy.h"
+#include "shill/mock_mm1_sim_proxy.h"
+#include "shill/mock_profile.h"
+#include "shill/mock_rtnl_handler.h"
+#include "shill/nice_mock_control.h"
+#include "shill/proxy_factory.h"
+
+using base::Bind;
+using base::Unretained;
+using std::string;
+using testing::InSequence;
+using testing::NiceMock;
+using testing::Return;
+using testing::_;
+
+namespace shill {
+
+MATCHER(IsSuccess, "") {
+  return arg.IsSuccess();
+}
+MATCHER(IsFailure, "") {
+  return arg.IsFailure();
+}
+
+class CellularCapabilityUniversalTest : public testing::Test {
+ public:
+  CellularCapabilityUniversalTest()
+      : manager_(&control_, &dispatcher_, &metrics_, &glib_),
+        cellular_(new Cellular(&control_,
+                               &dispatcher_,
+                               NULL,
+                               &manager_,
+                               "",
+                               "",
+                               0,
+                               Cellular::kTypeUniversal,
+                               "",
+                               "",
+                               NULL)),
+        modem_3gpp_proxy_(new mm1::MockModemModem3gppProxy()),
+        modem_cdma_proxy_(new mm1::MockModemModemCdmaProxy()),
+        modem_proxy_(new mm1::MockModemProxy()),
+        modem_simple_proxy_(new mm1::MockModemSimpleProxy()),
+        sim_proxy_(new mm1::MockSimProxy()),
+        proxy_factory_(this),
+        capability_(NULL),
+        device_adaptor_(NULL) {}
+
+  virtual ~CellularCapabilityUniversalTest() {
+    cellular_->service_ = NULL;
+    capability_ = NULL;
+    device_adaptor_ = NULL;
+  }
+
+  virtual void SetUp() {
+    capability_ = dynamic_cast<CellularCapabilityUniversal *>(
+        cellular_->capability_.get());
+    capability_->proxy_factory_ = &proxy_factory_;
+    device_adaptor_ =
+        dynamic_cast<NiceMock<DeviceMockAdaptor> *>(cellular_->adaptor());
+  }
+
+  virtual void TearDown() {
+    capability_->proxy_factory_ = NULL;
+  }
+
+  void InvokeEnable(bool enable, Error *error,
+                    const ResultCallback &callback, int timeout) {
+    callback.Run(Error());
+  }
+  void InvokeEnableFail(bool enable, Error *error,
+                        const ResultCallback &callback, int timeout) {
+    callback.Run(Error(Error::kOperationFailed));
+  }
+
+  MOCK_METHOD1(TestCallback, void(const Error &error));
+
+ protected:
+  static const char kImei[];
+
+  class TestProxyFactory : public ProxyFactory {
+   public:
+    explicit TestProxyFactory(CellularCapabilityUniversalTest *test) :
+        test_(test) {}
+
+    virtual mm1::ModemModem3gppProxyInterface *CreateMM1ModemModem3gppProxy(
+        const std::string &/* path */,
+        const std::string &/* service */) {
+      return test_->modem_3gpp_proxy_.release();
+    }
+
+    virtual mm1::ModemModemCdmaProxyInterface *CreateMM1ModemModemCdmaProxy(
+        const std::string &/* path */,
+        const std::string &/* service */) {
+      return test_->modem_cdma_proxy_.release();
+    }
+
+    virtual mm1::ModemProxyInterface *CreateMM1ModemProxy(
+        const std::string &/* path */,
+        const std::string &/* service */) {
+      return test_->modem_proxy_.release();
+    }
+
+    virtual mm1::ModemSimpleProxyInterface *CreateMM1ModemSimpleProxy(
+        const std::string &/* path */,
+        const std::string &/* service */) {
+      return test_->modem_simple_proxy_.release();
+    }
+
+    virtual mm1::SimProxyInterface *CreateSimProxy(
+        const std::string &/* path */,
+        const std::string &/* service */) {
+      return test_->sim_proxy_.release();
+    }
+
+   private:
+    CellularCapabilityUniversalTest *test_;
+  };
+
+  NiceMockControl control_;
+  EventDispatcher dispatcher_;
+  MockMetrics metrics_;
+  MockGLib glib_;
+  MockManager manager_;
+  CellularRefPtr cellular_;
+  scoped_ptr<mm1::MockModemModem3gppProxy> modem_3gpp_proxy_;
+  scoped_ptr<mm1::MockModemModemCdmaProxy> modem_cdma_proxy_;
+  scoped_ptr<mm1::MockModemProxy> modem_proxy_;
+  scoped_ptr<mm1::MockModemSimpleProxy> modem_simple_proxy_;
+  scoped_ptr<mm1::MockSimProxy> sim_proxy_;
+  TestProxyFactory proxy_factory_;
+  CellularCapabilityUniversal *capability_;  // Owned by |cellular_|.
+  NiceMock<DeviceMockAdaptor> *device_adaptor_;  // Owned by |cellular_|.
+};
+
+const char CellularCapabilityUniversalTest::kImei[] = "999911110000";
+
+TEST_F(CellularCapabilityUniversalTest, StartModem) {
+  EXPECT_CALL(*modem_proxy_,
+              Enable(true, _, _, CellularCapability::kTimeoutEnable))
+      .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::InvokeEnable));
+  EXPECT_CALL(*modem_proxy_, AccessTechnologies())
+      .WillOnce(Return(MM_MODEM_ACCESS_TECHNOLOGY_LTE|
+                       MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS));
+  EXPECT_CALL(*modem_3gpp_proxy_, EnabledFacilityLocks()).WillOnce(Return(0));
+  ::DBus::Struct< uint32_t, bool > quality;
+  quality._1 = 90;
+  quality._2 = true;
+  EXPECT_CALL(*modem_proxy_, SignalQuality()).WillOnce(Return(quality));
+  EXPECT_CALL(*modem_proxy_, Sim()).WillOnce(Return(""));
+  EXPECT_CALL(*modem_3gpp_proxy_, Imei()).WillOnce(Return(kImei));
+  EXPECT_CALL(*modem_3gpp_proxy_, RegistrationState())
+      .WillOnce(Return(MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN));
+
+  // After setup we lose pointers to the proxies, so it is hard to set
+  // expectations.
+  SetUp();
+
+  Error error;
+  ResultCallback callback =
+      Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
+  capability_->StartModem(&error, callback);
+  EXPECT_TRUE(error.IsSuccess());
+}
+
+TEST_F(CellularCapabilityUniversalTest, StartModemFail) {
+  EXPECT_CALL(*modem_proxy_,
+              Enable(true, _, _, CellularCapability::kTimeoutEnable))
+      .WillOnce(
+          Invoke(this, &CellularCapabilityUniversalTest::InvokeEnableFail));
+  EXPECT_CALL(*this, TestCallback(IsFailure()));
+  ResultCallback callback =
+      Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
+  SetUp();
+
+  Error error;
+  capability_->StartModem(&error, callback);
+  EXPECT_TRUE(error.IsSuccess());
+}
+
+}  // namespace shill
diff --git a/mock_mm1_modem_modem3gpp_proxy.cc b/mock_mm1_modem_modem3gpp_proxy.cc
new file mode 100644
index 0000000..16272a8
--- /dev/null
+++ b/mock_mm1_modem_modem3gpp_proxy.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "shill/mock_mm1_modem_modem3gpp_proxy.h"
+
+namespace shill {
+namespace mm1 {
+
+MockModemModem3gppProxy::MockModemModem3gppProxy() {}
+
+MockModemModem3gppProxy::~MockModemModem3gppProxy() {}
+
+}  // namespace mm1
+}  // namespace shill
diff --git a/mock_mm1_modem_modem3gpp_proxy.h b/mock_mm1_modem_modem3gpp_proxy.h
new file mode 100644
index 0000000..9e58bcd
--- /dev/null
+++ b/mock_mm1_modem_modem3gpp_proxy.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SHILL_MM1_MOCK_MODEM_MODEM3GPP_PROXY_
+#define SHILL_MM1_MOCK_MODEM_MODEM3GPP_PROXY_
+
+#include <string>
+
+#include <base/basictypes.h>
+#include <gmock/gmock.h>
+
+#include "shill/mm1_modem_modem3gpp_proxy_interface.h"
+
+namespace shill {
+namespace mm1 {
+
+class MockModemModem3gppProxy : public ModemModem3gppProxyInterface {
+ public:
+  MockModemModem3gppProxy();
+  virtual ~MockModemModem3gppProxy();
+
+  MOCK_METHOD4(Register, void(const std::string &operator_id,
+                              Error *error,
+                              const ResultCallback &callback,
+                              int timeout));
+  MOCK_METHOD3(Scan, void(Error *error,
+                          const DBusPropertyMapsCallback &callback,
+                          int timeout));
+
+  // Properties.
+  MOCK_METHOD0(Imei, std::string());
+  MOCK_METHOD0(RegistrationState, uint32_t());
+  MOCK_METHOD0(OperatorCode, std::string());
+  MOCK_METHOD0(OperatorName, std::string());
+  MOCK_METHOD0(EnabledFacilityLocks, uint32_t());
+
+  DISALLOW_COPY_AND_ASSIGN(MockModemModem3gppProxy);
+};
+
+}  // namespace mm1
+}  // namespace shill
+
+#endif  // SHILL_MM1_MOCK_MODEM_MODEM3GPP_PROXY_
diff --git a/mock_mm1_modem_modemcdma_proxy.cc b/mock_mm1_modem_modemcdma_proxy.cc
new file mode 100644
index 0000000..be3a9c7
--- /dev/null
+++ b/mock_mm1_modem_modemcdma_proxy.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "shill/mock_mm1_modem_modemcdma_proxy.h"
+
+namespace shill {
+namespace mm1 {
+
+MockModemModemCdmaProxy::MockModemModemCdmaProxy() {}
+
+MockModemModemCdmaProxy::~MockModemModemCdmaProxy() {}
+
+}  // namespace mm1
+}  // namespace shill
diff --git a/mock_mm1_modem_modemcdma_proxy.h b/mock_mm1_modem_modemcdma_proxy.h
new file mode 100644
index 0000000..26d92bb
--- /dev/null
+++ b/mock_mm1_modem_modemcdma_proxy.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SHILL_MM1_MOCK_MODEM_MODEMCDMA_PROXY_H_
+#define SHILL_MM1_MOCK_MODEM_MODEMCDMA_PROXY_H_
+
+#include <string>
+
+#include <base/basictypes.h>
+#include <gmock/gmock.h>
+
+#include "shill/mm1_modem_modemcdma_proxy_interface.h"
+
+namespace shill {
+namespace mm1 {
+
+class MockModemModemCdmaProxy : public ModemModemCdmaProxyInterface {
+ public:
+  MockModemModemCdmaProxy();
+  virtual ~MockModemModemCdmaProxy();
+
+  MOCK_METHOD4(Activate, void(
+      const std::string &carrier,
+      Error *error,
+      const ResultCallback &callback,
+      int timeout));
+
+  MOCK_METHOD4(ActivateManual, void(
+      const DBusPropertiesMap &properties,
+      Error *error,
+      const ResultCallback &callback,
+      int timeout));
+
+  MOCK_METHOD1(set_activation_state_callback,
+               void(const ActivationStateSignalCallback &callback));
+
+  // Properties.
+  MOCK_METHOD0(Meid, std::string());
+  MOCK_METHOD0(Esn, std::string());
+  MOCK_METHOD0(Sid, uint32_t());
+  MOCK_METHOD0(Nid, uint32_t());
+  MOCK_METHOD0(Cdma1xRegistrationState, uint32_t());
+  MOCK_METHOD0(EvdoRegistrationState, uint32_t());
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockModemModemCdmaProxy);
+};
+
+}  // namespace mm1
+}  // namespace shill
+
+#endif  // SHILL_MM1_MOCK_MODEM_MODEMCDMA_PROXY_H_
diff --git a/mock_mm1_modem_proxy.cc b/mock_mm1_modem_proxy.cc
new file mode 100644
index 0000000..fb8403c
--- /dev/null
+++ b/mock_mm1_modem_proxy.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "shill/mock_mm1_modem_proxy.h"
+
+namespace shill {
+namespace mm1 {
+
+MockModemProxy::MockModemProxy() {}
+
+MockModemProxy::~MockModemProxy() {}
+
+}  // namespace mm1
+}  // namespace shill
diff --git a/mock_mm1_modem_proxy.h b/mock_mm1_modem_proxy.h
new file mode 100644
index 0000000..8e7a78e
--- /dev/null
+++ b/mock_mm1_modem_proxy.h
@@ -0,0 +1,98 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SHILL_MM1_MOCK_MODEM_PROXY_
+#define SHILL_MM1_MOCK_MODEM_PROXY_
+
+#include <string>
+
+#include <base/basictypes.h>
+#include <gmock/gmock.h>
+
+#include "shill/mm1_modem_proxy_interface.h"
+
+namespace shill {
+namespace mm1 {
+
+class MockModemProxy : public ModemProxyInterface {
+ public:
+  MockModemProxy();
+  virtual ~MockModemProxy();
+
+  // Inherited methods from ModemProxyInterface.
+  MOCK_METHOD4(Enable, void(bool enable,
+                            Error *error,
+                            const ResultCallback &callback,
+                            int timeout));
+  MOCK_METHOD3(ListBearers, void(Error *error,
+                                 const DBusPathsCallback &callback,
+                                 int timeout));
+  MOCK_METHOD4(CreateBearer, void(const DBusPropertiesMap &properties,
+                                  Error *error,
+                                  const DBusPathCallback &callback,
+                                  int timeout));
+  MOCK_METHOD4(DeleteBearer, void(const ::DBus::Path &bearer,
+                                  Error *error,
+                                  const ResultCallback &callback,
+                                  int timeout));
+  MOCK_METHOD3(Reset, void(Error *error,
+                           const ResultCallback &callback,
+                           int timeout));
+  MOCK_METHOD4(FactoryReset, void(const std::string &code,
+                                  Error *error,
+                                  const ResultCallback &callback,
+                                  int timeout));
+  MOCK_METHOD5(SetAllowedModes, void(const uint32_t &modes,
+                                     const uint32_t &preferred,
+                                     Error *error,
+                                     const ResultCallback &callback,
+                                     int timeout));
+  MOCK_METHOD4(SetBands, void(const std::vector< uint32_t > &bands,
+                              Error *error,
+                              const ResultCallback &callback,
+                              int timeout));
+  MOCK_METHOD5(Command, void(const std::string &cmd,
+                             const uint32_t &user_timeout,
+                             Error *error,
+                             const StringCallback &callback,
+                             int timeout));
+  MOCK_METHOD1(set_state_changed_callback, void(
+      const ModemStateChangedSignalCallback &callback));
+
+  // Inherited properties from ModemProxyInterface.
+  MOCK_METHOD0(Sim, const ::DBus::Path());
+  MOCK_METHOD0(ModemCapabilities, uint32_t());
+  MOCK_METHOD0(CurrentCapabilities, uint32_t());
+  MOCK_METHOD0(MaxBearers, uint32_t());
+  MOCK_METHOD0(MaxActiveBearers, uint32_t());
+  MOCK_METHOD0(Manufacturer, const std::string());
+  MOCK_METHOD0(Model, const std::string());
+  MOCK_METHOD0(Revision, const std::string());
+  MOCK_METHOD0(DeviceIdentifier, const std::string());
+  MOCK_METHOD0(Device, const std::string());
+  MOCK_METHOD0(Driver, const std::string());
+  MOCK_METHOD0(Plugin, const std::string());
+  MOCK_METHOD0(EquipmentIdentifier, const std::string());
+  MOCK_METHOD0(UnlockRequired, uint32_t());
+  typedef std::map< uint32_t, uint32_t > RetryData;
+  MOCK_METHOD0(UnlockRetries, const RetryData());
+  MOCK_METHOD0(State, uint32_t());
+  MOCK_METHOD0(AccessTechnologies, uint32_t());
+  typedef ::DBus::Struct< uint32_t, bool > SignalQualityData;
+  MOCK_METHOD0(SignalQuality, const SignalQualityData());
+  MOCK_METHOD0(OwnNumbers, const std::vector< std::string >());
+  MOCK_METHOD0(SupportedModes, uint32_t());
+  MOCK_METHOD0(AllowedModes, uint32_t());
+  MOCK_METHOD0(PreferredMode, uint32_t());
+  MOCK_METHOD0(SupportedBands, const std::vector< uint32_t >());
+  MOCK_METHOD0(Bands, const std::vector< uint32_t >());
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockModemProxy);
+};
+
+}  // namespace mm1
+}  // namespace shill
+
+#endif  // SHILL_MM1_MOCK_MODEM_PROXY_
diff --git a/mock_mm1_modem_simple_proxy.cc b/mock_mm1_modem_simple_proxy.cc
new file mode 100644
index 0000000..42ecb0f
--- /dev/null
+++ b/mock_mm1_modem_simple_proxy.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "shill/mock_mm1_modem_simple_proxy.h"
+
+namespace shill {
+namespace mm1 {
+
+MockModemSimpleProxy::MockModemSimpleProxy() {}
+
+MockModemSimpleProxy::~MockModemSimpleProxy() {}
+
+}  // namespace mm1
+}  // namespace shill
diff --git a/mock_mm1_modem_simple_proxy.h b/mock_mm1_modem_simple_proxy.h
new file mode 100644
index 0000000..e41e0db
--- /dev/null
+++ b/mock_mm1_modem_simple_proxy.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SHILL_MM1_MOCK_MODEM_SIMPLE_PROXY_
+#define SHILL_MM1_MOCK_MODEM_SIMPLE_PROXY_
+
+#include <string>
+
+#include <base/basictypes.h>
+#include <gmock/gmock.h>
+
+#include "shill/mm1_modem_simple_proxy_interface.h"
+
+namespace shill {
+namespace mm1 {
+
+class MockModemSimpleProxy : public ModemSimpleProxyInterface {
+ public:
+  MockModemSimpleProxy();
+  virtual ~MockModemSimpleProxy();
+
+  MOCK_METHOD4(Connect, void(const DBusPropertiesMap &properties,
+                             Error *error,
+                             const DBusPathCallback &callback,
+                             int timeout));
+  MOCK_METHOD4(Disconnect, void(const ::DBus::Path &bearer,
+                                Error *error,
+                                const ResultCallback &callback,
+                                int timeout));
+  MOCK_METHOD3(GetStatus, void(Error *error,
+                               const DBusPropertyMapCallback &callback,
+                               int timeout));
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockModemSimpleProxy);
+};
+
+}  // namespace mm1
+}  // namespace shill
+
+#endif  // SHILL_MM1_MOCK_MODEM_SIMPLE_PROXY_
diff --git a/mock_mm1_sim_proxy.cc b/mock_mm1_sim_proxy.cc
new file mode 100644
index 0000000..4a117f9
--- /dev/null
+++ b/mock_mm1_sim_proxy.cc
@@ -0,0 +1,15 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "shill/mock_mm1_sim_proxy.h"
+
+namespace shill {
+namespace mm1 {
+
+MockSimProxy::MockSimProxy() {}
+
+MockSimProxy::~MockSimProxy() {}
+
+}  // namespace mm1
+}  // namespace shill
diff --git a/mock_mm1_sim_proxy.h b/mock_mm1_sim_proxy.h
new file mode 100644
index 0000000..00b50a7
--- /dev/null
+++ b/mock_mm1_sim_proxy.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SHILL_MM1_MOCK_SIM_PROXY_
+#define SHILL_MM1_MOCK_SIM_PROXY_
+
+#include <string>
+
+#include <base/basictypes.h>
+#include <gmock/gmock.h>
+
+#include "shill/mm1_sim_proxy_interface.h"
+
+namespace shill {
+namespace mm1 {
+
+class MockSimProxy : public SimProxyInterface {
+ public:
+  MockSimProxy();
+  virtual ~MockSimProxy();
+
+  MOCK_METHOD4(SendPin, void(const std::string &pin,
+                             Error *error,
+                             const ResultCallback &callback,
+                             int timeout));
+  MOCK_METHOD5(SendPuk, void(const std::string &puk,
+                             const std::string &pin,
+                             Error *error,
+                             const ResultCallback &callback,
+                             int timeout));
+  MOCK_METHOD5(EnablePin, void(const std::string &pin,
+                               const bool enabled,
+                               Error *error,
+                               const ResultCallback &callback,
+                               int timeout));
+  MOCK_METHOD5(ChangePin, void(const std::string &old_pin,
+                               const std::string &new_pin,
+                               Error *error,
+                               const ResultCallback &callback,
+                               int timeout));
+
+  MOCK_METHOD0(SimIdentifier, const std::string());
+  MOCK_METHOD0(Imsi, const std::string());
+  MOCK_METHOD0(OperatorIdentifier, const std::string());
+  MOCK_METHOD0(OperatorName, const std::string());
+
+  DISALLOW_COPY_AND_ASSIGN(MockSimProxy);
+};
+
+}  // namespace mm1
+}  // namespace shill
+
+#endif  // SHILL_MM1_MOCK_SIM_PROXY_