123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- // Copyright 2019 The Chromium 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 "ash/services/cellular_setup/ota_activator_impl.h"
- #include <memory>
- #include <utility>
- #include "ash/services/cellular_setup/public/cpp/fake_activation_delegate.h"
- #include "base/run_loop.h"
- #include "base/test/metrics/histogram_tester.h"
- #include "base/test/task_environment.h"
- #include "base/test/test_simple_task_runner.h"
- #include "chromeos/ash/components/network/fake_network_activation_handler.h"
- #include "chromeos/ash/components/network/fake_network_connection_handler.h"
- #include "chromeos/ash/components/network/network_connection_handler.h"
- #include "chromeos/ash/components/network/network_state_handler.h"
- #include "chromeos/ash/components/network/network_state_test_helper.h"
- #include "mojo/public/cpp/bindings/remote.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/cros_system_api/dbus/service_constants.h"
- #include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
- namespace ash::cellular_setup {
- namespace {
- const char kTestCellularDevicePath[] = "/device/wwan0";
- const char kTestCellularDeviceName[] = "testDeviceName";
- const char kTestCellularDeviceCarrier[] = "testDeviceCarrier";
- const char kTestCellularDeviceMeid[] = "testDeviceMeid";
- const char kTestCellularDeviceImei[] = "testDeviceImei";
- const char kTestCellularDeviceMdn[] = "testDeviceMdn";
- const char kTestCellularServicePath[] = "/service/cellular0";
- const char kTestCellularServiceIccid[] = "1234567890";
- const char kTestCellularServiceGuid[] = "testServiceGuid";
- const char kTestCellularServiceName[] = "testServiceName";
- const char kTestCellularServicePaymentUrl[] = "testServicePaymentUrl.com";
- const char kTestCellularServicePaymentPostData[] = "testServicePostData";
- const char kPaymentPortalMethodPost[] = "POST";
- } // namespace
- class CellularSetupOtaActivatorImplTest : public testing::Test {
- public:
- CellularSetupOtaActivatorImplTest(const CellularSetupOtaActivatorImplTest&) =
- delete;
- CellularSetupOtaActivatorImplTest& operator=(
- const CellularSetupOtaActivatorImplTest&) = delete;
- protected:
- CellularSetupOtaActivatorImplTest()
- : test_helper_(false /* use_default_devices_and_services */) {}
- ~CellularSetupOtaActivatorImplTest() override = default;
- // testing::Test:
- void SetUp() override {
- fake_activation_delegate_ = std::make_unique<FakeActivationDelegate>();
- fake_network_connection_handler_ =
- std::make_unique<FakeNetworkConnectionHandler>();
- fake_network_activation_handler_ =
- std::make_unique<FakeNetworkActivationHandler>();
- }
- void BuildOtaActivator() {
- auto test_task_runner = base::MakeRefCounted<base::TestSimpleTaskRunner>();
- ota_activator_ = OtaActivatorImpl::Factory::Create(
- fake_activation_delegate_->GenerateRemote(),
- base::BindOnce(&CellularSetupOtaActivatorImplTest::OnFinished,
- base::Unretained(this)),
- test_helper_.network_state_handler(),
- fake_network_connection_handler_.get(),
- fake_network_activation_handler_.get(), test_task_runner);
- test_task_runner->RunUntilIdle();
- carrier_portal_handler_remote_.Bind(ota_activator_->GenerateRemote());
- }
- void AddCellularDevice(bool has_valid_sim, bool has_physical_slots = true) {
- ShillDeviceClient::TestInterface* device_test = test_helper_.device_test();
- device_test->AddDevice(kTestCellularDevicePath, shill::kTypeCellular,
- kTestCellularDeviceName);
- if (has_valid_sim) {
- device_test->SetDeviceProperty(
- kTestCellularDevicePath, shill::kSIMPresentProperty,
- base::Value(true), false /* notify_changed */);
- device_test->SetDeviceProperty(
- kTestCellularDevicePath, shill::kSIMSlotInfoProperty,
- CreateCellularSIMSlotInfo(kTestCellularServiceIccid),
- false /* notify_changed */);
- base::DictionaryValue home_provider;
- home_provider.SetString(shill::kOperatorNameKey,
- kTestCellularDeviceCarrier);
- device_test->SetDeviceProperty(kTestCellularDevicePath,
- shill::kHomeProviderProperty,
- home_provider, false /* notify_changed */);
- device_test->SetDeviceProperty(
- kTestCellularDevicePath, shill::kMeidProperty,
- base::Value(kTestCellularDeviceMeid), false /* notify_changed */);
- device_test->SetDeviceProperty(
- kTestCellularDevicePath, shill::kImeiProperty,
- base::Value(kTestCellularDeviceImei), false /* notify_changed */);
- device_test->SetDeviceProperty(
- kTestCellularDevicePath, shill::kMdnProperty,
- base::Value(kTestCellularDeviceMdn), false /* notify_changed */);
- } else {
- std::string eid = has_physical_slots ? std::string() : "test_eid";
- device_test->SetDeviceProperty(
- kTestCellularDevicePath, shill::kSIMSlotInfoProperty,
- CreateCellularSIMSlotInfo(kTestCellularServiceIccid, eid),
- false /* notify_changed */);
- }
- base::RunLoop().RunUntilIdle();
- }
- void RemoveCellularDevice() {
- test_helper_.device_test()->RemoveDevice(kTestCellularDevicePath);
- base::RunLoop().RunUntilIdle();
- }
- void AddCellularNetwork(bool has_valid_payment_info,
- bool is_connected,
- bool is_already_activated) {
- ShillServiceClient::TestInterface* service_test =
- test_helper_.service_test();
- service_test->AddService(
- kTestCellularServicePath, kTestCellularServiceGuid,
- kTestCellularServiceName, shill::kTypeCellular,
- is_connected ? shill::kStateOnline : shill::kStateIdle, true);
- service_test->SetServiceProperty(kTestCellularServicePath,
- shill::kIccidProperty,
- base::Value(kTestCellularServiceIccid));
- service_test->SetServiceProperty(
- kTestCellularServicePath, shill::kActivationStateProperty,
- is_already_activated
- ? base::Value(shill::kActivationStateActivated)
- : base::Value(shill::kActivationStateNotActivated));
- if (has_valid_payment_info) {
- base::DictionaryValue payment_portal;
- payment_portal.SetString(shill::kPaymentPortalURL,
- kTestCellularServicePaymentUrl);
- payment_portal.SetString(shill::kPaymentPortalMethod,
- kPaymentPortalMethodPost);
- payment_portal.SetString(shill::kPaymentPortalPostData,
- kTestCellularServicePaymentPostData);
- service_test->SetServiceProperty(kTestCellularServicePath,
- shill::kPaymentPortalProperty,
- payment_portal);
- }
- base::RunLoop().RunUntilIdle();
- }
- void RemoveCellularNetwork() {
- test_helper_.service_test()->RemoveService(kTestCellularServicePath);
- base::RunLoop().RunUntilIdle();
- }
- void FlushForTesting() {
- static_cast<OtaActivatorImpl*>(ota_activator_.get())->FlushForTesting();
- }
- void VerifyCellularMetadataReceivedByDelegate() {
- const std::vector<mojom::CellularMetadataPtr>& cellular_metadata_list =
- fake_activation_delegate_->cellular_metadata_list();
- ASSERT_EQ(1u, cellular_metadata_list.size());
- EXPECT_EQ(GURL(kTestCellularServicePaymentUrl),
- cellular_metadata_list[0]->payment_url);
- EXPECT_EQ(kTestCellularDeviceCarrier, cellular_metadata_list[0]->carrier);
- EXPECT_EQ(kTestCellularDeviceMeid, cellular_metadata_list[0]->meid);
- EXPECT_EQ(kTestCellularDeviceImei, cellular_metadata_list[0]->imei);
- EXPECT_EQ(kTestCellularDeviceMdn, cellular_metadata_list[0]->mdn);
- }
- void UpdateCarrierPortalState(
- mojom::CarrierPortalStatus carrier_portal_status) {
- carrier_portal_handler_remote_->OnCarrierPortalStatusChange(
- carrier_portal_status);
- carrier_portal_handler_remote_.FlushForTesting();
- }
- void ConnectCellularNetwork() {
- const std::vector<FakeNetworkConnectionHandler::ConnectionParams>&
- connect_calls = fake_network_connection_handler_->connect_calls();
- ASSERT_FALSE(connect_calls.empty());
- // A connection should have been requested by |ota_activator_|.
- EXPECT_EQ(kTestCellularServicePath, connect_calls.back().service_path());
- // Simulate the connection succeeding.
- test_helper_.service_test()->SetServiceProperty(
- kTestCellularServicePath, shill::kStateProperty,
- base::Value(shill::kStateOnline));
- base::RunLoop().RunUntilIdle();
- }
- void FailCellularNetworkConnect() {
- std::vector<FakeNetworkConnectionHandler::ConnectionParams>& connect_calls =
- fake_network_connection_handler_->connect_calls();
- ASSERT_FALSE(connect_calls.empty());
- // A connection should have been requested by |ota_activator_|.
- EXPECT_EQ(kTestCellularServicePath, connect_calls.back().service_path());
- EXPECT_EQ(ConnectCallbackMode::ON_COMPLETED,
- connect_calls.back().connect_callback_mode());
- connect_calls.back().InvokeErrorCallback("fake_error");
- base::RunLoop().RunUntilIdle();
- }
- size_t ConnectCallCount() {
- return fake_network_connection_handler_->connect_calls().size();
- }
- void InvokePendingActivationCallback(bool success) {
- std::vector<FakeNetworkActivationHandler::ActivationParams>&
- complete_activation_calls =
- fake_network_activation_handler_->complete_activation_calls();
- ASSERT_EQ(1u, complete_activation_calls.size());
- EXPECT_EQ(kTestCellularServicePath,
- complete_activation_calls[0].service_path());
- if (success) {
- complete_activation_calls[0].InvokeSuccessCallback();
- } else {
- complete_activation_calls[0].InvokeErrorCallback("error");
- }
- }
- void VerifyActivationFinished(mojom::ActivationResult activation_result) {
- const std::vector<mojom::ActivationResult>& activation_results =
- fake_activation_delegate_->activation_results();
- ASSERT_EQ(1u, activation_results.size());
- EXPECT_EQ(activation_result, activation_results[0]);
- histogram_tester_.ExpectBucketCount(
- "Network.Cellular.PSim.OtaActivationResult", activation_result,
- /*expected_count=*/1);
- EXPECT_TRUE(is_finished_);
- }
- void DisconnectDelegate() {
- fake_activation_delegate_->DisconnectReceivers();
- }
- void FastForwardByConnectRetryDelay() {
- task_environment_.FastForwardBy(OtaActivatorImpl::kConnectRetryDelay);
- }
- bool is_finished() { return is_finished_; }
- private:
- void OnFinished() {
- EXPECT_FALSE(is_finished_);
- is_finished_ = true;
- }
- base::Value CreateCellularSIMSlotInfo(
- const std::string& iccid,
- const std::string& eid = std::string()) {
- base::Value::List sim_slot_infos;
- base::Value::Dict slot_info_item;
- slot_info_item.Set(shill::kSIMSlotInfoEID, eid);
- slot_info_item.Set(shill::kSIMSlotInfoICCID, iccid);
- slot_info_item.Set(shill::kSIMSlotInfoPrimary, false);
- sim_slot_infos.Append(std::move(slot_info_item));
- return base::Value(std::move(sim_slot_infos));
- }
- base::test::TaskEnvironment task_environment_{
- base::test::TaskEnvironment::TimeSource::MOCK_TIME};
- NetworkStateTestHelper test_helper_;
- base::HistogramTester histogram_tester_;
- std::unique_ptr<FakeActivationDelegate> fake_activation_delegate_;
- std::unique_ptr<FakeNetworkConnectionHandler>
- fake_network_connection_handler_;
- std::unique_ptr<FakeNetworkActivationHandler>
- fake_network_activation_handler_;
- std::unique_ptr<OtaActivator> ota_activator_;
- mojo::Remote<mojom::CarrierPortalHandler> carrier_portal_handler_remote_;
- bool is_finished_ = false;
- };
- TEST_F(CellularSetupOtaActivatorImplTest, Success) {
- AddCellularDevice(true /* has_valid_sim */);
- AddCellularNetwork(true /* has_valid_payment_info */, true /* is_connected */,
- false /* is_already_activated */);
- BuildOtaActivator();
- FlushForTesting();
- VerifyCellularMetadataReceivedByDelegate();
- UpdateCarrierPortalState(
- mojom::CarrierPortalStatus::kPortalLoadedWithoutPaidUser);
- UpdateCarrierPortalState(
- mojom::CarrierPortalStatus::kPortalLoadedAndUserCompletedPayment);
- InvokePendingActivationCallback(true /* success */);
- FlushForTesting();
- VerifyActivationFinished(
- mojom::ActivationResult::kSuccessfullyStartedActivation);
- }
- TEST_F(CellularSetupOtaActivatorImplTest, SuccessWithPaymentError) {
- AddCellularDevice(true /* has_valid_sim */);
- AddCellularNetwork(true /* has_valid_payment_info */, true /* is_connected */,
- false /* is_already_activated */);
- BuildOtaActivator();
- FlushForTesting();
- VerifyCellularMetadataReceivedByDelegate();
- UpdateCarrierPortalState(
- mojom::CarrierPortalStatus::kPortalLoadedWithoutPaidUser);
- UpdateCarrierPortalState(
- mojom::CarrierPortalStatus::kPortalLoadedButErrorOccurredDuringPayment);
- InvokePendingActivationCallback(true /* success */);
- FlushForTesting();
- VerifyActivationFinished(
- mojom::ActivationResult::kSuccessfullyStartedActivation);
- }
- TEST_F(CellularSetupOtaActivatorImplTest, HasNoPhysicalSlots) {
- AddCellularDevice(false /* has_valid_sim */, false /* has_physical_slots */);
- BuildOtaActivator();
- FlushForTesting();
- VerifyActivationFinished(mojom::ActivationResult::kFailedToActivate);
- }
- TEST_F(CellularSetupOtaActivatorImplTest, ConnectRetry) {
- AddCellularDevice(true /* has_valid_sim */);
- AddCellularNetwork(true /* has_valid_payment_info */,
- false /* is_connected */,
- false /* is_already_activated */);
- BuildOtaActivator();
- EXPECT_EQ(1u, ConnectCallCount());
- FailCellularNetworkConnect();
- // Ensure the a new connect call is not issued immediately.
- EXPECT_EQ(1u, ConnectCallCount());
- FastForwardByConnectRetryDelay();
- EXPECT_EQ(2u, ConnectCallCount());
- ConnectCellularNetwork();
- FlushForTesting();
- VerifyCellularMetadataReceivedByDelegate();
- UpdateCarrierPortalState(
- mojom::CarrierPortalStatus::kPortalLoadedWithoutPaidUser);
- UpdateCarrierPortalState(
- mojom::CarrierPortalStatus::kPortalLoadedAndUserCompletedPayment);
- InvokePendingActivationCallback(true /* success */);
- FlushForTesting();
- VerifyActivationFinished(
- mojom::ActivationResult::kSuccessfullyStartedActivation);
- }
- TEST_F(CellularSetupOtaActivatorImplTest,
- SimAndPaymentInfoNotInitiallyPresent_AndNetworkNotConnected) {
- AddCellularDevice(false /* has_valid_sim */);
- AddCellularNetwork(false /* has_valid_payment_info */,
- false /* is_connected */,
- false /* is_already_activated */);
- BuildOtaActivator();
- RemoveCellularDevice();
- RemoveCellularNetwork();
- AddCellularDevice(true /* has_valid_sim */);
- AddCellularNetwork(true /* has_valid_payment_info */,
- false /* is_connected */,
- false /* is_already_activated */);
- ConnectCellularNetwork();
- FlushForTesting();
- VerifyCellularMetadataReceivedByDelegate();
- UpdateCarrierPortalState(
- mojom::CarrierPortalStatus::kPortalLoadedWithoutPaidUser);
- UpdateCarrierPortalState(
- mojom::CarrierPortalStatus::kPortalLoadedAndUserCompletedPayment);
- InvokePendingActivationCallback(true /* success */);
- FlushForTesting();
- VerifyActivationFinished(
- mojom::ActivationResult::kSuccessfullyStartedActivation);
- }
- TEST_F(CellularSetupOtaActivatorImplTest, AlreadyActivated) {
- AddCellularDevice(true /* has_valid_sim */);
- AddCellularNetwork(true /* has_valid_payment_info */, true /* is_connected */,
- true /* is_already_activated */);
- BuildOtaActivator();
- FlushForTesting();
- VerifyActivationFinished(mojom::ActivationResult::kAlreadyActivated);
- }
- TEST_F(CellularSetupOtaActivatorImplTest, DelegateBecomesDisconnected) {
- AddCellularDevice(true /* has_valid_sim */);
- AddCellularNetwork(true /* has_valid_payment_info */, true /* is_connected */,
- false /* is_already_activated */);
- BuildOtaActivator();
- DisconnectDelegate();
- FlushForTesting();
- // Note: Cannot check the ActivationResult received by the delegate because
- // the delegate was disconnected and did not receive the result.
- EXPECT_TRUE(is_finished());
- }
- } // namespace ash::cellular_setup
|