OSDN Git Service

WifiCond: getScanStats() API in OffloadSCanManager
authorSohani Rao <sohanirao@google.com>
Fri, 14 Apr 2017 23:20:08 +0000 (16:20 -0700)
committerSohani Rao <sohanirao@google.com>
Wed, 3 May 2017 16:13:06 +0000 (09:13 -0700)
Introduce new API in OffloadScanManager getScanStats() to get scan stats
from Offload HAL. Created a parcelable NativeScanStats struct to export
this data and corresponding unit test coverage. Also included unit tests
to verify conversion from ScanStats in Offload HAL format to Wificond
format.

Test: Unit tests
Bug: 32842314
Change-Id: I82bec2cc42635588ef8cb3fd0ad3206242349645

14 files changed:
Android.mk
scanning/offload/offload_scan_manager.cpp
scanning/offload/offload_scan_manager.h
scanning/offload/offload_scan_utils.cpp
scanning/offload/offload_scan_utils.h
scanning/offload/scan_stats.cpp [new file with mode: 0644]
scanning/offload/scan_stats.h [new file with mode: 0644]
tests/offload_hal_test_constants.cpp [new file with mode: 0644]
tests/offload_hal_test_constants.h [new file with mode: 0644]
tests/offload_scan_manager_test.cpp
tests/offload_scan_utils_test.cpp
tests/offload_test_utils.cpp
tests/offload_test_utils.h
tests/scan_stats_unittest.cpp [new file with mode: 0644]

index dcb09bb..3be857d 100644 (file)
@@ -65,6 +65,7 @@ LOCAL_SRC_FILES := \
     scanning/pno_network.cpp \
     scanning/pno_settings.cpp \
     scanning/scan_result.cpp \
+    scanning/offload/scan_stats.cpp \
     scanning/single_scan_settings.cpp \
     scanning/scan_utils.cpp \
     scanning/scanner_impl.cpp \
@@ -175,11 +176,13 @@ LOCAL_SRC_FILES := \
     tests/nl80211_attribute_unittest.cpp \
     tests/nl80211_packet_unittest.cpp \
     tests/offload_callback_test.cpp \
+    tests/offload_hal_test_constants.cpp \
     tests/offload_scan_manager_test.cpp \
     tests/offload_scan_utils_test.cpp \
     tests/offload_test_utils.cpp \
     tests/scan_result_unittest.cpp \
     tests/scan_settings_unittest.cpp \
+    tests/scan_stats_unittest.cpp \
     tests/scan_utils_unittest.cpp \
     tests/server_unittest.cpp
 LOCAL_STATIC_LIBRARIES := \
index 137cf82..f19419f 100644 (file)
 #include "wificond/scanning/offload/offload_scan_utils.h"
 #include "wificond/scanning/offload/offload_service_utils.h"
 #include "wificond/scanning/scan_result.h"
+#include "wificond/scanning/offload/scan_stats.h"
 
 using ::android::hardware::hidl_vec;
 using android::hardware::wifi::offload::V1_0::IOffload;
 using android::hardware::wifi::offload::V1_0::ScanResult;
 using android::hardware::wifi::offload::V1_0::ScanFilter;
 using android::hardware::wifi::offload::V1_0::ScanParam;
+using android::hardware::wifi::offload::V1_0::ScanStats;
 using android::hardware::wifi::offload::V1_0::OffloadStatus;
 
 using android::wificond::OffloadCallback;
 using android::wificond::OnNativeScanResultsReadyHandler;
 using ::com::android::server::wifi::wificond::NativeScanResult;
-
+using ::com::android::server::wifi::wificond::NativeScanStats;
 using namespace std::placeholders;
 using std::vector;
 
@@ -147,6 +149,19 @@ OffloadScanManager::StatusCode OffloadScanManager::getOffloadStatus() const {
   return offload_status_;
 }
 
