C++程序  |  448行  |  19.75 KB

/*
 * 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