shill: cellular: Update online payment portal when available.

BUG=chrome-os-partner:11985
TEST=Build and run unit tests.

Change-Id: I50085707907cfa14251f76eba1b57d3cf0604938
Reviewed-on: https://gerrit.chromium.org/gerrit/37507
Commit-Ready: Ben Chan <benchan@chromium.org>
Reviewed-by: Ben Chan <benchan@chromium.org>
Tested-by: Ben Chan <benchan@chromium.org>
diff --git a/cellular.h b/cellular.h
index 67b9ab5..3404c40 100644
--- a/cellular.h
+++ b/cellular.h
@@ -235,6 +235,7 @@
   FRIEND_TEST(CellularCapabilityUniversalTest, Connect);
   FRIEND_TEST(CellularCapabilityUniversalTest, IsServiceActivationRequired);
   FRIEND_TEST(CellularCapabilityUniversalTest, StopModemConnected);
+  FRIEND_TEST(CellularCapabilityUniversalTest, UpdateOLP);
   FRIEND_TEST(CellularServiceTest, FriendlyName);
   FRIEND_TEST(CellularTest, CreateService);
   FRIEND_TEST(CellularTest, Connect);
diff --git a/cellular_capability_universal.cc b/cellular_capability_universal.cc
index 7ad4c37..742bf71 100644
--- a/cellular_capability_universal.cc
+++ b/cellular_capability_universal.cc
@@ -7,6 +7,7 @@
 #include <base/bind.h>
 #include <base/stl_util.h>
 #include <base/stringprintf.h>
+#include <base/string_util.h>
 #include <chromeos/dbus/service_constants.h>
 #include <mobile_provider.h>
 #include <ModemManager/ModemManager.h>
@@ -105,8 +106,8 @@
                              MM_MODEM_ACCESS_TECHNOLOGY_GSM))
     return flimflam::kTechnologyFamilyGsm;
   if (access_technologies & (MM_MODEM_ACCESS_TECHNOLOGY_EVDO0 |
-                              MM_MODEM_ACCESS_TECHNOLOGY_EVDOA |
-                              MM_MODEM_ACCESS_TECHNOLOGY_EVDOB |
+                             MM_MODEM_ACCESS_TECHNOLOGY_EVDOA |
+                             MM_MODEM_ACCESS_TECHNOLOGY_EVDOB |
                              MM_MODEM_ACCESS_TECHNOLOGY_1XRTT))
     return flimflam::kTechnologyFamilyCdma;
   return "";
@@ -373,6 +374,7 @@
       flimflam::kActivationStateNotActivated :
       flimflam::kActivationStateActivated);
   UpdateServingOperator();
+  UpdateOLP();
 }
 
 // Create the list of APNs to try, in the following order:
@@ -552,6 +554,26 @@
   InitAPNList();
 }
 
