shill: CellularCapabilityUniversal: return proper technology family

Previously the CellularCapabilityUniversal class had returned
"Universal" as the technology family.  This was incorrect and resulted
in the UI not displaying options to modify the APN or manipulate SIM
locking.

BUG=none
TEST=run with LTE modems, see APN choices in UI

Change-Id: Ie3edbfac8698ba41499fc3b41de0f7934fffdb62
Reviewed-on: https://gerrit.chromium.org/gerrit/22151
Reviewed-by: Jason Glasgow <jglasgow@chromium.org>
Tested-by: Jason Glasgow <jglasgow@chromium.org>
Commit-Ready: Jason Glasgow <jglasgow@chromium.org>
diff --git a/cellular_capability_cdma.h b/cellular_capability_cdma.h
index 3fb6edf..1b022b6 100644
--- a/cellular_capability_cdma.h
+++ b/cellular_capability_cdma.h
@@ -7,6 +7,7 @@
 
 #include <base/memory/scoped_ptr.h>
 #include <base/memory/weak_ptr.h>
+#include <chromeos/dbus/service_constants.h>
 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
 
 #include <string>
@@ -35,7 +36,9 @@
   virtual std::string GetNetworkTechnologyString() const;
   virtual std::string GetRoamingStateString() const;
   virtual void GetSignalQuality();
-  virtual std::string GetTypeString() const { return "CDMA"; }
+  virtual std::string GetTypeString() const {
+    return flimflam::kTechnologyFamilyCdma;
+  }
   virtual bool AllowRoaming();
   virtual void GetRegistrationState();
   virtual void GetProperties(const ResultCallback &callback);
diff --git a/cellular_capability_gsm.h b/cellular_capability_gsm.h
index bacc874..4e1a103 100644
--- a/cellular_capability_gsm.h
+++ b/cellular_capability_gsm.h
@@ -11,6 +11,7 @@
 
 #include <base/memory/scoped_ptr.h>
 #include <base/memory/weak_ptr.h>
+#include <chromeos/dbus/service_constants.h>
 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
 
 #include "shill/accessor_interface.h"
@@ -68,7 +69,9 @@
   virtual void Scan(Error *error, const ResultCallback &callback);
   virtual std::string GetNetworkTechnologyString() const;
   virtual std::string GetRoamingStateString() const;
-  virtual std::string GetTypeString() const { return "GSM"; }
+  virtual std::string GetTypeString() const {
+    return flimflam::kTechnologyFamilyGsm;
+  }
   virtual void OnDBusPropertiesChanged(
       const std::string &interface,
       const DBusPropertiesMap &properties,
diff --git a/cellular_capability_universal.cc b/cellular_capability_universal.cc
index 39d86ca..ee557ea 100644
--- a/cellular_capability_universal.cc
+++ b/cellular_capability_universal.cc
@@ -92,6 +92,26 @@
   return "";
 }
 
+static string AccessTechnologyToTechnologyFamily(uint32 access_technologies) {
+  if (access_technologies & (MM_MODEM_ACCESS_TECHNOLOGY_LTE |
+                             MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS |
+                             MM_MODEM_ACCESS_TECHNOLOGY_HSPA |
+                             MM_MODEM_ACCESS_TECHNOLOGY_HSUPA |
+                             MM_MODEM_ACCESS_TECHNOLOGY_HSDPA |
+                             MM_MODEM_ACCESS_TECHNOLOGY_UMTS |
+                             MM_MODEM_ACCESS_TECHNOLOGY_EDGE |
+                             MM_MODEM_ACCESS_TECHNOLOGY_GPRS |
+                             MM_MODEM_ACCESS_TECHNOLOGY_GSM_COMPACT |
+                             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_1XRTT))
+    return flimflam::kTechnologyFamilyCdma;
+  return "";
+}
+
 CellularCapabilityUniversal::CellularCapabilityUniversal(
     Cellular *cellular,
     ProxyFactory *proxy_factory)
@@ -774,7 +794,7 @@
 }
 
 string CellularCapabilityUniversal::GetNetworkTechnologyString() const {
-  // Order is imnportant.  Return the highest speed technology
+  // Order is important.  Return the highest speed technology
   // TODO(jglasgow): change shill interfaces to a capability model
 
   return AccessTechnologyToString(access_technologies_);
@@ -799,6 +819,10 @@
   OnSignalQualityChanged(quality._1);
 }
 
