shill: cellular: Use operator ID from SIM as a fallback.

When the serving operator ID is not available, use the operator ID from
SIM as a fallback.

BUG=chromium-os:36158
TEST=Build and run unit tests.

Change-Id: Ie1b4604177d69138162f9834cb65be93a61cae5b
Reviewed-on: https://gerrit.chromium.org/gerrit/37605
Reviewed-by: Darin Petkov <petkov@chromium.org>
Commit-Ready: Ben Chan <benchan@chromium.org>
Tested-by: Ben Chan <benchan@chromium.org>
diff --git a/cellular.h b/cellular.h
index 3404c40..4236592 100644
--- a/cellular.h
+++ b/cellular.h
@@ -236,6 +236,7 @@
   FRIEND_TEST(CellularCapabilityUniversalTest, IsServiceActivationRequired);
   FRIEND_TEST(CellularCapabilityUniversalTest, StopModemConnected);
   FRIEND_TEST(CellularCapabilityUniversalTest, UpdateOLP);
+  FRIEND_TEST(CellularCapabilityUniversalTest, UpdateOperatorInfoViaOperatorId);
   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 742bf71..5a56982 100644
--- a/cellular_capability_universal.cc
+++ b/cellular_capability_universal.cc
@@ -490,6 +490,13 @@
 
 string CellularCapabilityUniversal::CreateFriendlyServiceName() {
   SLOG(Cellular, 2) << __func__ << ": " << GetRoamingStateString();
+
+  // If |serving_operator_| does not have an operator ID, call
+  // UpdateOperatorInfo() to use |operator_id_| as a fallback when appropriate.
+  if (serving_operator_.GetCode().empty()) {
+    UpdateOperatorInfo();
+  }
+
   string name = serving_operator_.GetName();
   string home_provider_name = cellular()->home_provider().GetName();
   if (!name.empty()) {
@@ -576,6 +583,17 @@
 
 void CellularCapabilityUniversal::UpdateOperatorInfo() {
   SLOG(Cellular, 2) << __func__;
+
+  // If service activation is required, |serving_operator_| may not have an
+  // operator ID. Use |operator_id_| as a fallback when available.
+  // |operator_id_| is retrieved from the SIM card.
+  if (IsServiceActivationRequired() && serving_operator_.GetCode().empty() &&
+      !operator_id_.empty()) {
+    SLOG(Cellular, 2) << "Assuming operator '" << operator_id_
+                      << "' as serving operator.";
+    serving_operator_.SetCode(operator_id_);
+  }
+
   const string &network_id = serving_operator_.GetCode();
   if (!network_id.empty()) {
     SLOG(Cellular, 2) << "Looking up network id: " << network_id;
diff --git a/cellular_capability_universal.h b/cellular_capability_universal.h
index 066a941..075027f 100644
--- a/cellular_capability_universal.h
+++ b/cellular_capability_universal.h
@@ -142,6 +142,7 @@
   FRIEND_TEST(CellularCapabilityUniversalTest, StopModemConnected);
   FRIEND_TEST(CellularCapabilityUniversalTest, UpdateOLP);
   FRIEND_TEST(CellularCapabilityUniversalTest, UpdateOperatorInfo);
+  FRIEND_TEST(CellularCapabilityUniversalTest, UpdateOperatorInfoViaOperatorId);
 
   // Methods used in starting a modem
   void EnableModem(Error *error, const ResultCallback &callback);
diff --git a/cellular_capability_universal_unittest.cc b/cellular_capability_universal_unittest.cc
index 20ca0a3..d1a7425 100644
--- a/cellular_capability_universal_unittest.cc
+++ b/cellular_capability_universal_unittest.cc
@@ -932,8 +932,8 @@
   cellular_->cellular_operator_info_ = &cellular_operator_info_;
 
   EXPECT_CALL(cellular_operator_info_, GetOLP(capability_->operator_id_, _))
-      .WillOnce(Invoke(&get_olp_helper,
-                       &MockCellularOperatorInfoGetOLPHelper::GetOLP));
+      .WillRepeatedly(Invoke(&get_olp_helper,
+                             &MockCellularOperatorInfoGetOLPHelper::GetOLP));
 
   SetService();
   capability_->UpdateOLP();
@@ -963,11 +963,58 @@
   EXPECT_EQ(kTestOperator, cellular_->service()->serving_operator().GetName());
 }
 
+TEST_F(CellularCapabilityUniversalTest, UpdateOperatorInfoViaOperatorId) {
+  static const char kOperatorName[] = "Swisscom";
+  static const char kOperatorId[] = "22801";
+  InitProviderDB();
+  capability_->serving_operator_.SetCode("");
+  SetService();
+  capability_->UpdateOperatorInfo();
+  EXPECT_EQ("", capability_->serving_operator_.GetName());
+  EXPECT_EQ("", capability_->serving_operator_.GetCountry());
+  EXPECT_EQ("", cellular_->service()->serving_operator().GetName());
+
+  capability_->operator_id_ = kOperatorId;
+
+  // Service activation is not needed
+  cellular_->cellular_operator_info_ = &cellular_operator_info_;
+  EXPECT_CALL(cellular_operator_info_, GetOLP(_, _))
+      .WillOnce(Return(false));
+  capability_->UpdateOperatorInfo();
+  EXPECT_EQ("", capability_->serving_operator_.GetName());
+  EXPECT_EQ("", capability_->serving_operator_.GetCountry());
+  EXPECT_EQ("", cellular_->service()->serving_operator().GetName());
+
+  // Service activation is needed
+  capability_->mdn_ = "0000000000";
+  cellular_->cellular_operator_info_ = &cellular_operator_info_;
+  EXPECT_CALL(cellular_operator_info_, GetOLP(_, _))
+      .WillOnce(Return(true));
+
+  capability_->UpdateOperatorInfo();
+  EXPECT_EQ(kOperatorId, capability_->serving_operator_.GetCode());
+  EXPECT_EQ(kOperatorName, capability_->serving_operator_.GetName());
+  EXPECT_EQ("ch", capability_->serving_operator_.GetCountry());
+  EXPECT_EQ(kOperatorName, cellular_->service()->serving_operator().GetName());
+}
+
 TEST_F(CellularCapabilityUniversalTest, CreateFriendlyServiceName) {
   CellularCapabilityUniversal::friendly_service_name_id_ = 0;
   EXPECT_EQ("GSMNetwork0", capability_->CreateFriendlyServiceName());
   EXPECT_EQ("GSMNetwork1", capability_->CreateFriendlyServiceName());
 
+  // Service activation is not needed
+  capability_->operator_id_ = "0123";
+  EXPECT_EQ("GSMNetwork2", capability_->CreateFriendlyServiceName());
+
+  // Service activation is needed
+  capability_->mdn_ = "0000000000";
+  cellular_->cellular_operator_info_ = &cellular_operator_info_;
+  EXPECT_CALL(cellular_operator_info_, GetOLP(_, _))
+      .WillOnce(Return(true));
+  EXPECT_EQ("cellular_0123", capability_->CreateFriendlyServiceName());
+  EXPECT_EQ("0123", capability_->serving_operator_.GetCode());
+
   capability_->serving_operator_.SetCode("1234");
   EXPECT_EQ("cellular_1234", capability_->CreateFriendlyServiceName());