+void CellularCapabilityUniversal::UpdateOLP() {
+  if (!cellular()->cellular_operator_info())
+    return;
+
+  CellularService::OLP olp;
+  if (!cellular()->cellular_operator_info()->GetOLP(operator_id_, &olp))
+    return;
+
+  string post_data = olp.GetPostData();
+  ReplaceSubstringsAfterOffset(&post_data, 0, "${esn}", esn_);
+  ReplaceSubstringsAfterOffset(&post_data, 0, "${iccid}", sim_identifier_);
+  ReplaceSubstringsAfterOffset(&post_data, 0, "${imei}", imei_);
+  ReplaceSubstringsAfterOffset(&post_data, 0, "${imsi}", imsi_);
+  ReplaceSubstringsAfterOffset(&post_data, 0, "${mdn}", mdn_);
+  ReplaceSubstringsAfterOffset(&post_data, 0, "${meid}", meid_);
+  ReplaceSubstringsAfterOffset(&post_data, 0, "${min}", min_);
+  olp.SetPostData(post_data);
+  cellular()->service()->SetOLP(olp);
+}
+
 void CellularCapabilityUniversal::UpdateOperatorInfo() {
   SLOG(Cellular, 2) << __func__;
   const string &network_id = serving_operator_.GetCode();
@@ -1187,7 +1209,7 @@
 void CellularCapabilityUniversal::OnModem3GPPPropertiesChanged(
     const DBusPropertiesMap &properties,
     const vector<string> &/* invalidated_properties */) {
-  VLOG(2) << __func__;
+  SLOG(Cellular, 2) << __func__;
   string imei;
   if (DBusProperties::GetString(properties,
                                 MM_MODEM_MODEM3GPP_PROPERTY_IMEI,
@@ -1271,7 +1293,7 @@
 void CellularCapabilityUniversal::OnSimPropertiesChanged(
     const DBusPropertiesMap &props,
     const vector<string> &/* invalidated_properties */) {
-  VLOG(2) << __func__;
+  SLOG(Cellular, 2) << __func__;
   string value;
   bool must_update_home_provider = false;
   if (DBusProperties::GetString(props, MM_SIM_PROPERTY_SIMIDENTIFIER, &value))
@@ -1299,6 +1321,7 @@
 
 void CellularCapabilityUniversal::OnOperatorIdChanged(
     const string &operator_id) {
+  SLOG(Cellular, 2) << "Operator ID = '" << operator_id << "'";
   operator_id_ = operator_id;
 }
 
diff --git a/cellular_capability_universal.h b/cellular_capability_universal.h
index ec2ee2a..066a941 100644
--- a/cellular_capability_universal.h
+++ b/cellular_capability_universal.h
@@ -140,6 +140,7 @@
   FRIEND_TEST(CellularCapabilityUniversalTest, StartModem);
   FRIEND_TEST(CellularCapabilityUniversalTest, StopModem);
   FRIEND_TEST(CellularCapabilityUniversalTest, StopModemConnected);
+  FRIEND_TEST(CellularCapabilityUniversalTest, UpdateOLP);
   FRIEND_TEST(CellularCapabilityUniversalTest, UpdateOperatorInfo);
 
   // Methods used in starting a modem
@@ -158,6 +159,10 @@
   // modem's IMSI and SPN.
   void SetHomeProvider();
 
+  // Updates the online payment portal information, if any, for the cellular
+  // provider.
+  void UpdateOLP();
+
   // Updates the Universal operator name and country based on a newly
   // obtained network id.
   void UpdateOperatorInfo();
diff --git a/cellular_capability_universal_unittest.cc b/cellular_capability_universal_unittest.cc
index 3bcdd0c..20ca0a3 100644
--- a/cellular_capability_universal_unittest.cc
+++ b/cellular_capability_universal_unittest.cc
@@ -42,6 +42,7 @@
 using std::string;
 using std::vector;
 using testing::InSequence;
+using testing::Invoke;
 using testing::Mock;
 using testing::NiceMock;
 using testing::Return;
@@ -64,6 +65,23 @@
           apn == expected_apn);
 }
 
+class MockCellularOperatorInfoGetOLPHelper {
+ public:
+  MockCellularOperatorInfoGetOLPHelper(const CellularService::OLP &olp) {
+    olp_.CopyFrom(olp);
+  }
+
+  ~MockCellularOperatorInfoGetOLPHelper() {}
+
+  bool GetOLP(const std::string &operator_id, CellularService::OLP *olp) {
+    olp->CopyFrom(olp_);
+    return true;
+  }
+
+ private:
+  CellularService::OLP olp_;
+};
+
 class CellularCapabilityUniversalTest : public testing::Test {
  public:
   CellularCapabilityUniversalTest()
@@ -894,6 +912,38 @@
   EXPECT_TRUE(capability_->provider_requires_roaming_);
 }
 
+TEST_F(CellularCapabilityUniversalTest, UpdateOLP) {
+  CellularService::OLP test_olp;
+  test_olp.SetURL("http://testurl");
+  test_olp.SetMethod("POST");
+  test_olp.SetPostData("esn=${esn}&imei=${imei}&imsi=${imsi}&mdn=${mdn}&"
+                       "meid=${meid}&min=${min}&iccid=${iccid}");
+
+  MockCellularOperatorInfoGetOLPHelper get_olp_helper(test_olp);
+
+  capability_->esn_ = "0";
+  capability_->imei_ = "1";
+  capability_->imsi_ = "2";
+  capability_->mdn_ = "3";
+  capability_->meid_= "4";
+  capability_->min_ = "5";
+  capability_->sim_identifier_ = "6";
+  capability_->operator_id_ = "123456";
+  cellular_->cellular_operator_info_ = &cellular_operator_info_;
+
+  EXPECT_CALL(cellular_operator_info_, GetOLP(capability_->operator_id_, _))
+      .WillOnce(Invoke(&get_olp_helper,
+                       &MockCellularOperatorInfoGetOLPHelper::GetOLP));
+
+  SetService();
+  capability_->UpdateOLP();
+  const CellularService::OLP &olp = cellular_->service()->olp();
+  EXPECT_EQ("http://testurl", olp.GetURL());
+  EXPECT_EQ("POST", olp.GetMethod());
+  EXPECT_EQ("esn=0&imei=1&imsi=2&mdn=3&meid=4&min=5&iccid=6",
+            olp.GetPostData());
+}
+
 TEST_F(CellularCapabilityUniversalTest, UpdateOperatorInfo) {
   static const char kOperatorName[] = "Swisscom";
   InitProviderDB();