shill: Obtain the payment and usage URLs from ModemManager.

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

Change-Id: I98d800cd69684bdf9c201348c00ff79152e51e45
Reviewed-on: http://gerrit.chromium.org/gerrit/6106
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Chris Masone <cmasone@chromium.org>
Reviewed-by: Jason Glasgow <jglasgow@chromium.org>
diff --git a/cellular.cc b/cellular.cc
index 5473d01..6b036a2 100644
--- a/cellular.cc
+++ b/cellular.cc
@@ -258,9 +258,13 @@
   DBusProperties::GetUint16(properties, "prl_version", &prl_version_);
   DBusProperties::GetString(
       properties, "firmware_revision", &firmware_revision_);
-  // TODO(petkov): Get payment_url/olp_url/usage_url. For now, get these from
-  // ModemManager to match flimflam. In the future, provide a plugin API to get
-  // these directly from the modem driver.
+
+  // TODO(petkov): For now, get the payment and usage URLs from ModemManager to
+  // match flimflam. In the future, provide a plugin API to get these directly
+  // from the modem driver.
+  DBusProperties::GetString(properties, "payment_url", &payment_url_);
+  DBusProperties::GetString(properties, "usage_url", &usage_url_);
+
   if (type_ == kTypeCDMA) {
     // TODO(petkov): Get activation_state.
   }
@@ -397,9 +401,10 @@
   CHECK(!service_.get());
   service_ =
       new CellularService(control_interface_, dispatcher_, manager_, this);
+  service_->set_payment_url(payment_url_);
+  service_->set_usage_url(usage_url_);
   // TODO(petkov): Set activation_state.
   // TODO(petkov): Set operator.
-  // TODO(petkov): Set old_url/usage_url.
 }
 
 bool Cellular::TechnologyIs(const Device::Technology type) const {
@@ -469,6 +474,20 @@
   }
 }
 
+void Cellular::OnCDMAActivationStateChanged(
+    uint32 activation_state,
+    uint32 activation_error,
+    const DBusPropertiesMap &status_changes) {
+  CHECK_EQ(kTypeCDMA, type_);
+  DBusProperties::GetString(status_changes, "mdn", &mdn_);
+  DBusProperties::GetString(status_changes, "min", &min_);
+  if (DBusProperties::GetString(status_changes, "payment_url", &payment_url_) &&
+      service_.get()) {
+    service_->set_payment_url(payment_url_);
+  }
+  // TODO(petkov): Handle activation state updates.
+}
+
 void Cellular::OnCDMARegistrationStateChanged(uint32 state_1x,
                                               uint32 state_evdo) {
   CHECK_EQ(kTypeCDMA, type_);
diff --git a/cellular.h b/cellular.h
index 5dadff0..646a71c 100644
--- a/cellular.h
+++ b/cellular.h
@@ -208,6 +208,10 @@
   bool IsModemRegistered();
 
   // Signal callbacks inherited from ModemCDMAProxyListener.
+  virtual void OnCDMAActivationStateChanged(
+      uint32 activation_state,
+      uint32 activation_error,
+      const DBusPropertiesMap &status_changes);
   virtual void OnCDMARegistrationStateChanged(uint32 state_1x,
                                               uint32 state_evdo);
   virtual void OnCDMASignalQualityChanged(uint32 strength);
@@ -233,6 +237,9 @@
 
   ScopedRunnableMethodFactory<Cellular> task_factory_;
 
+  std::string payment_url_;
+  std::string usage_url_;
+
   // Properties
   bool allow_roaming_;
   std::string carrier_;
diff --git a/cellular_service.cc b/cellular_service.cc
index cbe9e02..654c5b4 100644
--- a/cellular_service.cc
+++ b/cellular_service.cc
@@ -40,6 +40,7 @@
 
   store_.RegisterConstUint8(flimflam::kSignalStrengthProperty, &strength_);
   store_.RegisterConstString(flimflam::kTypeProperty, &type_);
+  store_.RegisterConstString(flimflam::kUsageURLProperty, &usage_url_);
 }
 
 CellularService::~CellularService() { }
