shill: Handle setting of cellular's AllowRoaming property.

Disconnect the cellular device when roaming and roaming is disallowed. Broadcast
changes in the property.

BUG=chromium-os:25849
TEST=unit tests

Change-Id: I099f85152871cf8e64e96ded72b40712bd66dbd1
Reviewed-on: https://gerrit.chromium.org/gerrit/15406
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Eric Shienbrood <ers@chromium.org>
Commit-Ready: Darin Petkov <petkov@chromium.org>
diff --git a/cellular_capability.cc b/cellular_capability.cc
index 5b166a8..96b6a92 100644
--- a/cellular_capability.cc
+++ b/cellular_capability.cc
@@ -9,6 +9,7 @@
 #include "shill/adaptor_interfaces.h"
 #include "shill/cellular.h"
 #include "shill/error.h"
+#include "shill/property_accessor.h"
 #include "shill/proxy_factory.h"
 
 using base::Callback;
@@ -64,7 +65,9 @@
       proxy_factory_(proxy_factory) {
   PropertyStore *store = cellular->mutable_store();
   store->RegisterConstString(flimflam::kCarrierProperty, &carrier_);
-  store->RegisterBool(flimflam::kCellularAllowRoamingProperty, &allow_roaming_);
+  HelpRegisterDerivedBool(flimflam::kCellularAllowRoamingProperty,
+                          &CellularCapability::GetAllowRoaming,
+                          &CellularCapability::SetAllowRoaming);
   store->RegisterConstBool(flimflam::kSupportNetworkScanProperty,
                            &scanning_supported_);
   store->RegisterConstString(flimflam::kEsnProperty, &esn_);
@@ -83,6 +86,30 @@
 
 CellularCapability::~CellularCapability() {}
 
+void CellularCapability::HelpRegisterDerivedBool(
+    const string &name,
+    bool(CellularCapability::*get)(Error *error),
+    void(CellularCapability::*set)(const bool &value, Error *error)) {
+  cellular()->mutable_store()->RegisterDerivedBool(
+      name,
+      BoolAccessor(
+          new CustomAccessor<CellularCapability, bool>(this, get, set)));
+}
+
+void CellularCapability::SetAllowRoaming(const bool &value, Error */*error*/) {
+  VLOG(2) << __func__ << "(" << allow_roaming_ << "->" << value << ")";
+  if (allow_roaming_ == value) {
+    return;
+  }
+  allow_roaming_ = value;
+  if (!value && GetRoamingStateString() == flimflam::kRoamingStateRoaming) {
+    Error error;
+    cellular()->Disconnect(&error);
+  }
+  cellular()->adaptor()->EmitBoolChanged(
+      flimflam::kCellularAllowRoamingProperty, value);
+}
+
 void CellularCapability::StartModem() {
   VLOG(2) << __func__;
   proxy_.reset(proxy_factory()->CreateModemProxy(