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.cc b/cellular.cc
index 7cd274d..349e4c6 100644
--- a/cellular.cc
+++ b/cellular.cc
@@ -316,7 +316,12 @@
void Cellular::OnConnected() {
VLOG(2) << __func__;
SetState(kStateConnected);
- EstablishLink();
+ if (!capability_->allow_roaming() &&
+ service_->roaming_state() == flimflam::kRoamingStateRoaming) {
+ Disconnect(NULL);
+ } else {
+ EstablishLink();
+ }
}
void Cellular::OnConnectFailed() {
diff --git a/cellular.h b/cellular.h
index 578f32c..705b794 100644
--- a/cellular.h
+++ b/cellular.h
@@ -184,6 +184,7 @@
FRIEND_TEST(CellularTest, StartCDMARegister);
FRIEND_TEST(CellularTest, StartGSMRegister);
FRIEND_TEST(CellularTest, StartLinked);
+ FRIEND_TEST(CellularCapabilityTest, AllowRoaming);
FRIEND_TEST(CellularCapabilityTest, EnableModemFail);
FRIEND_TEST(CellularCapabilityTest, EnableModemSucceed);
FRIEND_TEST(CellularCapabilityTest, GetModemInfo);
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(
diff --git a/cellular_capability.h b/cellular_capability.h
index 78d9524..0b9a3af 100644
--- a/cellular_capability.h
+++ b/cellular_capability.h
@@ -183,6 +183,7 @@
friend class CellularCapabilityTest;
FRIEND_TEST(CellularCapabilityGSMTest, SetStorageIdentifier);
FRIEND_TEST(CellularCapabilityGSMTest, UpdateStatus);
+ FRIEND_TEST(CellularCapabilityTest, AllowRoaming);
FRIEND_TEST(CellularCapabilityTest, GetModemInfo);
FRIEND_TEST(CellularCapabilityTest, GetModemStatus);
FRIEND_TEST(CellularServiceTest, FriendlyName);
@@ -193,6 +194,14 @@
FRIEND_TEST(CellularTest, Connect);
FRIEND_TEST(CellularTest, DisconnectModem);
+ void HelpRegisterDerivedBool(
+ const std::string &name,
+ bool(CellularCapability::*get)(Error *error),
+ void(CellularCapability::*set)(const bool &value, Error *error));
+
+ bool GetAllowRoaming(Error */*error*/) { return allow_roaming_; }
+ void SetAllowRoaming(const bool &value, Error *error);
+
Cellular *cellular_;
// Store cached copies of singletons for speed/ease of testing.
diff --git a/cellular_capability_gsm.h b/cellular_capability_gsm.h
index d1eac54..4933039 100644
--- a/cellular_capability_gsm.h
+++ b/cellular_capability_gsm.h
@@ -62,6 +62,7 @@
friend class CellularTest;
friend class CellularCapabilityGSMTest;
FRIEND_TEST(CellularTest, StartGSMRegister);
+ FRIEND_TEST(CellularCapabilityTest, AllowRoaming);
FRIEND_TEST(CellularCapabilityGSMTest, CreateDeviceFromProperties);
FRIEND_TEST(CellularCapabilityGSMTest, CreateFriendlyServiceName);
FRIEND_TEST(CellularCapabilityGSMTest, GetIMEI);
diff --git a/cellular_capability_unittest.cc b/cellular_capability_unittest.cc
index 09ca81f..3e18772 100644
--- a/cellular_capability_unittest.cc
+++ b/cellular_capability_unittest.cc
@@ -23,6 +23,7 @@
#include "shill/proxy_factory.h"
using std::string;
+using testing::InSequence;
using testing::NiceMock;
namespace shill {
@@ -189,4 +190,32 @@
EXPECT_EQ(Cellular::kStateDisabled, cellular_->state_);
}
+TEST_F(CellularCapabilityTest, AllowRoaming) {
+ EXPECT_FALSE(capability_->GetAllowRoaming(NULL));
+ capability_->SetAllowRoaming(false, NULL);
+ EXPECT_FALSE(capability_->GetAllowRoaming(NULL));
+
+ {
+ InSequence seq;
+ EXPECT_CALL(*device_adaptor_, EmitBoolChanged(
+ flimflam::kCellularAllowRoamingProperty, true));
+ EXPECT_CALL(*device_adaptor_, EmitBoolChanged(
+ flimflam::kCellularAllowRoamingProperty, false));
+ }
+
+ cellular_->state_ = Cellular::kStateConnected;
+ dynamic_cast<CellularCapabilityGSM *>(capability_)->registration_state_ =
+ MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING;
+ capability_->SetAllowRoaming(true, NULL);
+ EXPECT_TRUE(capability_->GetAllowRoaming(NULL));
+ EXPECT_EQ(Cellular::kStateConnected, cellular_->state_);
+
+ EXPECT_CALL(*proxy_, Disconnect());
+ SetProxy();
+ cellular_->state_ = Cellular::kStateConnected;
+ capability_->SetAllowRoaming(false, NULL);
+ EXPECT_FALSE(capability_->GetAllowRoaming(NULL));
+ EXPECT_EQ(Cellular::kStateRegistered, cellular_->state_);
+}
+
} // namespace shill