+bool OffloadScanManager::getScanStats(NativeScanStats* native_scan_stats) {
+  if (offload_status_ != OffloadScanManager::kNoError) {
+    LOG(ERROR) << "Unable to get scan stats due to Wifi Offload HAL error";
+    return false;
+  }
+  wifi_offload_hal_->getScanStats(
+      [&native_scan_stats] (ScanStats offload_scan_stats)-> void {
+          *native_scan_stats =
+              OffloadScanUtils::convertToNativeScanStats(offload_scan_stats);
+      });
+  return true;
+}
+
 OffloadScanManager::~OffloadScanManager() {}
 
 void OffloadScanManager::ReportScanResults(
index 70eada4..2a3ec0c 100644 (file)
@@ -35,6 +35,7 @@ namespace wifi {
 namespace wificond {
 
 class NativeScanResult;
+class NativeScanStats;
 
 }  // namespace wificond
 }  // namespace wifi
@@ -112,6 +113,9 @@ class OffloadScanManager {
    * is updated in case of failure.
    */
   bool stopScan(ReasonCode* /* failure reason */);
+  /* Get statistics for scans performed by Offload HAL */
+  bool getScanStats(
+      ::com::android::server::wifi::wificond::NativeScanStats* /* scanStats */);
   /* Otain status of the Offload HAL service */
   StatusCode getOffloadStatus() const;
 
index d8a034a..2ccae10 100644 (file)
 #include <android-base/logging.h>
 
 #include "wificond/scanning/scan_result.h"
+#include "wificond/scanning/offload/scan_stats.h"
 
 using ::com::android::server::wifi::wificond::NativeScanResult;
+using ::com::android::server::wifi::wificond::NativeScanStats;
 using android::hardware::wifi::offload::V1_0::ScanResult;
 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::hardware::wifi::offload::V1_0::NetworkInfo;
 using android::hardware::hidl_vec;
 using std::vector;
@@ -85,6 +88,31 @@ ScanFilter OffloadScanUtils::createScanFilter(
   return scan_filter;
 }
 
+NativeScanStats OffloadScanUtils::convertToNativeScanStats(
+    const ScanStats& scanStats) {
+  uint32_t num_channels_scanned = 0;
+  uint32_t scan_duration_ms = 0;
+  vector<uint8_t> histogram_channels;
+
+  for (size_t i = 0; i < scanStats.scanRecord.size(); i++) {
+    scan_duration_ms += scanStats.scanRecord[i].durationMs;
+    num_channels_scanned +=
+        scanStats.scanRecord[i].numChannelsScanned;
+  }
+  for (size_t i = 0; i < scanStats.histogramChannelsScanned.size(); i++) {
+    histogram_channels.push_back(
+      scanStats.histogramChannelsScanned[i]);
+  }
+
+  NativeScanStats native_scan_stats(scanStats.numScansRequestedByWifi,
+      scanStats.numScansServicedByWifi,
+      scanStats.subscriptionDurationMs,
+      scan_duration_ms,
+      num_channels_scanned,
+      histogram_channels);
+  return native_scan_stats;
+}
+
 } // namespace wificond
 } // namespace android
 
index 81541fb..34fe21a 100644 (file)
@@ -24,6 +24,7 @@
 using android::hardware::wifi::offload::V1_0::ScanResult;
 using android::hardware::wifi::offload::V1_0::ScanParam;
 using android::hardware::wifi::offload::V1_0::ScanFilter;
