shill: Get and update the GSM signal strength on registration state transition.

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

Change-Id: I2fa1292f5c3413a685ba87bc827aa34943109b37
Reviewed-on: http://gerrit.chromium.org/gerrit/6845
Reviewed-by: Darin Petkov <petkov@chromium.org>
Tested-by: Darin Petkov <petkov@chromium.org>
diff --git a/cellular.cc b/cellular.cc
index 9883fd6..5052b9e 100644
--- a/cellular.cc
+++ b/cellular.cc
@@ -567,9 +567,10 @@
 }
 
 uint32 Cellular::GetGSMSignalQuality() {
-  // TODO(petkov): Implement this.
-  NOTIMPLEMENTED();
-  return 0;
+  VLOG(2) << __func__;
+  CHECK_EQ(kTypeGSM, type_);
+  // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
+  return gsm_network_proxy_->GetSignalQuality();
 }
 
 void Cellular::HandleNewSignalQuality(uint32 strength) {
@@ -775,8 +776,8 @@
 }
 
 void Cellular::OnGSMSignalQualityChanged(uint32 quality) {
-  // TODO(petkov): Implement this.
-  NOTIMPLEMENTED();
+  CHECK_EQ(kTypeGSM, type_);
+  HandleNewSignalQuality(quality);
 }
 
 void Cellular::OnModemStateChanged(uint32 old_state,
diff --git a/cellular.h b/cellular.h
index 6d1fa1d..d809b10 100644
--- a/cellular.h
+++ b/cellular.h
@@ -171,6 +171,7 @@
   FRIEND_TEST(CellularTest, GetCDMASignalQuality);
   FRIEND_TEST(CellularTest, GetGSMNetworkTechnologyString);
   FRIEND_TEST(CellularTest, GetGSMRoamingStateString);
+  FRIEND_TEST(CellularTest, GetGSMSignalQuality);
   FRIEND_TEST(CellularTest, GetModemInfo);
   FRIEND_TEST(CellularTest, GetModemStatus);
   FRIEND_TEST(CellularTest, GetStateString);
diff --git a/cellular_unittest.cc b/cellular_unittest.cc
index 65b9778..dd8915b 100644
--- a/cellular_unittest.cc
+++ b/cellular_unittest.cc
@@ -386,6 +386,7 @@
 }
 
 TEST_F(CellularTest, StartCDMARegister) {
+  const int kStrength = 90;
   device_->type_ = Cellular::kTypeCDMA;
   EXPECT_CALL(*proxy_, Enable(true)).Times(1);
   EXPECT_CALL(*simple_proxy_, GetStatus())
@@ -395,19 +396,21 @@
       .WillOnce(DoAll(
           SetArgumentPointee<0>(MM_MODEM_CDMA_REGISTRATION_STATE_HOME),
           SetArgumentPointee<1>(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN)));
-  EXPECT_CALL(*cdma_proxy_, GetSignalQuality()).WillOnce(Return(90));
+  EXPECT_CALL(*cdma_proxy_, GetSignalQuality()).WillOnce(Return(kStrength));
   device_->Start();
   dispatcher_.DispatchPendingEvents();
   EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
   ASSERT_TRUE(device_->service_.get());
   EXPECT_EQ(flimflam::kNetworkTechnology1Xrtt,
             device_->service_->network_tech());
+  EXPECT_EQ(kStrength, device_->service_->strength());
   EXPECT_EQ(flimflam::kRoamingStateHome, device_->service_->roaming_state());
 }
 
 TEST_F(CellularTest, StartGSMRegister) {
   device_->type_ = Cellular::kTypeGSM;
   static const char kNetwork[] = "My Favorite GSM Network";
+  const int kStrength = 70;
   device_->selected_network_ = kNetwork;
   EXPECT_CALL(*proxy_, Enable(true)).Times(1);
   EXPECT_CALL(*gsm_network_proxy_, Register(kNetwork)).Times(1);
@@ -420,12 +423,15 @@
   reg_info._1 = MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING;
   EXPECT_CALL(*gsm_network_proxy_, GetRegistrationInfo())
       .WillOnce(Return(reg_info));
+  EXPECT_CALL(*gsm_network_proxy_, GetSignalQuality())
+      .WillOnce(Return(kStrength));
   device_->Start();
   dispatcher_.DispatchPendingEvents();
   EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
   ASSERT_TRUE(device_->service_.get());
   EXPECT_EQ(flimflam::kNetworkTechnologyEdge,
             device_->service_->network_tech());
+  EXPECT_EQ(kStrength, device_->service_->strength());
   EXPECT_EQ(flimflam::kRoamingStateRoaming, device_->service_->roaming_state());
 }
 
