1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/chromeos/mobile/mobile_activator.h" 6 7 #include "chrome/browser/chromeos/cros/mock_network_library.h" 8 #include "chrome/browser/chromeos/cros/network_library.h" 9 #include "content/public/browser/browser_thread.h" 10 #include "testing/gmock/include/gmock/gmock.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 13 using std::string; 14 15 using content::BrowserThread; 16 using testing::_; 17 using testing::Eq; 18 using testing::Return; 19 20 namespace { 21 22 const char kTestServicePath[] = "/a/service/path"; 23 24 const size_t kNumOTASPStates = 3; 25 26 chromeos::MobileActivator::PlanActivationState kOTASPStates[kNumOTASPStates] = { 27 chromeos::MobileActivator::PLAN_ACTIVATION_TRYING_OTASP, 28 chromeos::MobileActivator::PLAN_ACTIVATION_INITIATING_ACTIVATION, 29 chromeos::MobileActivator::PLAN_ACTIVATION_OTASP, 30 }; 31 32 } // namespace 33 namespace chromeos { 34 35 class TestMobileActivator : public MobileActivator { 36 public: 37 TestMobileActivator(MockNetworkLibrary* mock_network_library, 38 CellularNetwork* cellular_network) 39 : mock_network_library_(mock_network_library), 40 cellular_network_(cellular_network) { 41 // Provide reasonable defaults for basic things we're usually not testing. 42 ON_CALL(*this, DCheckOnThread(_)) 43 .WillByDefault(Return()); 44 ON_CALL(*this, FindMatchingCellularNetwork(_)) 45 .WillByDefault(Return(cellular_network)); 46 ON_CALL(*this, GetNetworkLibrary()) 47 .WillByDefault(Return(mock_network_library_)); 48 } 49 virtual ~TestMobileActivator() {} 50 51 MOCK_METHOD3(ChangeState, void(CellularNetwork*, 52 MobileActivator::PlanActivationState, 53 const std::string&)); 54 MOCK_METHOD1(EvaluateCellularNetwork, void(CellularNetwork*)); 55 MOCK_METHOD1(FindMatchingCellularNetwork, CellularNetwork*(bool)); 56 MOCK_METHOD0(StartOTASPTimer, void(void)); 57 58 void InvokeChangeState(CellularNetwork* network, 59 MobileActivator::PlanActivationState new_state, 60 const std::string& error_description) { 61 MobileActivator::ChangeState(network, new_state, error_description); 62 } 63 64 private: 65 MOCK_CONST_METHOD0(GetNetworkLibrary, NetworkLibrary*(void)); 66 MOCK_CONST_METHOD1(DCheckOnThread, void(const BrowserThread::ID id)); 67 68 MockNetworkLibrary* mock_network_library_; 69 CellularNetwork* cellular_network_; 70 71 DISALLOW_COPY_AND_ASSIGN(TestMobileActivator); 72 }; 73 74 class MobileActivatorTest : public testing::Test { 75 public: 76 MobileActivatorTest() 77 : network_library_(), 78 cellular_network_(string(kTestServicePath)), 79 mobile_activator_(&network_library_, &cellular_network_) {} 80 virtual ~MobileActivatorTest() {} 81 82 protected: 83 virtual void SetUp() {} 84 virtual void TearDown() {} 85 86 void set_activator_state(const MobileActivator::PlanActivationState state) { 87 mobile_activator_.state_ = state; 88 } 89 void set_network_activation_state(ActivationState state) { 90 cellular_network_.activation_state_ = state; 91 } 92 void set_connection_state(ConnectionState state) { 93 cellular_network_.state_ = state; 94 } 95 96 MockNetworkLibrary network_library_; 97 MockCellularNetwork cellular_network_; 98 TestMobileActivator mobile_activator_; 99 private: 100 DISALLOW_COPY_AND_ASSIGN(MobileActivatorTest); 101 }; 102 103 TEST_F(MobileActivatorTest, BasicFlowForNewDevices) { 104 // In a new device, we aren't connected to Verizon, we start at START 105 // because we haven't paid Verizon (ever), and the modem isn't even partially 106 // activated. 107 std::string error_description; 108 set_activator_state(MobileActivator::PLAN_ACTIVATION_START); 109 set_connection_state(STATE_IDLE); 110 set_network_activation_state(ACTIVATION_STATE_NOT_ACTIVATED); 111 EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_INITIATING_ACTIVATION, 112 mobile_activator_.PickNextState(&cellular_network_, 113 &error_description)); 114 // Now behave as if ChangeState() has initiated an activation. 115 set_activator_state(MobileActivator::PLAN_ACTIVATION_INITIATING_ACTIVATION); 116 set_network_activation_state(ACTIVATION_STATE_ACTIVATING); 117 // We'll sit in this state while we wait for the OTASP to finish. 118 EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_INITIATING_ACTIVATION, 119 mobile_activator_.PickNextState(&cellular_network_, 120 &error_description)); 121 set_network_activation_state(ACTIVATION_STATE_PARTIALLY_ACTIVATED); 122 // We'll sit in this state until we go online as well. 123 EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_INITIATING_ACTIVATION, 124 mobile_activator_.PickNextState(&cellular_network_, 125 &error_description)); 126 set_connection_state(STATE_PORTAL); 127 // After we go online, we go back to START, which acts as a jumping off 128 // point for the two types of initial OTASP. 129 EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_START, 130 mobile_activator_.PickNextState(&cellular_network_, 131 &error_description)); 132 set_activator_state(MobileActivator::PLAN_ACTIVATION_START); 133 EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_TRYING_OTASP, 134 mobile_activator_.PickNextState(&cellular_network_, 135 &error_description)); 136 // Very similar things happen while we're trying OTASP. 137 set_activator_state(MobileActivator::PLAN_ACTIVATION_TRYING_OTASP); 138 set_network_activation_state(ACTIVATION_STATE_ACTIVATING); 139 EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_TRYING_OTASP, 140 mobile_activator_.PickNextState(&cellular_network_, 141 &error_description)); 142 set_network_activation_state(ACTIVATION_STATE_PARTIALLY_ACTIVATED); 143 set_connection_state(STATE_PORTAL); 144 // And when we come back online again and aren't activating, load the portal. 145 EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING, 146 mobile_activator_.PickNextState(&cellular_network_, 147 &error_description)); 148 // The JS drives us through the payment portal. 149 set_activator_state(MobileActivator::PLAN_ACTIVATION_SHOWING_PAYMENT); 150 // The JS also calls us to signal that the portal is done. This triggers us 151 // to start our final OTASP via the aptly named StartOTASP(). 152 EXPECT_CALL(network_library_, SignalCellularPlanPayment()); 153 EXPECT_CALL(mobile_activator_, 154 ChangeState(Eq(&cellular_network_), 155 Eq(MobileActivator::PLAN_ACTIVATION_START_OTASP), 156 _)); 157 EXPECT_CALL(mobile_activator_, 158 EvaluateCellularNetwork(Eq(&cellular_network_))); 159 mobile_activator_.HandleSetTransactionStatus(true); 160 // Evaluate state will defer to PickNextState to select what to do now that 161 // we're in START_ACTIVATION. PickNextState should decide to start a final 162 // OTASP. 163 set_activator_state(MobileActivator::PLAN_ACTIVATION_START_OTASP); 164 EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_OTASP, 165 mobile_activator_.PickNextState(&cellular_network_, 166 &error_description)); 167 // Similarly to TRYING_OTASP and INITIATING_OTASP above... 168 set_activator_state(MobileActivator::PLAN_ACTIVATION_OTASP); 169 set_network_activation_state(ACTIVATION_STATE_ACTIVATING); 170 EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_OTASP, 171 mobile_activator_.PickNextState(&cellular_network_, 172 &error_description)); 173 set_network_activation_state(ACTIVATION_STATE_ACTIVATED); 174 EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_DONE, 175 mobile_activator_.PickNextState(&cellular_network_, 176 &error_description)); 177 } 178 179 TEST_F(MobileActivatorTest, OTASPScheduling) { 180 const std::string error; 181 for (size_t i = 0; i < kNumOTASPStates; ++i) { 182 // When activation works, we start a timer to watch for success. 183 EXPECT_CALL(cellular_network_, StartActivation()) 184 .Times(1) 185 .WillOnce(Return(true)); 186 EXPECT_CALL(mobile_activator_, StartOTASPTimer()) 187 .Times(1); 188 set_activator_state(MobileActivator::PLAN_ACTIVATION_START); 189 mobile_activator_.InvokeChangeState(&cellular_network_, 190 kOTASPStates[i], 191 error); 192 // When activation fails, it's an error, unless we're trying for the final 193 // OTASP, in which case we try again via DELAY_OTASP. 194 EXPECT_CALL(cellular_network_, StartActivation()) 195 .Times(1) 196 .WillOnce(Return(false)); 197 if (kOTASPStates[i] == MobileActivator::PLAN_ACTIVATION_OTASP) { 198 EXPECT_CALL(mobile_activator_, ChangeState( 199 Eq(&cellular_network_), 200 Eq(MobileActivator::PLAN_ACTIVATION_DELAY_OTASP), 201 _)); 202 } else { 203 EXPECT_CALL(mobile_activator_, ChangeState( 204 Eq(&cellular_network_), 205 Eq(MobileActivator::PLAN_ACTIVATION_ERROR), 206 _)); 207 } 208 set_activator_state(MobileActivator::PLAN_ACTIVATION_START); 209 mobile_activator_.InvokeChangeState(&cellular_network_, 210 kOTASPStates[i], 211 error); 212 } 213 } 214 215 TEST_F(MobileActivatorTest, ReconnectOnDisconnectFromPaymentPortal) { 216 // Most states either don't care if we're offline or expect to be offline at 217 // some point. For instance the OTASP states expect to go offline during 218 // activation and eventually come back. There are a few transitions states 219 // like START_OTASP and DELAY_OTASP which don't really depend on the state of 220 // the modem (offline or online) to work correctly. A few places however, 221 // like when we're displaying the portal care quite a bit about going 222 // offline. Lets test for those cases. 223 std::string error_description; 224 set_connection_state(STATE_FAILURE); 225 set_network_activation_state(ACTIVATION_STATE_PARTIALLY_ACTIVATED); 226 set_activator_state(MobileActivator::PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING); 227 EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_RECONNECTING, 228 mobile_activator_.PickNextState(&cellular_network_, 229 &error_description)); 230 set_activator_state(MobileActivator::PLAN_ACTIVATION_SHOWING_PAYMENT); 231 EXPECT_EQ(MobileActivator::PLAN_ACTIVATION_RECONNECTING, 232 mobile_activator_.PickNextState(&cellular_network_, 233 &error_description)); 234 } 235 236 TEST_F(MobileActivatorTest, StartAtStart) { 237 EXPECT_CALL(network_library_, 238 AddNetworkManagerObserver(Eq(&mobile_activator_))); 239 EXPECT_CALL(network_library_, HasRecentCellularPlanPayment()). 240 WillOnce(Return(false)); 241 EXPECT_CALL(mobile_activator_, 242 EvaluateCellularNetwork(Eq(&cellular_network_))); 243 mobile_activator_.StartActivation(); 244 EXPECT_EQ(mobile_activator_.state(), MobileActivator::PLAN_ACTIVATION_START); 245 } 246 247 } // namespace chromeos 248