+using android::hardware::wifi::offload::V1_0::ScanStats;
 
 namespace com {
 namespace android {
@@ -32,6 +33,7 @@ namespace wifi {
 namespace wificond {
 
 class NativeScanResult;
+class NativeScanStats;
 
 }  // namespace wificond
 }  // namespace wifi
@@ -58,6 +60,8 @@ class OffloadScanUtils {
   static ScanFilter createScanFilter(
       const std::vector<std::vector<uint8_t>>& ssids,
       const std::vector<uint8_t>& flags, int8_t rssi_threshold);
+  static ::com::android::server::wifi::wificond::NativeScanStats
+      convertToNativeScanStats(const ScanStats& /* scanStats */);
 };
 
 }  // namespace wificond
diff --git a/scanning/offload/scan_stats.cpp b/scanning/offload/scan_stats.cpp
new file mode 100644 (file)
index 0000000..554e113
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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 "wificond/scanning/offload/scan_stats.h"
+
+#include <android-base/logging.h>
+
+#include "wificond/parcelable_utils.h"
+
+using android::status_t;
+
+namespace com {
+namespace android {
+namespace server {
+namespace wifi {
+namespace wificond {
+
+NativeScanStats::NativeScanStats(uint32_t num_scans_requested_by_wifi,
+    uint32_t num_scans_serviced_by_wifi,
+    uint32_t subscription_duration_ms,
+    uint32_t scan_duration_ms,
+    uint32_t num_channels_scanned,
+    std::vector<uint8_t> histogram_channels)
+    : num_scans_requested_by_wifi_(num_scans_requested_by_wifi),
+      num_scans_serviced_by_wifi_(num_scans_serviced_by_wifi),
+      subscription_duration_ms_(subscription_duration_ms),
+      scan_duration_ms_(scan_duration_ms),
+      num_channels_scanned_(num_channels_scanned),
+      time_stamp_(0),
+      histogram_channels_(histogram_channels) {
+}
+
+NativeScanStats::NativeScanStats()
+    : num_scans_requested_by_wifi_(0),
+      num_scans_serviced_by_wifi_(0),
+      subscription_duration_ms_(0),
+      num_channels_scanned_(0),
+      time_stamp_(0) {
+}
+
+bool NativeScanStats::operator==(const NativeScanStats& rhs) const {
+  bool result = true;
+  if ((rhs.num_scans_requested_by_wifi_ != num_scans_requested_by_wifi_) ||
+      (rhs.num_scans_serviced_by_wifi_ != num_scans_serviced_by_wifi_) ||
+      (rhs.scan_duration_ms_ != scan_duration_ms_) ||
+      (rhs.num_channels_scanned_ != num_channels_scanned_)) {
+    result = false;
+  }
+  if (rhs.histogram_channels_.size() != histogram_channels_.size()) {
+    return false;
+  }
+  for (size_t i = 0; i < histogram_channels_.size(); i++) {
+    if (rhs.histogram_channels_[i] != histogram_channels_[i]) {
+      result = false;
+    }
+  }
+  return result;
+}
+
+status_t NativeScanStats::writeToParcel(::android::Parcel* parcel) const {
+  RETURN_IF_FAILED(parcel->writeUint32(num_scans_requested_by_wifi_));
+  RETURN_IF_FAILED(parcel->writeUint32(num_scans_serviced_by_wifi_));
+  RETURN_IF_FAILED(parcel->writeUint32(subscription_duration_ms_));
+  RETURN_IF_FAILED(parcel->writeUint32(scan_duration_ms_));
+  RETURN_IF_FAILED(parcel->writeUint32(num_channels_scanned_));
+  RETURN_IF_FAILED(parcel->writeByteVector(histogram_channels_));
+  return ::android::OK;
+}
+
+status_t NativeScanStats::readFromParcel(const ::android::Parcel* parcel) {
+  RETURN_IF_FAILED(parcel->readUint32(&num_scans_requested_by_wifi_));
+  RETURN_IF_FAILED(parcel->readUint32(&num_scans_serviced_by_wifi_));
+  RETURN_IF_FAILED(parcel->readUint32(&subscription_duration_ms_));
+  RETURN_IF_FAILED(parcel->readUint32(&scan_duration_ms_));
+  RETURN_IF_FAILED(parcel->readUint32(&num_channels_scanned_));
+  RETURN_IF_FAILED(parcel->readByteVector(&histogram_channels_));
+  return ::android::OK;
+}
+
+
+}  // namespace wificond
+}  // namespace wifi
+}  // namespace server
+}  // namespace android
+}  // namespace com
diff --git a/scanning/offload/scan_stats.h b/scanning/offload/scan_stats.h
new file mode 100644 (file)
index 0000000..cae3e7e
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+#ifndef WIFICOND_SCAN_STATS_H
+#define WIFICOND_SCAN_STATS_H
+
+#include <vector>
+
+#include <binder/Parcel.h>
+#include <binder/Parcelable.h>
+
+namespace com {
+namespace android {
+namespace server {
+namespace wifi {
+namespace wificond {
+
+class NativeScanStats : public ::android::Parcelable {
+ public:
+  NativeScanStats();
+  NativeScanStats(uint32_t num_scans_requested_by_wifi,
+      uint32_t num_scans_serviced_by_wifi,
+      uint32_t subscription_duration_ms,
+      uint32_t scan_duration_ms,
+      uint32_t num_channels_scanned,
+      std::vector<uint8_t> histogram_channels);
+
+  bool operator==(const NativeScanStats&) const;
+  ::android::status_t writeToParcel(::android::Parcel* parcel) const override;
+  ::android::status_t readFromParcel(const ::android::Parcel* parcel) override;
+
+  uint32_t num_scans_requested_by_wifi_;
+  uint32_t num_scans_serviced_by_wifi_;
+  uint32_t subscription_duration_ms_;
+  uint32_t scan_duration_ms_;
+  uint32_t num_channels_scanned_;
+  uint32_t time_stamp_;
+  std::vector<uint8_t> histogram_channels_;
+};
+
+}  // namespace wificond
+}  // namespace wifi
+}  // namespace server
+}  // namespace android
+}  // namespace com
+#endif // WIFICOND_SCAN_STATS_H
+
diff --git a/tests/offload_hal_test_constants.cpp b/tests/offload_hal_test_constants.cpp
new file mode 100644 (file)
index 0000000..4214f56
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 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 "offload_hal_test_constants.h"
+
+namespace android {
+namespace wificond {
+namespace offload_hal_test_constants {
+
+const uint8_t kSsid1[] = { 'G', 'o', 'o', 'g', 'l', 'e' };
+const size_t kSsid1_size = sizeof(kSsid1);
+const uint8_t kSsid2[] = { 'X', 'f', 'i', 'n', 'i', 't', 'y' };
+const size_t kSsid2_size = sizeof(kSsid2);
+const uint8_t kBssid [6] = { 0x12, 0xef, 0xa1, 0x2c, 0x97, 0x8b };
+const int16_t kRssi = -60;
+const int16_t kRssiThreshold = -76;
+const uint32_t kFrequency1 = 2412;
+const uint32_t kFrequency2 = 2437;
+const uint8_t kBssidSize = 6;
+const uint64_t kTsf = 0;
+const uint16_t kCapability = 0;
+const uint8_t kNetworkFlags = 0;
+const uint32_t kDisconnectedModeScanIntervalMs = 5000;
+const uint64_t kSubscriptionDurationMs = 10000;
+const uint64_t kScanDurationMs[2] = { 2000, 500 };
+const uint32_t kNumChannelsScanned[2] = { 14, 6 };
+const uint8_t kDefaultNumTimesAChannelsIsScanned = 1;
+const uint8_t kChannelNotScanned = 0;
+const uint32_t kDefaultNumScansRequestedByWifi = 2;
+const uint32_t kDefaultNumScansServicedByWifi = 2;
+const uint64_t kScanDurationTotalMs = 2000;
+const uint32_t kNumChannelsTotalScanned = 20;
+
+}  // namespace offload_hal_test_constants
+}  // namespace wificond
+}  // namespace android
+
diff --git a/tests/offload_hal_test_constants.h b/tests/offload_hal_test_constants.h
new file mode 100644 (file)
index 0000000..d0b7138
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef WIFICOND_OFFLOAD_HAL_TEST_CONSTANTS_H_
+#define WIFICOND_OFFLOAD_HAL_TEST_CONSTANTS_H_
+
+#include <cstdint>
+
+namespace android {
+namespace wificond {
+namespace offload_hal_test_constants {
+
+extern const uint8_t kSsid1[];
+extern const size_t kSsid1_size;
+extern const uint8_t kSsid2[];
+extern const size_t kSsid2_size;
+extern const uint8_t kBssid [6];
+extern const int16_t kRssi;
+extern const int16_t kRssiThreshold;
+extern const uint32_t kFrequency1;
+extern const uint32_t kFrequency2;
+extern const uint8_t kBssidSize;
+extern const uint64_t kTsf;
+extern const uint16_t kCapability;
+extern const uint8_t kNetworkFlags;
+extern const uint32_t kDisconnectedModeScanIntervalMs;
+extern const uint64_t kSubscriptionDurationMs;
+extern const uint64_t kScanDurationMs[2];
+extern const uint32_t kNumChannelsScanned[2];
+extern const uint8_t kDefaultNumTimesAChannelsIsScanned;
+extern const uint8_t kChannelNotScanned;
+extern const uint32_t kDefaultNumScansRequestedByWifi;
+extern const uint32_t kDefaultNumScansServicedByWifi;
+extern const uint64_t kScanDurationTotalMs;
+extern const uint32_t kNumChannelsTotalScanned;
+
+}  // namespace offload_hal_test_constants
+}  // namespace wificond
+}  // namespace android
+
+#endif  // WIFICOND_OFFLOAD_HAL_TEST_CONSTANTS_H_
index 99e6aef..909bd81 100644 (file)
 #include <gtest/gtest.h>
 #include <android/hardware/wifi/offload/1.0/IOffload.h>
 
+#include "wificond/tests/offload_hal_test_constants.h"
+#include "wificond/tests/offload_test_utils.h"
 #include "wificond/tests/mock_offload.h"
 #include "wificond/tests/mock_offload_service_utils.h"
-#include "wificond/tests/offload_test_utils.h"
 
 #include "wificond/scanning/scan_result.h"
 #include "wificond/scanning/offload/offload_callback.h"
@@ -36,6 +37,7 @@ using android::hardware::wifi::offload::V1_0::OffloadStatus;
 using android::hardware::wifi::offload::V1_0::ScanParam;
 using android::hardware::wifi::offload::V1_0::ScanFilter;
 using com::android::server::wifi::wificond::NativeScanResult;
+using com::android::server::wifi::wificond::NativeScanStats;
 using testing::NiceMock;
 using testing::_;
 using testing::Invoke;
@@ -45,6 +47,7 @@ using std::vector;
 using std::bind;
 
 using namespace std::placeholders;
+using namespace android::wificond::offload_hal_test_constants;
 
 namespace android {
 namespace wificond {
@@ -74,6 +77,10 @@ class OffloadScanManagerTest: public ::testing::Test {
     unique_ptr<NiceMock<MockOffloadServiceUtils>> mock_offload_service_utils_{
         new NiceMock<MockOffloadServiceUtils>()};
     unique_ptr<OffloadScanManager> offload_scan_manager_;
+    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 };
 };
 
 /**
@@ -164,12 +171,9 @@ TEST_F(OffloadScanManagerTest, StartScanTestWhenServiceIsOk) {
       [] (vector<NativeScanResult> scanResult) -> void {}));
   EXPECT_CALL(*mock_offload_, subscribeScanResults(_));
   EXPECT_CALL(*mock_offload_, configureScans(_, _));
-  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 };
   OffloadScanManager::ReasonCode reason_code = OffloadScanManager::kNone;
-  bool result = offload_scan_manager_->startScan(kDisconnectedModeScanIntervalMs,
+  bool result = offload_scan_manager_->startScan(
+      kDisconnectedModeScanIntervalMs,
       kRssiThreshold,
       scan_ssids,
       match_ssids,
@@ -190,12 +194,9 @@ TEST_F(OffloadScanManagerTest, StartScanTestWhenServiceIsNotAvailable) {
   offload_scan_manager_ .reset(new OffloadScanManager(
       mock_offload_service_utils_.get(),
       [] (vector<NativeScanResult> scanResult) -> void {}));
-  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 };
   OffloadScanManager::ReasonCode reason_code = OffloadScanManager::kNone;
-  bool result = offload_scan_manager_->startScan(kDisconnectedModeScanIntervalMs,
+  bool result = offload_scan_manager_->startScan(
+      kDisconnectedModeScanIntervalMs,
       kRssiThreshold,
       scan_ssids,
       match_ssids,
@@ -217,13 +218,10 @@ TEST_F(OffloadScanManagerTest, StartScanTestWhenServiceIsNotConnected) {
   offload_scan_manager_ .reset(new OffloadScanManager(
       mock_offload_service_utils_.get(),
       [] (vector<NativeScanResult> scanResult) -> void {}));
-  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 };
   offload_callback_->onError(OffloadStatus::OFFLOAD_STATUS_NO_CONNECTION);
   OffloadScanManager::ReasonCode reason_code = OffloadScanManager::kNone;
-  bool result = offload_scan_manager_->startScan(kDisconnectedModeScanIntervalMs,
+  bool result = offload_scan_manager_->startScan(
+      kDisconnectedModeScanIntervalMs,
       kRssiThreshold,
       scan_ssids,
       match_ssids,
@@ -247,12 +245,9 @@ TEST_F(OffloadScanManagerTest, StartScanTwiceTestWhenServiceIsOk) {
       [] (vector<NativeScanResult> scanResult) -> void {}));
   EXPECT_CALL(*mock_offload_, subscribeScanResults(_)).Times(1);
   EXPECT_CALL(*mock_offload_, configureScans(_, _)).Times(2);
-  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 };
   OffloadScanManager::ReasonCode reason_code = OffloadScanManager::kNone;
-  bool result = offload_scan_manager_->startScan(kDisconnectedModeScanIntervalMs,
+  bool result = offload_scan_manager_->startScan(
+      kDisconnectedModeScanIntervalMs,
       kRssiThreshold,
       scan_ssids,
       match_ssids,
@@ -260,7 +255,8 @@ TEST_F(OffloadScanManagerTest, StartScanTwiceTestWhenServiceIsOk) {
       frequencies,
       &reason_code);
   EXPECT_EQ(result, true);
-  result = offload_scan_manager_->startScan(kDisconnectedModeScanIntervalMs,
+  result = offload_scan_manager_->startScan(
+      kDisconnectedModeScanIntervalMs,
       kRssiThreshold,
       scan_ssids,
       match_ssids,
@@ -284,12 +280,9 @@ TEST_F(OffloadScanManagerTest, StopScanTestWhenServiceIsOk) {
   EXPECT_CALL(*mock_offload_, subscribeScanResults(_));
   EXPECT_CALL(*mock_offload_, configureScans(_, _));
   EXPECT_CALL(*mock_offload_, unsubscribeScanResults());
-  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 };
   OffloadScanManager::ReasonCode reason_code = OffloadScanManager::kNone;
-  bool result = offload_scan_manager_->startScan(kDisconnectedModeScanIntervalMs,
+  bool result = offload_scan_manager_->startScan(
+      kDisconnectedModeScanIntervalMs,
       kRssiThreshold,
       scan_ssids,
       match_ssids,
@@ -332,12 +325,9 @@ TEST_F(OffloadScanManagerTest, StopScanTestWhenServiceIsNotConnectedAnymore) {
   EXPECT_CALL(*mock_offload_, subscribeScanResults(_));
   EXPECT_CALL(*mock_offload_, configureScans(_, _));
   EXPECT_CALL(*mock_offload_, unsubscribeScanResults());
-  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 };
   OffloadScanManager::ReasonCode reason_code = OffloadScanManager::kNone;
-  bool result = offload_scan_manager_->startScan(kDisconnectedModeScanIntervalMs,
+  bool result = offload_scan_manager_->startScan(
+      kDisconnectedModeScanIntervalMs,
       kRssiThreshold,
       scan_ssids,
       match_ssids,
@@ -350,6 +340,41 @@ TEST_F(OffloadScanManagerTest, StopScanTestWhenServiceIsNotConnectedAnymore) {
   EXPECT_EQ(result, true);
 }
 
+/**
+ * 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());
+  ON_CALL(*mock_offload_service_utils_, GetOffloadService())
+      .WillByDefault(testing::Return(mock_offload_));
+  offload_scan_manager_ .reset(new OffloadScanManager(
+      mock_offload_service_utils_.get(),
+      [] (vector<NativeScanResult> scanResult) -> void {}));
+  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());
+  ON_CALL(*mock_offload_service_utils_, GetOffloadService())
+      .WillByDefault(testing::Return(mock_offload_));
+  offload_scan_manager_ .reset(new OffloadScanManager(
+      mock_offload_service_utils_.get(),
+      [] (vector<NativeScanResult> scanResult) -> void {}));
+  offload_callback_->onError(OffloadStatus::OFFLOAD_STATUS_NO_CONNECTION);
+  EXPECT_CALL(*mock_offload_, getScanStats(_)).Times(0);
+  NativeScanStats stats;
+  bool result = offload_scan_manager_->getScanStats(&stats);
+  EXPECT_EQ(result, false);
 }
 
+} // namespace wificond
+} // namespace android
+
index 59a4b45..e01a298 100644 (file)
 #include <android-base/logging.h>
 #include "wificond/scanning/scan_result.h"
 #include "wificond/scanning/offload/offload_scan_utils.h"
+#include "wificond/tests/offload_hal_test_constants.h"
 
 using android::hardware::wifi::offload::V1_0::ScanResult;
 using android::hardware::wifi::offload::V1_0::ScanParam;
 using android::hardware::wifi::offload::V1_0::ScanFilter;
 using android::hardware::wifi::offload::V1_0::NetworkInfo;
+using android::hardware::wifi::offload::V1_0::ScanRecord;
+using android::hardware::wifi::offload::V1_0::ScanStats;
 using ::com::android::server::wifi::wificond::NativeScanResult;
+using ::com::android::server::wifi::wificond::NativeScanStats;
 using std::vector;
 
+using namespace android::wificond::offload_hal_test_constants;
+
 namespace android {
 namespace wificond {
 
@@ -67,7 +73,7 @@ TEST_F(OffloadScanUtilsTest, verifyScanParam) {
   ScanParam scanParam = OffloadScanUtils::createScanParam(scan_ssids, frequencies,
       kDisconnectedModeScanIntervalMs);
   EXPECT_EQ(scanParam.disconnectedModeScanIntervalMs,
-          kDisconnectedModeScanIntervalMs);
+      kDisconnectedModeScanIntervalMs);
   for (size_t i = 0; i < frequencies.size(); i++) {
     EXPECT_EQ(scanParam.frequencyList[i], frequencies[i]);
   }
@@ -98,5 +104,13 @@ TEST_F(OffloadScanUtilsTest, verifyScanFilter) {
   }
 }
 
+TEST_F(OffloadScanUtilsTest, verifyScanStats) {
+  NativeScanStats stats_expected;
+  ScanStats offload_scan_stats = OffloadTestUtils::createScanStats(&stats_expected);
+  NativeScanStats stats_returned = OffloadScanUtils::convertToNativeScanStats(
+    offload_scan_stats);
+  EXPECT_TRUE(stats_expected == stats_returned);
+}
+
 } // namespace wificond
 } // namespace android
index c0c3e15..6302f24 100644 (file)
 #include <vector>
 
 #include "wificond/tests/offload_test_utils.h"
+#include "wificond/tests/offload_hal_test_constants.h"
 
 using android::hardware::wifi::offload::V1_0::ScanResult;
+using android::hardware::wifi::offload::V1_0::ScanStats;
+using android::hardware::wifi::offload::V1_0::ScanRecord;
+using namespace android::wificond::offload_hal_test_constants;
 
 namespace android {
 namespace wificond {
@@ -26,7 +30,7 @@ namespace wificond {
 std::vector<ScanResult> OffloadTestUtils::createOffloadScanResults() {
   std::vector<ScanResult> scanResults;
   ScanResult scanResult;
-  std::vector<uint8_t> ssid(kSsid1, kSsid1 + sizeof(kSsid1));
+  std::vector<uint8_t> ssid(kSsid1, kSsid1 + kSsid1_size);
   scanResult.tsf = kTsf;
   scanResult.rssi = kRssi;
   scanResult.frequency = kFrequency1;
@@ -38,5 +42,46 @@ std::vector<ScanResult> OffloadTestUtils::createOffloadScanResults() {
   return scanResults;
 }
 
+ScanStats OffloadTestUtils::createScanStats(NativeScanStats* nativeScanStats) {
+  std::vector<ScanRecord> scan_records;
+  std::vector<uint8_t> histogram_channels;
+  uint32_t scan_duration_ms = 0;
+  uint32_t num_channels_scanned = 0;
+  ScanStats scan_stats;
+  int numEntriesInScanRecord =
+      sizeof(kNumChannelsScanned)/sizeof(kNumChannelsScanned[0]);
+  for (int i = 0; i < numEntriesInScanRecord; i++) {
+    ScanRecord scan_record;
+    scan_record.durationMs = kScanDurationMs[i];
+    scan_duration_ms += kScanDurationMs[i];
+    scan_record.numChannelsScanned = kNumChannelsScanned[i];
+    num_channels_scanned += kNumChannelsScanned[i];
+    scan_record.numEntriesAggregated = 1;
+    scan_records.push_back(scan_record);
+  }
+  scan_stats.scanRecord = scan_records;
+  scan_stats.numScansRequestedByWifi = kDefaultNumScansRequestedByWifi;
+  scan_stats.numScansServicedByWifi = kDefaultNumScansServicedByWifi;
+  scan_stats.subscriptionDurationMs = kSubscriptionDurationMs;
+  uint32_t skip_tmp = 256/num_channels_scanned;
+  for(size_t i = 0; i < 256; i++) {
+    if (i % skip_tmp == 0) {
+      scan_stats.histogramChannelsScanned[i] = kDefaultNumTimesAChannelsIsScanned;
+      histogram_channels.push_back(kDefaultNumTimesAChannelsIsScanned);
+    } else {
+      scan_stats.histogramChannelsScanned[i] = kChannelNotScanned;
+      histogram_channels.push_back(kChannelNotScanned);
+    }
+  }
+  NativeScanStats native_scan_stats(kDefaultNumScansRequestedByWifi,
+      kDefaultNumScansServicedByWifi,
+      kSubscriptionDurationMs,
+      scan_duration_ms,
+      num_channels_scanned,
+      histogram_channels);
+  *nativeScanStats = native_scan_stats;
+  return scan_stats;
+}
+
 } // namespace wificond
 } // namespace android
index 499d620..e624ec1 100644 (file)
 #include <android/hardware/wifi/offload/1.0/IOffload.h>
 #include <vector>
 
+#include "wificond/scanning/offload/scan_stats.h"
+
 using android::hardware::wifi::offload::V1_0::ScanResult;
+using android::hardware::wifi::offload::V1_0::ScanStats;
+using ::com::android::server::wifi::wificond::NativeScanStats;
 
 namespace android {
 namespace wificond {
 
-namespace {
-  const uint8_t kSsid1[] = { 'G', 'o', 'o', 'g', 'l', 'e' };
-  const uint8_t kSsid2[] = { 'X', 'f', 'i', 'n', 'i', 't', 'y' };
-  const uint8_t kBssid [6] = { 0x12, 0xef, 0xa1, 0x2c, 0x97, 0x8b };
-  const int16_t kRssi = -60;
-  const int16_t kRssiThreshold = -76;
-  const uint32_t kFrequency1 = 2412;
-  const uint32_t kFrequency2 = 2437;
-  const uint8_t kBssidSize = 6;
-  const uint64_t kTsf = 0;
-  const uint16_t kCapability = 0;
-  const uint8_t kNetworkFlags = 0;
-  const uint32_t kDisconnectedModeScanIntervalMs = 5000;
-} // namespace
-
 class OffloadTestUtils {
  public:
   static std::vector<ScanResult> createOffloadScanResults();
+  static ScanStats createScanStats(NativeScanStats* /* nativeScanStats */);
 };
 
 } // namespace wificond