@@ -558,6 +564,24 @@
   EXPECT_EQ(kStrength, device_->service_->strength());
 }
 
+TEST_F(CellularTest, GetGSMSignalQuality) {
+  const int kStrength = 80;
+  device_->type_ = Cellular::kTypeGSM;
+  EXPECT_CALL(*gsm_network_proxy_, GetSignalQuality())
+      .Times(2)
+      .WillRepeatedly(Return(kStrength));
+  device_->gsm_network_proxy_.reset(gsm_network_proxy_.release());
+
+  EXPECT_FALSE(device_->service_.get());
+  device_->GetModemSignalQuality();
+
+  device_->service_ = new CellularService(
+      &control_interface_, &dispatcher_, &manager_, device_);
+  EXPECT_EQ(0, device_->service_->strength());
+  device_->GetModemSignalQuality();
+  EXPECT_EQ(kStrength, device_->service_->strength());
+}
+
 TEST_F(CellularTest, CreateService) {
   device_->type_ = Cellular::kTypeCDMA;
   static const char kPaymentURL[] = "https://payment.url";
diff --git a/mock_modem_gsm_network_proxy.h b/mock_modem_gsm_network_proxy.h
index ebf6bd6..bec2180 100644
--- a/mock_modem_gsm_network_proxy.h
+++ b/mock_modem_gsm_network_proxy.h
@@ -17,8 +17,9 @@
   MockModemGSMNetworkProxy();
   virtual ~MockModemGSMNetworkProxy();
 
-  MOCK_METHOD1(Register, void(const std::string &network_id));
   MOCK_METHOD0(GetRegistrationInfo, RegistrationInfo());
+  MOCK_METHOD0(GetSignalQuality, uint32());
+  MOCK_METHOD1(Register, void(const std::string &network_id));
   MOCK_METHOD0(AccessTechnology, uint32());
 
  private:
diff --git a/modem_gsm_network_proxy.cc b/modem_gsm_network_proxy.cc
index abbe710..ba1d362 100644
--- a/modem_gsm_network_proxy.cc
+++ b/modem_gsm_network_proxy.cc
@@ -19,15 +19,19 @@
 
 ModemGSMNetworkProxy::~ModemGSMNetworkProxy() {}
 
-void ModemGSMNetworkProxy::Register(const string &network_id) {
-  proxy_.Register(network_id);
-}
-
 ModemGSMNetworkProxyInterface::RegistrationInfo
 ModemGSMNetworkProxy::GetRegistrationInfo() {
   return proxy_.GetRegistrationInfo();
 }
 
+uint32 ModemGSMNetworkProxy::GetSignalQuality() {
+  return proxy_.GetSignalQuality();
+}
+
+void ModemGSMNetworkProxy::Register(const string &network_id) {
+  proxy_.Register(network_id);
+}
+
 uint32 ModemGSMNetworkProxy::AccessTechnology() {
   return proxy_.AccessTechnology();
 }
diff --git a/modem_gsm_network_proxy.h b/modem_gsm_network_proxy.h
index 2a8df41..7a8bddd 100644
--- a/modem_gsm_network_proxy.h
+++ b/modem_gsm_network_proxy.h
@@ -21,8 +21,9 @@
   virtual ~ModemGSMNetworkProxy();
 
   // Inherited from ModemGSMNetworkProxyInterface.
-  virtual void Register(const std::string &network_id);
   virtual RegistrationInfo GetRegistrationInfo();
+  virtual uint32 GetSignalQuality();
+  virtual void Register(const std::string &network_id);
   virtual uint32 AccessTechnology();
 
  private:
diff --git a/modem_gsm_network_proxy_interface.h b/modem_gsm_network_proxy_interface.h
index a461d46..0c53f95 100644
--- a/modem_gsm_network_proxy_interface.h
+++ b/modem_gsm_network_proxy_interface.h
@@ -20,8 +20,9 @@
 
   virtual ~ModemGSMNetworkProxyInterface() {}
 
-  virtual void Register(const std::string &network_id) = 0;
   virtual RegistrationInfo GetRegistrationInfo() = 0;
+  virtual uint32 GetSignalQuality() = 0;
+  virtual void Register(const std::string &network_id) = 0;
 
   // Properties.
   virtual uint32 AccessTechnology() = 0;