shill: cellular: Create a pseudo service for activation.

BUG=chromium-os:16134
TEST=Tested the following:
1. Build and run unit tests.
2. Verify existing GSM and CDMA cellular services work as expected.
3. Verify a cellular service that requires activation is created without
   registering to a network.

Change-Id: Ic02ac53641483d60c0517691b9b1f42dc4744d6e
Reviewed-on: https://gerrit.chromium.org/gerrit/38096
Reviewed-by: Darin Petkov <petkov@chromium.org>
Commit-Ready: Ben Chan <benchan@chromium.org>
Tested-by: Ben Chan <benchan@chromium.org>
diff --git a/cellular.cc b/cellular.cc
index dd387dd..ace05cd 100644
--- a/cellular.cc
+++ b/cellular.cc
@@ -343,6 +343,12 @@
 
 void Cellular::HandleNewRegistrationState() {
   SLOG(Cellular, 2) << __func__ << ": " << GetStateString(state_);
+  if (capability_->IsServiceActivationRequired()) {
+    if (state_ == kStateEnabled && !service_.get()) {
+      CreateService();
+    }
+    return;
+  }
   if (!capability_->IsRegistered()) {
     DestroyService();
     if (state_ == kStateLinked ||
@@ -440,7 +446,7 @@
 void Cellular::OnConnected() {
   SLOG(Cellular, 2) << __func__;
   if (state_ == kStateConnected || state_ == kStateLinked) {
-    VLOG(2) << "Already connected";
+    SLOG(Cellular, 2) << "Already connected";
     return;
   }
   Closure start_cb = Bind(&Cellular::StartTermination,
diff --git a/cellular.h b/cellular.h
index 4236592..0d71663 100644
--- a/cellular.h
+++ b/cellular.h
@@ -246,6 +246,8 @@
   FRIEND_TEST(CellularTest, DisableModem);
   FRIEND_TEST(CellularTest, Disconnect);
   FRIEND_TEST(CellularTest, DisconnectFailure);
+  FRIEND_TEST(CellularTest,
+              HandleNewRegistrationStateForServiceRequiringActivation);
   FRIEND_TEST(CellularTest, ModemStateChangeDisable);
   FRIEND_TEST(CellularTest, ModemStateChangeEnable);
   FRIEND_TEST(CellularTest, ModemStateChangeStaleConnected);
diff --git a/cellular_capability_universal.h b/cellular_capability_universal.h
index 075027f..2ef65e5 100644
--- a/cellular_capability_universal.h
+++ b/cellular_capability_universal.h
@@ -143,6 +143,8 @@
   FRIEND_TEST(CellularCapabilityUniversalTest, UpdateOLP);
   FRIEND_TEST(CellularCapabilityUniversalTest, UpdateOperatorInfo);
   FRIEND_TEST(CellularCapabilityUniversalTest, UpdateOperatorInfoViaOperatorId);
+  FRIEND_TEST(CellularTest,
+              HandleNewRegistrationStateForServiceRequiringActivation);
 
   // Methods used in starting a modem
   void EnableModem(Error *error, const ResultCallback &callback);
diff --git a/cellular_unittest.cc b/cellular_unittest.cc
index 6c90b3c..13b98aa 100644
--- a/cellular_unittest.cc
+++ b/cellular_unittest.cc
@@ -10,15 +10,16 @@
 
 #include <base/bind.h>
 #include <chromeos/dbus/service_constants.h>
-#include <mm/mm-modem.h>
 #include <mobile_provider.h>
 
 #include "shill/cellular_capability_cdma.h"
 #include "shill/cellular_capability_classic.h"
 #include "shill/cellular_capability_gsm.h"
+#include "shill/cellular_capability_universal.h"
 #include "shill/cellular_service.h"
 #include "shill/error.h"
 #include "shill/event_dispatcher.h"
+#include "shill/mock_cellular_operator_info.h"
 #include "shill/mock_cellular_service.h"
 #include "shill/mock_device_info.h"
 #include "shill/mock_dhcp_config.h"
@@ -35,6 +36,10 @@
 #include "shill/property_store_unittest.h"
 #include "shill/proxy_factory.h"
 
+// mm/mm-modem.h must be included after cellular_capability_universal.h
+// in order to allow MM_MODEM_CDMA_* to be defined properly.
+#include <mm/mm-modem.h>
+
 using base::Bind;
 using base::Unretained;
 using std::map;
@@ -376,8 +381,14 @@
     return dynamic_cast<CellularCapabilityGSM *>(device_->capability_.get());
   }
 
+  CellularCapabilityUniversal *GetCapabilityUniversal() {
+    return dynamic_cast<CellularCapabilityUniversal *>(
+        device_->capability_.get());
+  }
+
   NiceMockControl control_interface_;
   EventDispatcher dispatcher_;
+  MockCellularOperatorInfo cellular_operator_info_;
   MockMetrics metrics_;
   MockGLib glib_;
   MockManager manager_;
@@ -673,6 +684,24 @@
   device_->Connect(&error);
 }
 
+TEST_F(CellularTest, HandleNewRegistrationStateForServiceRequiringActivation) {
+  SetCellularType(Cellular::kTypeUniversal);
+
+  // Service activation is needed
+  GetCapabilityUniversal()->mdn_ = "0000000000";
+  device_->cellular_operator_info_ = &cellular_operator_info_;
+  EXPECT_CALL(cellular_operator_info_, GetOLP(_, _))
+      .WillRepeatedly(Return(true));
+
+  device_->state_ = Cellular::kStateDisabled;
+  device_->HandleNewRegistrationState();
+  EXPECT_FALSE(device_->service_.get());
+
+  device_->state_ = Cellular::kStateEnabled;
+  device_->HandleNewRegistrationState();
+  EXPECT_TRUE(device_->service_.get());
+}
+
 TEST_F(CellularTest, ModemStateChangeEnable) {
   EXPECT_CALL(*simple_proxy_,
               GetModemStatus(_, _, CellularCapability::kTimeoutDefault))