+string CellularCapabilityUniversal::GetTypeString() const {
+  return AccessTechnologyToTechnologyFamily(access_technologies_);
+}
+
 void CellularCapabilityUniversal::OnModemPropertiesChanged(
     const DBusPropertiesMap &properties,
     const vector<string> &/* invalidated_properties */) {
@@ -1010,9 +1034,16 @@
 
 void CellularCapabilityUniversal::OnAccessTechnologiesChanged(
     uint32 access_technologies) {
-  access_technologies_ = access_technologies;
-  if (cellular()->service().get()) {
-    cellular()->service()->SetNetworkTechnology(GetNetworkTechnologyString());
+  if (access_technologies_ != access_technologies) {
+    access_technologies_ = access_technologies;
+    // TODO(jglasgow): address layering violation of emitting change
+    // signal here for a property owned by Cellular.
+    cellular()->adaptor()->EmitStringChanged(
+        flimflam::kTechnologyFamilyProperty,
+        GetTypeString());
+    if (cellular()->service().get()) {
+      cellular()->service()->SetNetworkTechnology(GetNetworkTechnologyString());
+    }
   }
 }
 
diff --git a/cellular_capability_universal.h b/cellular_capability_universal.h
index a0fd239..411f4c9 100644
--- a/cellular_capability_universal.h
+++ b/cellular_capability_universal.h
@@ -92,7 +92,7 @@
   virtual std::string GetNetworkTechnologyString() const;
   virtual std::string GetRoamingStateString() const;
   virtual void GetSignalQuality();
-  virtual std::string GetTypeString() const { return "Universal"; }
+  virtual std::string GetTypeString() const;
   virtual void OnDBusPropertiesChanged(
       const std::string &interface,
       const DBusPropertiesMap &changed_properties,
@@ -126,6 +126,7 @@
   FRIEND_TEST(CellularCapabilityUniversalTest, ScanFailure);
   FRIEND_TEST(CellularCapabilityUniversalTest, Connect);
   FRIEND_TEST(CellularCapabilityUniversalTest, ConnectApns);
+  FRIEND_TEST(CellularCapabilityUniversalTest, GetTypeString);
 
   // Methods used in starting a modem
   void Start_EnableModemCompleted(const ResultCallback &callback,
diff --git a/cellular_capability_universal_unittest.cc b/cellular_capability_universal_unittest.cc
index c2fd206..65b1ba3 100644
--- a/cellular_capability_universal_unittest.cc
+++ b/cellular_capability_universal_unittest.cc
@@ -570,4 +570,45 @@
   connect_callback_.Run(bearer, Error(Error::kSuccess));
 }
 
+// Validates GetTypeString and AccessTechnologyToTechnologyFamily
+TEST_F(CellularCapabilityUniversalTest, GetTypeString) {
+  const int gsm_technologies[] = {
+    MM_MODEM_ACCESS_TECHNOLOGY_LTE,
+    MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS,
+    MM_MODEM_ACCESS_TECHNOLOGY_HSPA,
+    MM_MODEM_ACCESS_TECHNOLOGY_HSUPA,
+    MM_MODEM_ACCESS_TECHNOLOGY_HSDPA,
+    MM_MODEM_ACCESS_TECHNOLOGY_UMTS,
+    MM_MODEM_ACCESS_TECHNOLOGY_EDGE,
+    MM_MODEM_ACCESS_TECHNOLOGY_GPRS,
+    MM_MODEM_ACCESS_TECHNOLOGY_GSM_COMPACT,
+    MM_MODEM_ACCESS_TECHNOLOGY_GSM,
+    MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
+    MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
+    MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
+    MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
+    MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
+    MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
+    MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_1XRTT,
+  };
+  for(size_t i = 0; i < arraysize(gsm_technologies); ++i) {
+    capability_->access_technologies_ = gsm_technologies[i];
+    ASSERT_EQ(capability_->GetTypeString(), flimflam::kTechnologyFamilyGsm);
+  }
+  const int cdma_technologies[] = {
+    MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
+    MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
+    MM_MODEM_ACCESS_TECHNOLOGY_EVDOA | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
+    MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
+    MM_MODEM_ACCESS_TECHNOLOGY_EVDOB | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
+    MM_MODEM_ACCESS_TECHNOLOGY_1XRTT,
+  };
+  for(size_t i = 0; i < arraysize(cdma_technologies); ++i) {
+    capability_->access_technologies_ = cdma_technologies[i];
+    ASSERT_EQ(capability_->GetTypeString(), flimflam::kTechnologyFamilyCdma);
+  }
+  capability_->access_technologies_ = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
+  ASSERT_EQ(capability_->GetTypeString(), "");
+}
+
 }  // namespace shill