add scan function in presence BLE

PiperOrigin-RevId: 478666843
This commit is contained in:
Hai Shang
2022-10-03 19:35:23 -07:00
committed by Copybara-Service
parent 2fff61b312
commit c4ad6de6f8
6 changed files with 243 additions and 9 deletions
+2
View File
@@ -220,6 +220,7 @@ cc_library(
"//connections:__subpackages__",
"//internal/platform:__pkg__",
"//internal/platform/implementation:__subpackages__",
"//presence:__subpackages__",
],
deps = [
":base",
@@ -341,6 +342,7 @@ cc_library(
"//internal/platform/implementation/ios:__subpackages__",
"//internal/platform/implementation/windows:__subpackages__",
"//location/nearby/cpp/sharing:__subpackages__",
"//presence:__subpackages__",
],
deps = [
":base",
+1 -1
View File
@@ -70,7 +70,7 @@ cc_library(
"//internal/platform:__pkg__",
"//internal/platform/implementation:__subpackages__",
"//presence:__pkg__",
"//presence/implementation:__pkg__",
"//presence/implementation:__subpackages__",
],
deps = [
"//connections/implementation/proto:offline_wire_formats_cc_proto",
+32 -2
View File
@@ -15,7 +15,8 @@ licenses(["notice"])
cc_library(
name = "mediums",
srcs = [],
srcs = [
],
hdrs = [
"ble.h",
"mediums.h",
@@ -23,5 +24,34 @@ cc_library(
visibility = [
"//presence/implementation:__subpackages__",
],
deps = ["//internal/platform:comm"],
deps = [
"//internal/platform:comm",
"//internal/platform:uuid",
"//internal/platform/implementation:comm",
"//presence:types",
],
)
cc_test(
name = "mediums_test",
size = "small",
srcs = [
"ble_test.cc",
],
shard_count = 16,
deps = [
":mediums",
"//internal/platform:base",
"//internal/platform:comm",
"//internal/platform:test_util",
"//internal/platform:types",
"//internal/platform:uuid",
"//internal/platform/implementation:comm",
"//internal/platform/implementation/g3", # build_cleaner: keep
"//presence:types",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/time",
"@com_google_googletest//:gtest_main",
],
)
+50 -4
View File
@@ -15,24 +15,70 @@
#ifndef THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_BLE_H_
#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_BLE_H_
#include "internal/platform/ble_v2.h"
#include <memory>
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/uuid.h"
#include "presence/power_mode.h"
#include "presence/scan_request.h"
namespace nearby {
namespace presence {
/** Presence advertisement service data uuid. */
ABSL_CONST_INIT const location::nearby::Uuid kPresenceServiceUuid(
0x0000fcf100001000, 0x800000805f9b34fb);
using ScanningSession =
::location::nearby::api::ble_v2::BleMedium::ScanningSession;
using ScanningCallback =
::location::nearby::api::ble_v2::BleMedium::ScanningCallback;
using ::location::nearby::api::ble_v2::TxPowerLevel;
/*
* This Ble class utilizes platform/ble_v2 BleV2Medium, provides ble functions
* for presence logic layer to invoke.
* This class would have states like if ble is available or not, if it's doing
* broadcast/scan.
*/
template <typename Medium>
// since we are using template for test, then we need to keep functions defs in
// the header, more details: go/cstyle#Self_contained_Headers.
class Ble {
public:
Ble() = default;
explicit Ble(location::nearby::BluetoothAdapter& bluetooth_adapter)
: adapter_(bluetooth_adapter),
medium_(std::make_unique<Medium>(bluetooth_adapter)) {}
~Ble() = default;
// TODO(hais): add expected function set.
bool IsAvailable() const { return medium_->IsValid(); }
std::unique_ptr<ScanningSession> StartScanning(ScanRequest scan_request,
ScanningCallback callback) {
return medium_->StartScanning(
kPresenceServiceUuid,
ConvertPowerModeToPowerLevel(scan_request.power_mode), callback);
}
private:
location::nearby::BleV2Medium medium_;
friend class BleTest;
location::nearby::BluetoothAdapter& adapter_;
std::unique_ptr<Medium> medium_;
TxPowerLevel ConvertPowerModeToPowerLevel(PowerMode power_mode) {
switch (power_mode) {
case PowerMode::kNoPower:
return TxPowerLevel::kUnknown;
case PowerMode::kLowPower:
return TxPowerLevel::kLow;
case PowerMode::kBalanced:
return TxPowerLevel::kMedium;
case PowerMode::kLowLatency:
return TxPowerLevel::kHigh;
}
return TxPowerLevel::kUnknown;
}
};
} // namespace presence
+155
View File
@@ -0,0 +1,155 @@
// Copyright 2022 Google LLC
//
// 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
//
// https://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 "presence/implementation/mediums/ble.h"
#include <memory>
#include <string>
#include <vector>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "internal/platform/ble_v2.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/medium_environment.h"
#include "internal/platform/uuid.h"
#include "presence/data_element.h"
#include "presence/scan_request.h"
namespace nearby {
namespace presence {
using FeatureFlags = location::nearby::FeatureFlags::Flags;
using BleOperationStatus = location::nearby::api::ble_v2::BleOperationStatus;
using BleV2MediumStatus =
location::nearby::MediumEnvironment::BleV2MediumStatus;
using ScanningSession =
location::nearby::api::ble_v2::BleMedium::ScanningSession;
using TxPowerLevel = location::nearby::api::ble_v2::TxPowerLevel;
using ScanningCallback =
location::nearby::api::ble_v2::BleMedium::ScanningCallback;
using Uuid = location::nearby::Uuid;
constexpr FeatureFlags kTestCases[] = {
FeatureFlags{},
};
class BleTest : public testing::TestWithParam<FeatureFlags> {
public:
class MockBleMedium {
public:
explicit MockBleMedium(location::nearby::BluetoothAdapter& adapter){}
MOCK_METHOD((std::unique_ptr<ScanningSession>), StartScanning,
(const Uuid& service_uuid, TxPowerLevel tx_power_level,
ScanningCallback callback));
};
constexpr static absl::Duration kWaitDuration = absl::Milliseconds(1000);
std::string account_name_ = "Test-Name";
constexpr static PowerMode kPowerMode = PowerMode::kBalanced;
std::vector<nearby::internal::IdentityType> identity_types_ = {
nearby::internal::IdentityType::IDENTITY_TYPE_TRUSTED,
};
std::vector<DataElement> extended_properties_ = {
DataElement{DataElement::kTxPowerFieldType, "-10"}};
std::vector<absl::variant<PresenceScanFilter, LegacyPresenceScanFilter> >
filters_ = {PresenceScanFilter{
.scan_type = ScanType::kPresenceScan,
.extended_properties = extended_properties_,
}};
constexpr static bool kUseBle = true;
constexpr static ScanType kScanType = ScanType::kPresenceScan;
constexpr static bool kScanOnlyWhenScreenOn = true;
ScanRequest scan_request_ = {
.account_name = account_name_,
.identity_types = identity_types_,
.scan_filters = filters_,
.use_ble = kUseBle,
.scan_type = kScanType,
.power_mode = kPowerMode,
.scan_only_when_screen_on = kScanOnlyWhenScreenOn,
};
protected:
BleTest() { env_.Stop(); }
absl::optional<BleV2MediumStatus> GetBleStatus(
const Ble<location::nearby::BleV2Medium>& ble) {
return env_.GetBleV2MediumStatus(*ble.medium_->GetImpl());
}
MockBleMedium* GetMedium(const Ble<MockBleMedium>& ble) {
return ble.medium_.get();
}
location::nearby::MediumEnvironment& env_{
location::nearby::MediumEnvironment::Instance()};
};
INSTANTIATE_TEST_SUITE_P(ParametrisedBleTest, BleTest,
::testing::ValuesIn(kTestCases));
// Using MediumEnvironment to verify the start&stop StartScanning callback flows
// are working as intended.
TEST_P(BleTest, CanStartThenStopScanning) {
env_.Start();
::location::nearby::BluetoothAdapter adapter;
Ble<location::nearby::BleV2Medium> ble(adapter);
ScanRequest scan_request{
.power_mode = PowerMode::kBalanced,
};
ScanningCallback scanning_callback;
location::nearby::CountDownLatch started_scanning_latch(1);
std::unique_ptr<ScanningSession> scannning_session = ble.StartScanning(
scan_request,
ScanningCallback{
.start_scanning_result =
[&started_scanning_latch](BleOperationStatus status) {
if (status == BleOperationStatus::kSucceeded) {
started_scanning_latch.CountDown();
}
},
});
EXPECT_TRUE(started_scanning_latch.Await(kWaitDuration).result());
EXPECT_TRUE(GetBleStatus(ble).has_value() &&
GetBleStatus(ble).value().is_scanning == true);
BleOperationStatus stop_scanning_status = scannning_session->stop_scanning();
EXPECT_EQ(BleOperationStatus::kSucceeded, stop_scanning_status);
EXPECT_TRUE(GetBleStatus(ble).has_value() &&
GetBleStatus(ble).value().is_scanning == false);
env_.Stop();
}
// Using MockBleMedium to verify StartScanning is using the expected parameters
// with underneath BleMedium.
TEST_P(BleTest, VerifyStartScanning) {
env_.Start();
::location::nearby::BluetoothAdapter adapter;
Ble<MockBleMedium> ble(adapter);
EXPECT_CALL(*GetMedium(ble), StartScanning(kPresenceServiceUuid,
TxPowerLevel::kMedium, testing::_))
.Times(1);
std::unique_ptr<ScanningSession> scanning_session =
ble.StartScanning(scan_request_, ScanningCallback{});
env_.Stop();
}
} // namespace presence
} // namespace nearby
+3 -2
View File
@@ -15,6 +15,7 @@
#ifndef THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_MEDIUMS_H_
#define THIRD_PARTY_NEARBY_PRESENCE_IMPLEMENTATION_MEDIUMS_MEDIUMS_H_
#include "internal/platform/ble_v2.h"
#include "presence/implementation/mediums/ble.h"
namespace nearby {
@@ -30,10 +31,10 @@ class Mediums {
~Mediums() = default;
// Returns a handle to the Ble medium.
Ble& GetBle();
Ble<location::nearby::BleV2Medium>& GetBle();
private:
Ble ble_;
Ble<location::nearby::BleV2Medium> ble_;
};
} // namespace presence