diff --git a/tests/scan_stats_unittest.cpp b/tests/scan_stats_unittest.cpp
new file mode 100644 (file)
index 0000000..a867378
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017, 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 <vector>
+
+#include <gtest/gtest.h>
+
+#include "wificond/scanning/offload/scan_stats.h"
+#include "wificond/tests/offload_hal_test_constants.h"
+
+using ::com::android::server::wifi::wificond::NativeScanStats;
+using namespace android::wificond::offload_hal_test_constants;
+
+namespace android {
+namespace wificond {
+
+class ScanStatsTest : public ::testing::Test {
+};
+
+TEST_F(ScanStatsTest, ParcelableTest) {
+  std::vector<uint8_t> histogram_channels;
+  for(size_t i = 0; i < 256; i++) {
+    histogram_channels.push_back(255 - i);
+  }
+  NativeScanStats  scan_stats_in(kDefaultNumScansRequestedByWifi,
+      kDefaultNumScansServicedByWifi,
+      kScanDurationTotalMs,
+      kSubscriptionDurationMs,
+      kNumChannelsTotalScanned,
+      histogram_channels);
+  Parcel parcel;
+  EXPECT_EQ(::android::OK, scan_stats_in.writeToParcel(&parcel));
+  NativeScanStats scan_stats_out;
+  parcel.setDataPosition(0);
+  EXPECT_EQ(::android::OK, scan_stats_out.readFromParcel(&parcel));
+  EXPECT_TRUE(scan_stats_in == scan_stats_out);
+}
+
+} // namespace wificond
+} // namespace android