diff --git a/cellular_service.h b/cellular_service.h
index f1b2c0a..1c75358 100644
--- a/cellular_service.h
+++ b/cellular_service.h
@@ -27,12 +27,18 @@
                   const CellularRefPtr &device);
   virtual ~CellularService();
 
-  void Connect();
-  void Disconnect();
+  virtual void Connect();
+  virtual void Disconnect();
 
   uint8 strength() const { return strength_; }
   void set_strength(uint8 strength) { strength_ = strength; }
 
+  const std::string &payment_url() const { return payment_url_; }
+  void set_payment_url(const std::string &url) { payment_url_ = url; }
+
+  const std::string &usage_url() const { return usage_url_; }
+  void set_usage_url(const std::string &url) { usage_url_ = url; }
+
  protected:
   virtual std::string CalculateState() { return "idle"; }
 
@@ -44,12 +50,13 @@
   std::string roaming_state_;
   std::string payment_url_;
   uint8 strength_;
+  std::string usage_url_;
 
   std::map<std::string, std::string> apn_info_;
   std::map<std::string, std::string> last_good_apn_info_;
 
  private:
-  std::string GetDeviceRpcId();
+  virtual std::string GetDeviceRpcId();
 
   CellularRefPtr cellular_;
   const std::string type_;
diff --git a/cellular_unittest.cc b/cellular_unittest.cc
index c326e6b..ce9670d 100644
--- a/cellular_unittest.cc
+++ b/cellular_unittest.cc
@@ -348,13 +348,19 @@
           SetArgumentPointee<1>(MM_MODEM_CDMA_REGISTRATION_STATE_HOME)));
   EXPECT_CALL(*cdma_proxy_, GetSignalQuality()).WillOnce(Return(90));
   device_->cdma_proxy_.reset(cdma_proxy_.release());
+  static const char kPaymentURL[] = "https://payment.url";
+  static const char kUsageURL[] = "https://usage.url";
+  device_->payment_url_ = kPaymentURL;
+  device_->usage_url_ = kUsageURL;
   device_->GetModemRegistrationState();
   dispatcher_.DispatchPendingEvents();
   EXPECT_EQ(MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED,
             device_->cdma_.registration_state_1x);
   EXPECT_EQ(MM_MODEM_CDMA_REGISTRATION_STATE_HOME,
             device_->cdma_.registration_state_evdo);
-  EXPECT_TRUE(device_->service_.get());
+  ASSERT_TRUE(device_->service_.get());
+  EXPECT_EQ(kPaymentURL, device_->service_->payment_url());
+  EXPECT_EQ(kUsageURL, device_->service_->usage_url());
 }
 
 TEST_F(CellularTest, GetCDMASignalQuality) {
diff --git a/modem_cdma_proxy.cc b/modem_cdma_proxy.cc
index 4380c2d..4628fb8 100644
--- a/modem_cdma_proxy.cc
+++ b/modem_cdma_proxy.cc
@@ -40,9 +40,10 @@
     const uint32 &activation_state,
     const uint32 &activation_error,
     const DBusPropertiesMap &status_changes) {
-  VLOG(2) << __func__;
-  // TODO(petkov): Implement this.
-  NOTIMPLEMENTED();
+  VLOG(2) << __func__ << "(" << activation_state << ", " << activation_error
+          << ")";
+  listener_->OnCDMAActivationStateChanged(
+      activation_state, activation_error, status_changes);
 }
 
 void ModemCDMAProxy::Proxy::SignalQuality(const uint32 &quality) {
diff --git a/modem_cdma_proxy_interface.h b/modem_cdma_proxy_interface.h
index 04f058e..9a91f3e 100644
--- a/modem_cdma_proxy_interface.h
+++ b/modem_cdma_proxy_interface.h
@@ -26,6 +26,10 @@
  public:
   virtual ~ModemCDMAProxyListener() {}
 
+  virtual void OnCDMAActivationStateChanged(
+      uint32 activation_state,
+      uint32 activation_error,
+      const DBusPropertiesMap &status_changes) = 0;
   virtual void OnCDMARegistrationStateChanged(uint32 state_1x,
                                               uint32 state_evdo) = 0;
   virtual void OnCDMASignalQualityChanged(uint32 strength) = 0;