shill: cellular: Determine if service activation is required.
BUG=chrome-os-partner:10631
TEST=Build and run unit tests.
Change-Id: I2d23994b07aca2fc685318273f6dcc8a76a344f9
Reviewed-on: https://gerrit.chromium.org/gerrit/37358
Commit-Ready: Ben Chan <benchan@chromium.org>
Reviewed-by: Ben Chan <benchan@chromium.org>
Tested-by: Ben Chan <benchan@chromium.org>
diff --git a/Makefile b/Makefile
index 52f8a35..ff228ba 100644
--- a/Makefile
+++ b/Makefile
@@ -322,6 +322,7 @@
mock_arp_client.o \
mock_async_connection.o \
mock_cellular.o \
+ mock_cellular_operator_info.o \
mock_cellular_service.o \
mock_connection.o \
mock_control.o \
diff --git a/cellular.h b/cellular.h
index 11a3684..67b9ab5 100644
--- a/cellular.h
+++ b/cellular.h
@@ -233,6 +233,7 @@
FRIEND_TEST(CellularCapabilityUniversalTest, AllowRoaming);
FRIEND_TEST(CellularCapabilityUniversalTest, CreateFriendlyServiceName);
FRIEND_TEST(CellularCapabilityUniversalTest, Connect);
+ FRIEND_TEST(CellularCapabilityUniversalTest, IsServiceActivationRequired);
FRIEND_TEST(CellularCapabilityUniversalTest, StopModemConnected);
FRIEND_TEST(CellularServiceTest, FriendlyName);
FRIEND_TEST(CellularTest, CreateService);
diff --git a/cellular_capability.cc b/cellular_capability.cc
index cb99a40..81382ab 100644
--- a/cellular_capability.cc
+++ b/cellular_capability.cc
@@ -43,6 +43,10 @@
Error::PopulateAndLog(error, Error::kNotSupported, message);
}
+bool CellularCapability::IsServiceActivationRequired() const {
+ return false;
+}
+
void CellularCapability::RegisterOnNetwork(
const string &/*network_id*/,
Error *error, const ResultCallback &/*callback*/) {
diff --git a/cellular_capability.h b/cellular_capability.h
index 0603ea7..647a9b3 100644
--- a/cellular_capability.h
+++ b/cellular_capability.h
@@ -105,6 +105,10 @@
virtual void Activate(const std::string &carrier,
Error *error, const ResultCallback &callback) = 0;
+ // Returns true if service activation is required. Returns false by default
+ // in this base class.
+ virtual bool IsServiceActivationRequired() const;
+
// Network registration.
virtual void RegisterOnNetwork(const std::string &network_id,
Error *error,
diff --git a/cellular_capability_universal.cc b/cellular_capability_universal.cc
index f90819c..7ad4c37 100644
--- a/cellular_capability_universal.cc
+++ b/cellular_capability_universal.cc
@@ -15,6 +15,7 @@
#include <vector>
#include "shill/adaptor_interfaces.h"
+#include "shill/cellular_operator_info.h"
#include "shill/cellular_service.h"
#include "shill/dbus_properties_proxy_interface.h"
#include "shill/error.h"
@@ -368,6 +369,8 @@
cellular()->address() + "_" + imsi_);
}
cellular()->service()->SetActivationState(
+ IsServiceActivationRequired() ?
+ flimflam::kActivationStateNotActivated :
flimflam::kActivationStateActivated);
UpdateServingOperator();
}
@@ -630,6 +633,30 @@
}
}
+bool CellularCapabilityUniversal::IsServiceActivationRequired() const {
+ // If there is no online payment portal information, it's safer to assume
+ // the service does not require activation.
+ if (!cellular()->cellular_operator_info())
+ return false;
+
+ CellularService::OLP olp;
+ if (!cellular()->cellular_operator_info()->GetOLP(operator_id_, &olp))
+ return false;
+
+ // To avoid false positives, it's safer to assume the service does not
+ // require activation if MDN is not set.
+ if (mdn_.empty())
+ return false;
+
+ // If MDN contains only zeros ('+' and '-' characters are ignored),
+ // the service requires activation.
+ for (size_t i = 0; i < mdn_.size(); ++i) {
+ if (mdn_[i] != '0' && mdn_[i] != '-' && mdn_[i] != '+')
+ return false;
+ }
+ return true;
+}
+
// always called from an async context
void CellularCapabilityUniversal::Register(const ResultCallback &callback) {
SLOG(Cellular, 2) << __func__ << " \"" << selected_network_ << "\"";
diff --git a/cellular_capability_universal.h b/cellular_capability_universal.h
index c92c99e..ec2ee2a 100644
--- a/cellular_capability_universal.h
+++ b/cellular_capability_universal.h
@@ -73,6 +73,7 @@
virtual void OnServiceCreated();
virtual void SetupConnectProperties(DBusPropertiesMap *properties);
virtual void GetProperties();
+ virtual bool IsServiceActivationRequired() const;
virtual void Register(const ResultCallback &callback);
virtual void RegisterOnNetwork(const std::string &network_id,
@@ -129,6 +130,7 @@
FRIEND_TEST(CellularCapabilityUniversalTest, CreateFriendlyServiceName);
FRIEND_TEST(CellularCapabilityUniversalTest, DisconnectNoProxy);
FRIEND_TEST(CellularCapabilityUniversalTest, GetTypeString);
+ FRIEND_TEST(CellularCapabilityUniversalTest, IsServiceActivationRequired);
FRIEND_TEST(CellularCapabilityUniversalTest, PropertiesChanged);
FRIEND_TEST(CellularCapabilityUniversalTest, Scan);
FRIEND_TEST(CellularCapabilityUniversalTest, ScanFailure);
diff --git a/cellular_capability_universal_unittest.cc b/cellular_capability_universal_unittest.cc
index cf0b0c3..3bcdd0c 100644
--- a/cellular_capability_universal_unittest.cc
+++ b/cellular_capability_universal_unittest.cc
@@ -20,6 +20,7 @@
#include "shill/error.h"
#include "shill/event_dispatcher.h"
#include "shill/mock_adaptors.h"
+#include "shill/mock_cellular_operator_info.h"
#include "shill/mock_cellular_service.h"
#include "shill/mock_dbus_properties_proxy.h"
#include "shill/mock_glib.h"
@@ -231,6 +232,7 @@
TestProxyFactory proxy_factory_;
CellularCapabilityUniversal *capability_; // Owned by |cellular_|.
NiceMock<DeviceMockAdaptor> *device_adaptor_; // Owned by |cellular_|.
+ MockCellularOperatorInfo cellular_operator_info_;
mobile_provider_db *provider_db_;
CellularRefPtr cellular_;
MockCellularService *service_; // owned by cellular_
@@ -934,4 +936,29 @@
capability_->CreateFriendlyServiceName());
}
+TEST_F(CellularCapabilityUniversalTest, IsServiceActivationRequired) {
+ capability_->mdn_ = "0000000000";
+ cellular_->cellular_operator_info_ = NULL;
+ EXPECT_FALSE(capability_->IsServiceActivationRequired());
+
+ cellular_->cellular_operator_info_ = &cellular_operator_info_;
+ EXPECT_CALL(cellular_operator_info_, GetOLP(_, _))
+ .WillOnce(Return(false))
+ .WillRepeatedly(Return(true));
+ EXPECT_FALSE(capability_->IsServiceActivationRequired());
+
+ capability_->mdn_ = "";
+ EXPECT_FALSE(capability_->IsServiceActivationRequired());
+ capability_->mdn_ = "1234567890";
+ EXPECT_FALSE(capability_->IsServiceActivationRequired());
+ capability_->mdn_ = "+1-234-567-890";
+ EXPECT_FALSE(capability_->IsServiceActivationRequired());
+ capability_->mdn_ = "0000000000";
+ EXPECT_TRUE(capability_->IsServiceActivationRequired());
+ capability_->mdn_ = "0-000-000-000";
+ EXPECT_TRUE(capability_->IsServiceActivationRequired());
+ capability_->mdn_ = "+0-000-000-000";
+ EXPECT_TRUE(capability_->IsServiceActivationRequired());
+}
+
} // namespace shill
diff --git a/cellular_operator_info.h b/cellular_operator_info.h
index da6b2ad..f09f319 100644
--- a/cellular_operator_info.h
+++ b/cellular_operator_info.h
@@ -20,14 +20,15 @@
class CellularOperatorInfo {
public:
explicit CellularOperatorInfo(GLib *glib);
- ~CellularOperatorInfo();
+ virtual ~CellularOperatorInfo();
// Loads the operator info from |info_file_path|. Returns true on success.
- bool Load(const FilePath &info_file_path);
+ virtual bool Load(const FilePath &info_file_path);
// Gets the online payment portal info of the operator with ID |operator_id|.
// Returns true if the info is found.
- bool GetOLP(const std::string &operator_id, CellularService::OLP *olp);
+ virtual bool GetOLP(const std::string &operator_id,
+ CellularService::OLP *olp);
private:
KeyFileStore info_file_;
diff --git a/mock_cellular_operator_info.cc b/mock_cellular_operator_info.cc
new file mode 100644
index 0000000..f5cc5ca
--- /dev/null
+++ b/mock_cellular_operator_info.cc
@@ -0,0 +1,14 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "shill/mock_cellular_operator_info.h"
+
+namespace shill {
+
+MockCellularOperatorInfo::MockCellularOperatorInfo()
+ : CellularOperatorInfo(NULL) {}
+
+MockCellularOperatorInfo::~MockCellularOperatorInfo() {}
+
+} // namespace shill
diff --git a/mock_cellular_operator_info.h b/mock_cellular_operator_info.h
new file mode 100644
index 0000000..2acb0db
--- /dev/null
+++ b/mock_cellular_operator_info.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SHILL_MOCK_CELLULAR_OPERATOR_INFO_H_
+#define SHILL_MOCK_CELLULAR_OPERATOR_INFO_H_
+
+#include <string>
+
+#include <gmock/gmock.h>
+
+#include "shill/cellular_operator_info.h"
+
+namespace shill {
+
+class MockCellularOperatorInfo : public CellularOperatorInfo {
+ public:
+ MockCellularOperatorInfo();
+ virtual ~MockCellularOperatorInfo();
+
+ MOCK_METHOD1(Load, bool(const FilePath &info_file_path));
+ MOCK_METHOD2(GetOLP, bool(const std::string &operator_id,
+ CellularService::OLP *olp));
+};
+
+} // namespace shill
+
+#endif // SHILL_MOCK_CELLULAR_OPERATOR_INFO_H_