/* * Copyright (C) 2016, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <functional> #include <memory> #include <string> #include <vector> #include <android/hardware/wifi/offload/1.0/IOffload.h> #include <gtest/gtest.h> #include "wificond/tests/mock_offload.h" #include "wificond/tests/mock_offload_scan_callback_interface.h" #include "wificond/tests/mock_offload_service_utils.h" #include "wificond/tests/offload_hal_test_constants.h" #include "wificond/tests/offload_test_utils.h" #include "wificond/scanning/offload/offload_callback.h" #include "wificond/scanning/offload/offload_callback_handlers.h" #include "wificond/scanning/offload/offload_scan_manager.h" #include "wificond/scanning/scan_result.h" using android::hardware::Return; using android::hardware::Void; using android::hardware::wifi::offload::V1_0::IOffload; using android::hardware::wifi::offload::V1_0::ScanResult; using android::hardware::wifi::offload::V1_0::OffloadStatus; using android::hardware::wifi::offload::V1_0::OffloadStatusCode; using android::hardware::wifi::offload::V1_0::ScanParam; using android::hardware::wifi::offload::V1_0::ScanFilter; using android::hardware::wifi::offload::V1_0::ScanStats; using android::sp; using com::android::server::wifi::wificond::NativeScanResult; using com::android::server::wifi::wificond::NativeScanStats; using testing::NiceMock; using testing::_; using testing::Invoke; using std::shared_ptr; using std::unique_ptr; using std::vector; using std::bind; using namespace std::placeholders; using namespace android::wificond::offload_hal_test_constants; namespace android { namespace wificond { sp<OffloadCallback> CaptureCallback(OffloadCallbackHandlers* handler, sp<OffloadCallback>* offload_callback) { *offload_callback = sp<OffloadCallback>(new OffloadCallback(handler)); return *offload_callback; } OffloadDeathRecipient* CaptureDeathRecipient( OffloadDeathRecipientHandler handler, sp<OffloadDeathRecipient>* death_recipient_) { OffloadDeathRecipient* death_recipient = new OffloadDeathRecipient(handler); *death_recipient_ = sp<OffloadDeathRecipient>(death_recipient); return death_recipient; } Return<void> HidlStatusReturn(android::wificond::StatusCallback cb, OffloadStatus* status) { cb(*status); return Void(); } Return<void> ScanStatusReturn(android::wificond::OnScanStatsCallback cb, OffloadStatus* status) { ScanStats stats; cb(*status, stats); return Void(); } class OffloadScanManagerTest : public ::testing::Test { protected: virtual void SetUp() { ON_CALL(*mock_offload_service_utils_, GetOffloadCallback(_)) .WillByDefault(Invoke(bind(CaptureCallback, _1, &offload_callback_))); ON_CALL(*mock_offload_service_utils_, GetOffloadDeathRecipient(_)) .WillByDefault( Invoke(bind(CaptureDeathRecipient, _1, &death_recipient_))); status = OffloadTestUtils::createOffloadStatus(OffloadStatusCode::OK); ON_CALL(*mock_offload_, configureScans(_, _, _)) .WillByDefault(Invoke(bind(HidlStatusReturn, _3, &status))); ON_CALL(*mock_offload_, subscribeScanResults(_, _)) .WillByDefault(Invoke(bind(HidlStatusReturn, _2, &status))); ON_CALL(*mock_offload_, getScanStats(_)) .WillByDefault(Invoke(bind(ScanStatusReturn, _1, &status))); } void TearDown() override { offload_callback_.clear(); death_recipient_.clear(); } sp<NiceMock<MockOffload>> mock_offload_{new NiceMock<MockOffload>()}; sp<OffloadCallback> offload_callback_; sp<OffloadDeathRecipient> death_recipient_; shared_ptr<NiceMock<MockOffloadServiceUtils>> mock_offload_service_utils_{ new NiceMock<MockOffloadServiceUtils>()}; shared_ptr<NiceMock<MockOffloadScanCallbackInterface>> mock_offload_scan_callback_interface_{ new NiceMock<MockOffloadScanCallbackInterface>()}; unique_ptr<OffloadScanManager> offload_scan_manager_; OffloadStatus status; vector<vector<uint8_t>> scan_ssids{kSsid1, kSsid2}; vector<vector<uint8_t>> match_ssids{kSsid1, kSsid2}; vector<uint8_t> security_flags{kNetworkFlags, kNetworkFlags}; vector<uint32_t> frequencies{kFrequency1, kFrequency2}; uint64_t cookie_ = reinterpret_cast<uint64_t>(mock_offload_.get()); }; /** * Testing OffloadScanManager for binder death with registered cookie */ TEST_F(OffloadScanManagerTest, BinderDeathRegisteredCookieAndService) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadCallback(_)); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadDeathRecipient(_)); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(mock_offload_)); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); EXPECT_CALL(*mock_offload_scan_callback_interface_, OnOffloadError(_)); death_recipient_->serviceDied(cookie_, mock_offload_); EXPECT_EQ(OffloadScanManager::kNoService, offload_scan_manager_->getOffloadStatus()); } /** * Testing OffloadScanManager for binder death with invalid cookie */ TEST_F(OffloadScanManagerTest, BinderDeathUnregisteredCookie) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadDeathRecipient(_)); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(mock_offload_)); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); death_recipient_->serviceDied(kDeathCode, mock_offload_); EXPECT_FALSE(OffloadScanManager::kNoService == offload_scan_manager_->getOffloadStatus()); } /** * Testing OffloadScanManager with no handle on Offloal HAL service * and no registered handler for Offload Scan results */ TEST_F(OffloadScanManagerTest, ServiceNotAvailableTest) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(nullptr)); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); EXPECT_EQ(OffloadScanManager::kNoService, offload_scan_manager_->getOffloadStatus()); } /** * Testing OffloadScanManager when service is available and valid handler * registered for Offload Scan results */ TEST_F(OffloadScanManagerTest, ServiceAvailableTest) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadCallback(_)); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadDeathRecipient(_)); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(mock_offload_)); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); EXPECT_EQ(OffloadScanManager::kNoError, offload_scan_manager_->getOffloadStatus()); } /** * Testing OffloadScanManager when service is available and valid handler * is registered, test to ensure that registered handler is invoked when * scan results are available */ TEST_F(OffloadScanManagerTest, CallbackInvokedTest) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadCallback(_)); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadDeathRecipient(_)); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(mock_offload_)); EXPECT_CALL(*mock_offload_scan_callback_interface_, OnOffloadScanResult()); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); vector<ScanResult> dummy_scan_results_ = OffloadTestUtils::createOffloadScanResults(); offload_callback_->onScanResult(dummy_scan_results_); } /** * Testing OffloadScanManager when service is available and valid handler * is registered, ensure that error callback is invoked */ TEST_F(OffloadScanManagerTest, ErrorCallbackInvokedTest) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadCallback(_)); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadDeathRecipient(_)); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(mock_offload_)); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); OffloadStatus status = OffloadTestUtils::createOffloadStatus(OffloadStatusCode::ERROR); EXPECT_CALL(*mock_offload_scan_callback_interface_, OnOffloadError(_)); offload_callback_->onError(status); EXPECT_EQ(offload_scan_manager_->getOffloadStatus(), OffloadScanManager::kError); } /** * Testing OffloadScanManager for subscribing to the scan results from * Offload HAL when service is running without errors */ TEST_F(OffloadScanManagerTest, StartScanTestWhenServiceIsOk) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadCallback(_)); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadDeathRecipient(_)); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(mock_offload_)); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); EXPECT_CALL(*mock_offload_, subscribeScanResults(_, _)); EXPECT_CALL(*mock_offload_, configureScans(_, _, _)); OffloadScanManager::ReasonCode reason_code = OffloadScanManager::kNone; bool result = offload_scan_manager_->startScan( kDisconnectedModeScanIntervalMs, kRssiThreshold, scan_ssids, match_ssids, security_flags, frequencies, &reason_code); EXPECT_EQ(result, true); } /** * Testing OffloadScanManager for subscribing to the scan results from * Offload HAL when service is not available */ TEST_F(OffloadScanManagerTest, StartScanTestWhenServiceIsNotAvailable) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()).Times(2); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(nullptr)); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); OffloadScanManager::ReasonCode reason_code = OffloadScanManager::kNone; bool result = offload_scan_manager_->startScan( kDisconnectedModeScanIntervalMs, kRssiThreshold, scan_ssids, match_ssids, security_flags, frequencies, &reason_code); EXPECT_EQ(result, false); EXPECT_EQ(reason_code, OffloadScanManager::kNotAvailable); } /** * Testing OffloadScanManager for subscribing to the scan results from * Offload HAL when service is not working correctly */ TEST_F(OffloadScanManagerTest, StartScanTestWhenServiceIsNotConnected) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadCallback(_)); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadDeathRecipient(_)); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(mock_offload_)); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); OffloadStatus status = OffloadTestUtils::createOffloadStatus(OffloadStatusCode::NO_CONNECTION); offload_callback_->onError(status); OffloadScanManager::ReasonCode reason_code = OffloadScanManager::kNone; bool result = offload_scan_manager_->startScan( kDisconnectedModeScanIntervalMs, kRssiThreshold, scan_ssids, match_ssids, security_flags, frequencies, &reason_code); EXPECT_EQ(result, false); EXPECT_EQ(reason_code, OffloadScanManager::kNotAvailable); } /** * Testing OffloadScanManager for subscribing to the scan results from * Offload HAL twice when service is okay */ TEST_F(OffloadScanManagerTest, StartScanTwiceTestWhenServiceIsOk) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadCallback(_)); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadDeathRecipient(_)); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(mock_offload_)); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); EXPECT_CALL(*mock_offload_, subscribeScanResults(_, _)).Times(2); EXPECT_CALL(*mock_offload_, configureScans(_, _, _)).Times(2); OffloadScanManager::ReasonCode reason_code = OffloadScanManager::kNone; bool result = offload_scan_manager_->startScan( kDisconnectedModeScanIntervalMs, kRssiThreshold, scan_ssids, match_ssids, security_flags, frequencies, &reason_code); EXPECT_EQ(result, true); result = offload_scan_manager_->startScan( kDisconnectedModeScanIntervalMs, kRssiThreshold, scan_ssids, match_ssids, security_flags, frequencies, &reason_code); EXPECT_EQ(result, true); } /** * Testing OffloadScanManager for unsubscribing to the scan results from * Offload HAL when service is ok */ TEST_F(OffloadScanManagerTest, StopScanTestWhenServiceIsOk) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadCallback(_)); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadDeathRecipient(_)); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(mock_offload_)); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); EXPECT_CALL(*mock_offload_, subscribeScanResults(_, _)); EXPECT_CALL(*mock_offload_, configureScans(_, _, _)); EXPECT_CALL(*mock_offload_, unsubscribeScanResults()); OffloadScanManager::ReasonCode reason_code = OffloadScanManager::kNone; bool result = offload_scan_manager_->startScan( kDisconnectedModeScanIntervalMs, kRssiThreshold, scan_ssids, match_ssids, security_flags, frequencies, &reason_code); EXPECT_EQ(result, true); result = offload_scan_manager_->stopScan(&reason_code); EXPECT_EQ(result, true); } /** * Testing OffloadScanManager for unsubscribing to the scan results from * when service is not connected to the hardware */ TEST_F(OffloadScanManagerTest, StopScanTestWhenServiceIsNotConnectedAnymore) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadCallback(_)); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(mock_offload_)); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); EXPECT_CALL(*mock_offload_, subscribeScanResults(_, _)); EXPECT_CALL(*mock_offload_, configureScans(_, _, _)); OffloadScanManager::ReasonCode reason_code = OffloadScanManager::kNone; bool result = offload_scan_manager_->startScan( kDisconnectedModeScanIntervalMs, kRssiThreshold, scan_ssids, match_ssids, security_flags, frequencies, &reason_code); EXPECT_EQ(result, true); OffloadStatus status = OffloadTestUtils::createOffloadStatus(OffloadStatusCode::NO_CONNECTION); offload_callback_->onError(status); result = offload_scan_manager_->stopScan(&reason_code); EXPECT_EQ(result, false); } /** * Testing OffloadScanManager for getting scan statistics when the * Offload HAL service is running without errors */ TEST_F(OffloadScanManagerTest, getScanStatsTestWhenServiceIsOk) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadCallback(_)); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadDeathRecipient(_)); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(mock_offload_)); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); EXPECT_CALL(*mock_offload_, getScanStats(_)); NativeScanStats stats; bool result = offload_scan_manager_->getScanStats(&stats); EXPECT_EQ(result, true); } /** * Testing OffloadScanManager for getting scan statistics when the * Offload HAL service is not connected */ TEST_F(OffloadScanManagerTest, getScanStatsTestWhenServiceIsNotOk) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadCallback(_)); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadDeathRecipient(_)); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(mock_offload_)); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); OffloadStatus status = OffloadTestUtils::createOffloadStatus(OffloadStatusCode::NO_CONNECTION); offload_callback_->onError(status); EXPECT_CALL(*mock_offload_, getScanStats(_)).Times(0); NativeScanStats stats; bool result = offload_scan_manager_->getScanStats(&stats); EXPECT_EQ(result, false); } /** * Testing OffloadScanManager for subscribing to the scan results from * Offload HAL when service is running without errors, operation failure */ TEST_F(OffloadScanManagerTest, StartScanFailedTest) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadCallback(_)); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadDeathRecipient(_)); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(mock_offload_)); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); EXPECT_CALL(*mock_offload_, subscribeScanResults(_, _)).Times(0); EXPECT_CALL(*mock_offload_, configureScans(_, _, _)).Times(1); status = OffloadTestUtils::createOffloadStatus(OffloadStatusCode::ERROR); OffloadScanManager::ReasonCode reason_code = OffloadScanManager::kNone; bool result = offload_scan_manager_->startScan( kDisconnectedModeScanIntervalMs, kRssiThreshold, scan_ssids, match_ssids, security_flags, frequencies, &reason_code); EXPECT_EQ(result, false); EXPECT_EQ(reason_code, OffloadScanManager::kOperationFailed); } /** * Testing OffloadScanManager for getting scan statistics when the * Offload HAL service is running without errors, getting scan stats failure */ TEST_F(OffloadScanManagerTest, getScanStatsFailedTest) { EXPECT_CALL(*mock_offload_service_utils_, GetOffloadService()); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadCallback(_)); EXPECT_CALL(*mock_offload_service_utils_, GetOffloadDeathRecipient(_)); ON_CALL(*mock_offload_service_utils_, GetOffloadService()) .WillByDefault(testing::Return(mock_offload_)); offload_scan_manager_.reset(new OffloadScanManager( mock_offload_service_utils_, mock_offload_scan_callback_interface_)); status = OffloadTestUtils::createOffloadStatus(OffloadStatusCode::TIMEOUT); EXPECT_CALL(*mock_offload_, getScanStats(_)); NativeScanStats stats; bool result = offload_scan_manager_->getScanStats(&stats); EXPECT_EQ(result, false); } } // namespace wificond } // namespace android