shill: Supplying an APN with no "apn" field clears Cellular.APN.

Changed semantics of setting the Cellular.APN property to match
flimflam: if the supplied APN has a missing or empty "apn" field,
the user-specified APN is cleared.

BUG=chromium-os:28899
TEST=Added unit test, ran on platform using "set-apn -c" from
command line.

Change-Id: I0092b275b6322768ad7517089bb9877e76025692
Reviewed-on: https://gerrit.chromium.org/gerrit/19536
Commit-Ready: Eric Shienbrood <ers@chromium.org>
Reviewed-by: Eric Shienbrood <ers@chromium.org>
Tested-by: Eric Shienbrood <ers@chromium.org>
diff --git a/cellular_service.cc b/cellular_service.cc
index 74017bc..de5788c 100644
--- a/cellular_service.cc
+++ b/cellular_service.cc
@@ -148,20 +148,23 @@
 
 void CellularService::SetApn(const Stringmap &value, Error *error) {
   // Only copy in the fields we care about, and validate the contents.
-  // The "apn" field is mandatory.
+  // If the "apn" field is missing or empty, the APN is cleared.
   string str;
   if (!GetNonEmptyField(value, flimflam::kApnProperty, &str)) {
-    error->Populate(Error::kInvalidArguments,
-                    "supplied APN info is missing the apn");
-    return;
+    apn_info_.clear();
+  } else {
+    apn_info_[flimflam::kApnProperty] = str;
+    if (GetNonEmptyField(value, flimflam::kApnUsernameProperty, &str))
+      apn_info_[flimflam::kApnUsernameProperty] = str;
+    if (GetNonEmptyField(value, flimflam::kApnPasswordProperty, &str))
+      apn_info_[flimflam::kApnPasswordProperty] = str;
+    // Clear the last good APN, otherwise the one the user just
+    // set won't be used, since LastGoodApn comes first in the
+    // search order when trying to connect. Only do this if a
+    // non-empty user APN has been supplied. If the user APN is
+    // being cleared, leave LastGoodApn alone.
+    ClearLastGoodApn();
   }
-  apn_info_[flimflam::kApnProperty] = str;
-  if (GetNonEmptyField(value, flimflam::kApnUsernameProperty, &str))
-    apn_info_[flimflam::kApnUsernameProperty] = str;
-  if (GetNonEmptyField(value, flimflam::kApnPasswordProperty, &str))
-    apn_info_[flimflam::kApnPasswordProperty] = str;
-
-  ClearLastGoodApn();
   adaptor()->EmitStringmapChanged(flimflam::kCellularApnProperty, apn_info_);
   SaveToCurrentProfile();
 }