Home | History | Annotate | Download | only in mobile
      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