Add sharing/fast_initiation to github.

PiperOrigin-RevId: 597004964
This commit is contained in:
Francis Tsui
2024-01-09 12:05:19 -08:00
committed by Copybara-Service
parent cd4963b0f9
commit 41d2d6fc4c
9 changed files with 1172 additions and 1 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ jobs:
- name: Build Presence
run: CC=clang CXX=clang++ bazel build --features=-layering_check //presence --spawn_strategy=standalone
- name: Build Sharing
run: CC=clang CXX=clang++ bazel build --features=-layering_check //sharing/proto:all //sharing/internal/public:nearby_context //sharing/common:all //sharing/scheduling:scheduling --spawn_strategy=standalone
run: CC=clang CXX=clang++ bazel build --features=-layering_check //sharing/proto:all //sharing/internal/public:nearby_context //sharing/common:all //sharing/scheduling:scheduling //sharing/fast_initiation:nearby_fast_initiation --spawn_strategy=standalone
build-rust-linux:
name: Build Rust on Linux
+69
View File
@@ -0,0 +1,69 @@
# Copyright 2024 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.
licenses(["notice"])
cc_library(
name = "nearby_fast_initiation",
srcs = [
"nearby_fast_initiation_impl.cc",
],
hdrs = [
"nearby_fast_initiation.h",
"nearby_fast_initiation_impl.h",
],
visibility = ["//visibility:public"],
deps = [
"//internal/base",
"//sharing/internal/api:platform",
"//sharing/internal/public:logging",
"//sharing/internal/public:types",
],
)
cc_library(
name = "test_support",
testonly = True,
srcs = [
"fake_nearby_fast_initiation.cc",
],
hdrs = [
"fake_nearby_fast_initiation.h",
"fake_nearby_fast_initiation_observer.h",
],
visibility = ["//visibility:public"],
deps = [
":nearby_fast_initiation",
"//internal/base",
"//sharing/internal/public:logging",
"//sharing/internal/public:types",
"@com_google_absl//absl/memory",
],
)
cc_test(
name = "nearby_fast_initiation_test",
srcs = [
"nearby_fast_initiation_impl_test.cc",
],
deps = [
":nearby_fast_initiation",
":test_support",
"//internal/platform/implementation/g3", # fixdeps: keep
"//sharing/internal/api:platform",
"//sharing/internal/test:nearby_test",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_googletest//:gtest_main",
],
)
@@ -0,0 +1,202 @@
// 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 "sharing/fast_initiation/fake_nearby_fast_initiation.h"
#include <functional>
#include <memory>
#include <utility>
#include "absl/memory/memory.h"
#include "sharing/fast_initiation/nearby_fast_initiation.h"
#include "sharing/internal/public/context.h"
#include "sharing/internal/public/logging.h"
namespace nearby {
namespace sharing {
void FakeNearbyFastInitiation::Factory::SetStartScanningError(
bool is_start_scanning_error) {
is_start_scanning_error_ = is_start_scanning_error;
}
void FakeNearbyFastInitiation::Factory::SetStartAdvertisingError(
bool is_start_advertising_error) {
is_start_advertising_error_ = is_start_advertising_error;
}
void FakeNearbyFastInitiation::Factory::SetLowEnergySupported(
bool is_low_energy_supported) {
is_low_energy_supported_ = is_low_energy_supported;
}
void FakeNearbyFastInitiation::Factory::SetScanOffloadSupported(
bool is_scan_offload_supported) {
is_scan_offload_supported_ = is_scan_offload_supported;
}
void FakeNearbyFastInitiation::Factory::SetAdvertisementOffloadSupported(
bool is_advertisement_offload_supported) {
is_advertisement_offload_supported_ = is_advertisement_offload_supported;
}
FakeNearbyFastInitiation*
FakeNearbyFastInitiation::Factory::GetNearbyFastInitiation() {
return fake_nearby_fast_initiation_;
}
std::unique_ptr<NearbyFastInitiation>
FakeNearbyFastInitiation::Factory::CreateInstance(Context* context) {
fake_nearby_fast_initiation_ = new FakeNearbyFastInitiation(context);
fake_nearby_fast_initiation_->SetStartScanningError(is_start_scanning_error_);
fake_nearby_fast_initiation_->SetStartAdvertisingError(
is_start_advertising_error_);
fake_nearby_fast_initiation_->SetLowEnergySupported(is_low_energy_supported_);
fake_nearby_fast_initiation_->SetScanOffloadSupported(
is_scan_offload_supported_);
fake_nearby_fast_initiation_->SetAdvertisementOffloadSupported(
is_advertisement_offload_supported_);
return absl::WrapUnique<NearbyFastInitiation>(fake_nearby_fast_initiation_);
}
FakeNearbyFastInitiation::FakeNearbyFastInitiation(Context* context)
: context_(context) {
NL_DCHECK(context_);
}
bool FakeNearbyFastInitiation::IsLowEnergySupported() {
return is_low_energy_supported_;
}
bool FakeNearbyFastInitiation::IsScanOffloadSupported() {
return is_scan_offload_supported_;
}
bool FakeNearbyFastInitiation::IsAdvertisementOffloadSupported() {
return is_advertisement_offload_supported_;
}
void FakeNearbyFastInitiation::StartScanning(
std::function<void()> devices_discovered_callback,
std::function<void()> devices_not_discovered_callback,
std::function<void()> error_callback) {
++start_scanning_call_count_;
if (is_start_scanning_error_) {
error_callback();
return;
}
is_scanning_ = true;
scanning_devices_discovered_callback_ =
std::move(devices_discovered_callback);
scanning_devices_not_discovered_callback_ =
std::move(devices_not_discovered_callback);
}
void FakeNearbyFastInitiation::StopScanning(std::function<void()> callback) {
++stop_scanning_call_count_;
is_scanning_ = false;
callback();
}
void FakeNearbyFastInitiation::StartAdvertising(
FastInitType type, std::function<void()> callback,
std::function<void()> error_callback) {
++start_advertising_call_count_;
if (is_start_advertising_error_) {
error_callback();
} else {
is_advertising_ = true;
callback();
}
}
void FakeNearbyFastInitiation::StopAdvertising(std::function<void()> callback) {
++stop_advertising_call_count_;
is_advertising_ = false;
callback();
}
void FakeNearbyFastInitiation::AddObserver(Observer* observer) {
observer_list_.AddObserver(observer);
}
void FakeNearbyFastInitiation::RemoveObserver(Observer* observer) {
observer_list_.RemoveObserver(observer);
}
bool FakeNearbyFastInitiation::HasObserver(Observer* observer) {
return observer_list_.HasObserver(observer);
}
// Fake methods
void FakeNearbyFastInitiation::SetStartScanningError(
bool is_start_scanning_error) {
is_start_scanning_error_ = is_start_scanning_error;
for (Observer* observer : observer_list_.GetObservers()) {
if (observer != nullptr) {
observer->HardwareErrorReported(this);
}
}
}
void FakeNearbyFastInitiation::SetStartAdvertisingError(
bool is_start_advertising_error) {
is_start_advertising_error_ = is_start_advertising_error;
for (Observer* observer : observer_list_.GetObservers()) {
if (observer != nullptr) {
observer->HardwareErrorReported(this);
}
}
}
void FakeNearbyFastInitiation::SetLowEnergySupported(
bool is_low_energy_supported) {
is_low_energy_supported_ = is_low_energy_supported;
}
void FakeNearbyFastInitiation::SetScanOffloadSupported(
bool is_scan_offload_supported) {
is_scan_offload_supported_ = is_scan_offload_supported;
}
void FakeNearbyFastInitiation::SetAdvertisementOffloadSupported(
bool is_advertisement_offload_supported) {
is_advertisement_offload_supported_ = is_advertisement_offload_supported;
}
int FakeNearbyFastInitiation::StartScanningCount() const {
return start_scanning_call_count_;
}
int FakeNearbyFastInitiation::StopScanningCount() const {
return stop_scanning_call_count_;
}
int FakeNearbyFastInitiation::StartAdvertisingCount() const {
return start_advertising_call_count_;
}
int FakeNearbyFastInitiation::StopAdvertisingCount() const {
return stop_advertising_call_count_;
}
void FakeNearbyFastInitiation::FireDevicesDetected() {
scanning_devices_discovered_callback_();
}
void FakeNearbyFastInitiation::FireDevicesNotDetected() {
scanning_devices_not_discovered_callback_();
}
} // namespace sharing
} // namespace nearby
@@ -0,0 +1,128 @@
// 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.
#ifndef THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_FAKE_NEARBY_FAST_INITIATION_H_
#define THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_FAKE_NEARBY_FAST_INITIATION_H_
#include <functional>
#include <memory>
#include "internal/base/observer_list.h"
#include "sharing/fast_initiation/nearby_fast_initiation.h"
#include "sharing/fast_initiation/nearby_fast_initiation_impl.h"
#include "sharing/internal/public/context.h"
namespace nearby {
namespace sharing {
// FakeNearbyFastInitiation is a fake implementation of NearbyFastInitiation.
// In the implementation, developers can simulate different output by calling
// faked methods, such as setting offload supports on scanning or advertising.
class FakeNearbyFastInitiation : public NearbyFastInitiation {
public:
class Factory : public NearbyFastInitiationImpl::Factory {
public:
Factory() = default;
~Factory() override = default;
void SetStartScanningError(bool is_start_scanning_error);
void SetStartAdvertisingError(bool is_start_advertising_error);
void SetLowEnergySupported(bool is_low_energy_supported);
void SetScanOffloadSupported(bool is_scan_offload_supported);
void SetAdvertisementOffloadSupported(
bool is_advertisement_offload_supported);
FakeNearbyFastInitiation* GetNearbyFastInitiation();
private:
std::unique_ptr<NearbyFastInitiation> CreateInstance(
Context* context) override;
bool is_start_scanning_error_ = false;
bool is_start_advertising_error_ = false;
bool is_low_energy_supported_ = true;
bool is_scan_offload_supported_ = true;
bool is_advertisement_offload_supported_ = true;
FakeNearbyFastInitiation* fake_nearby_fast_initiation_ = nullptr;
};
explicit FakeNearbyFastInitiation(Context* context);
~FakeNearbyFastInitiation() override = default;
bool IsLowEnergySupported() override;
bool IsScanOffloadSupported() override;
bool IsAdvertisementOffloadSupported() override;
void StartScanning(std::function<void()> devices_discovered_callback,
std::function<void()> devices_not_discovered_callback,
std::function<void()> error_callback) override;
void StopScanning(std::function<void()> callback) override;
void StartAdvertising(FastInitType type, std::function<void()> callback,
std::function<void()> error_callback) override;
void StopAdvertising(std::function<void()> callback) override;
bool IsScanning() const override { return is_scanning_; }
bool IsAdvertising() const override { return is_advertising_; }
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
bool HasObserver(Observer* observer) override;
// Fake methods
void SetStartScanningError(bool is_start_scanning_error);
void SetStartAdvertisingError(bool is_start_advertising_error);
void SetLowEnergySupported(bool is_low_energy_supported);
void SetScanOffloadSupported(bool is_scan_offload_supported);
void SetAdvertisementOffloadSupported(
bool is_advertisement_offload_supported);
int StartScanningCount() const;
int StopScanningCount() const;
int StartAdvertisingCount() const;
int StopAdvertisingCount() const;
void FireDevicesDetected();
void FireDevicesNotDetected();
private:
Context* context_;
bool is_scanning_ = false;
bool is_advertising_ = false;
bool is_start_scanning_error_ = false;
bool is_start_advertising_error_ = false;
bool is_low_energy_supported_ = true;
bool is_scan_offload_supported_ = true;
bool is_advertisement_offload_supported_ = true;
int start_scanning_call_count_ = 0;
int stop_scanning_call_count_ = 0;
int start_advertising_call_count_ = 0;
int stop_advertising_call_count_ = 0;
std::function<void()> scanning_devices_discovered_callback_ = nullptr;
std::function<void()> scanning_devices_not_discovered_callback_ = nullptr;
ObserverList<NearbyFastInitiation::Observer> observer_list_;
};
} // namespace sharing
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_FAKE_NEARBY_FAST_INITIATION_H_
@@ -0,0 +1,46 @@
// Copyright 2024 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.
#ifndef THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_FAKE_NEARBY_FAST_INITIATION_OBSERVER_H_
#define THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_FAKE_NEARBY_FAST_INITIATION_OBSERVER_H_
#include "sharing/fast_initiation/nearby_fast_initiation.h"
namespace nearby {
namespace sharing {
class FakeNearbyFastInitiationObserver : public NearbyFastInitiation::Observer {
public:
explicit FakeNearbyFastInitiationObserver(
NearbyFastInitiation* fast_init_manager) {
fast_init_manager_ = fast_init_manager;
num_hardware_error_reported_ = 0;
}
void HardwareErrorReported(NearbyFastInitiation* fast_init_manager) override {
if (fast_init_manager_ == fast_init_manager) {
num_hardware_error_reported_ += 1;
}
}
int GetNumHardwareErrorReported() { return num_hardware_error_reported_; }
private:
NearbyFastInitiation* fast_init_manager_;
int num_hardware_error_reported_;
};
} // namespace sharing
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_FAKE_NEARBY_FAST_INITIATION_OBSERVER_H_
@@ -0,0 +1,101 @@
// 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.
#ifndef THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_NEARBY_FAST_INITIATION_H_
#define THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_NEARBY_FAST_INITIATION_H_
#include <stdint.h>
#include <functional>
namespace nearby {
namespace sharing {
class NearbyFastInitiation {
public:
enum class Version { kV1 = 0 };
// Fast initialization type impacts on the metadata information in payload of
// advertising.
// kNotify = The sender is in the foreground, actively trying to send a file
// to another device. Receivers in the room should be alerted that they may
// need to enter Everyone mode to receive the file.
// kSilent = The phone is passively looking for nearby receivers, but the user
// has not explicitly tried to enter Nearby Share to send the file. The phone
// may cache the receivers nearby so that discovery is faster, or it may
// present these users on ambient surfaces
enum class FastInitType : uint8_t {
kNotify = 0,
kSilent = 1,
};
class Observer {
public:
virtual ~Observer() = default;
// Called when hardware error reported that requires PC restart
virtual void HardwareErrorReported(NearbyFastInitiation* fast_init) {}
};
virtual ~NearbyFastInitiation() = default;
virtual bool IsLowEnergySupported() = 0;
virtual bool IsScanOffloadSupported() = 0;
virtual bool IsAdvertisementOffloadSupported() = 0;
// Scans nearby devices using BLE.
// |devices_discovered_callback| is called when discovered devices from
// 0 to more. |devices_not_discovered_callback| is called when discovered
// devices become to 0 from more than one. |error_callback| is called
// when error happened.
virtual void StartScanning(
std::function<void()> devices_discovered_callback,
std::function<void()> devices_not_discovered_callback,
std::function<void()> error_callback) = 0;
// Stops Fast Initialization scanning. |callback| is called
// when scanning is stopped.
virtual void StopScanning(std::function<void()> callback) = 0;
// Begins broadcasting Fast Initiation advertisement. |callback| is called
// when advertising is started. |error_callback| is called if start
// advertising with errors.
// Note: FastInitType is currently hardcoded to kNotify under the hood. To
// support changing the FastInitType after initialization, additional APIs
// need to be added/refactored to Context to reinitialize/reset the
// FastInitiationManager with the desired type.
virtual void StartAdvertising(FastInitType type,
std::function<void()> callback,
std::function<void()> error_callback) = 0;
// Stop broadcasting Fast Initiation advertisements. |callback|
// is called when advertising is stopped.
virtual void StopAdvertising(std::function<void()> callback) = 0;
// Check the scanning status.
virtual bool IsScanning() const = 0;
// Check the advertising status.
virtual bool IsAdvertising() const = 0;
// Adds and removes observers for hardware error events.
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
virtual bool HasObserver(Observer* observer) = 0;
};
} // namespace sharing
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_NEARBY_FAST_INITIATION_H_
@@ -0,0 +1,299 @@
// 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 "sharing/fast_initiation/nearby_fast_initiation_impl.h"
#include <functional>
#include <memory>
#include <ostream>
#include <utility>
#include "sharing/fast_initiation/nearby_fast_initiation.h"
#include "sharing/internal/api/bluetooth_adapter.h"
#include "sharing/internal/api/fast_init_ble_beacon.h"
#include "sharing/internal/api/fast_initiation_manager.h"
#include "sharing/internal/public/context.h"
#include "sharing/internal/public/logging.h"
namespace nearby {
namespace sharing {
using ::nearby::api::FastInitiationManager;
NearbyFastInitiationImpl::Factory*
NearbyFastInitiationImpl::Factory::test_factory_ = nullptr;
std::unique_ptr<NearbyFastInitiation> NearbyFastInitiationImpl::Factory::Create(
Context* context) {
NL_DCHECK(context);
if (test_factory_) {
return test_factory_->CreateInstance(context);
}
return std::make_unique<NearbyFastInitiationImpl>(context);
}
void NearbyFastInitiationImpl::Factory::SetFactoryForTesting(
Factory* test_factory) {
test_factory_ = test_factory;
}
NearbyFastInitiationImpl::NearbyFastInitiationImpl(Context* context)
: context_(context) {
NL_DCHECK(context);
}
bool NearbyFastInitiationImpl::IsLowEnergySupported() {
return context_->GetBluetoothAdapter().IsLowEnergySupported();
}
bool NearbyFastInitiationImpl::IsScanOffloadSupported() {
return context_->GetBluetoothAdapter().IsScanOffloadSupported();
}
bool NearbyFastInitiationImpl::IsAdvertisementOffloadSupported() {
return context_->GetBluetoothAdapter().IsAdvertisementOffloadSupported();
}
bool NearbyFastInitiationImpl::IsScanning() const {
return context_->GetFastInitiationManager().IsScanning();
}
bool NearbyFastInitiationImpl::IsAdvertising() const {
return context_->GetFastInitiationManager().IsAdvertising();
}
void NearbyFastInitiationImpl::StartScanning(
std::function<void()> devices_discovered_callback,
std::function<void()> devices_not_discovered_callback,
std::function<void()> error_callback) {
if (IsScanning()) {
NL_LOG(WARNING) << __func__
<< ": FastInit BLE scanning was started already.";
error_callback();
return;
}
context_->GetFastInitiationManager().StartScanning(
std::move(devices_discovered_callback),
std::move(devices_not_discovered_callback),
[&, error_callback =
std::move(error_callback)](FastInitiationManager::Error error) {
ScanningErrorCodeCallbackHandler(error);
error_callback();
});
}
void NearbyFastInitiationImpl::StopScanning(std::function<void()> callback) {
if (!IsScanning()) {
NL_LOG(WARNING) << __func__ << ": FastInit BLE scanning is not running.";
callback();
return;
}
context_->GetFastInitiationManager().StopScanning(
[&, callback = std::move(callback)]() { callback(); });
}
void NearbyFastInitiationImpl::StartAdvertising(
FastInitType type, std::function<void()> callback,
std::function<void()> error_callback) {
if (IsAdvertising()) {
NL_LOG(WARNING) << __func__
<< ": FastInit BLE advertising was started already.";
error_callback();
return;
}
context_->GetFastInitiationManager().StartAdvertising(
::nearby::api::FastInitBleBeacon::FastInitType(type),
[&, callback = std::move(callback)]() { callback(); },
[&, error_callback =
std::move(error_callback)](FastInitiationManager::Error error) {
AdvertisingErrorCodeCallbackHandler(error);
error_callback();
});
}
void NearbyFastInitiationImpl::StopAdvertising(std::function<void()> callback) {
if (!IsAdvertising()) {
NL_LOG(WARNING) << __func__ << ": FastInit BLE advertising is not running.";
callback();
return;
}
context_->GetFastInitiationManager().StopAdvertising(
[&, callback = std::move(callback)]() { callback(); });
}
void NearbyFastInitiationImpl::ScanningErrorCodeCallbackHandler(
FastInitiationManager::Error error) {
switch (error) {
case FastInitiationManager::Error::kBluetoothRadioUnavailable:
for (Observer* observer : observer_list_.GetObservers()) {
if (observer != nullptr) {
observer->HardwareErrorReported(this);
}
}
NL_LOG(ERROR) << __func__
<< ": FastInit BLE scanning failed due to bluetooth radio "
"unavailable.";
break;
case FastInitiationManager::Error::kResourceInUse:
for (Observer* observer : observer_list_.GetObservers()) {
if (observer != nullptr) {
observer->HardwareErrorReported(this);
}
}
NL_LOG(ERROR)
<< __func__
<< ": FastInit BLE scanning failed due to bluetooth resources are "
"in use/at full capacity.";
break;
case FastInitiationManager::Error::kDisabledByPolicy:
NL_LOG(ERROR)
<< __func__
<< ": FastInit BLE scanning failed due to being disabled by policy.";
break;
case FastInitiationManager::Error::kDisabledByUser:
NL_LOG(ERROR)
<< __func__
<< ": FastInit BLE scanning failed due to being disabled by user.";
break;
case FastInitiationManager::Error::kHardwareNotSupported:
for (Observer* observer : observer_list_.GetObservers()) {
if (observer != nullptr) {
observer->HardwareErrorReported(this);
}
}
NL_LOG(ERROR)
<< __func__
<< ": FastInit BLE scanning failed due to hardware not supported.";
break;
case FastInitiationManager::Error::kTransportNotSupported:
for (Observer* observer : observer_list_.GetObservers()) {
if (observer != nullptr) {
observer->HardwareErrorReported(this);
}
}
NL_LOG(ERROR)
<< __func__
<< ": FastInit BLE scanning failed due to transport not supported.";
break;
case FastInitiationManager::Error::kConsentRequired:
NL_LOG(ERROR)
<< __func__
<< ": FastInit BLE scanning failed due to consent required.";
break;
case FastInitiationManager::Error::kUnknown:
for (Observer* observer : observer_list_.GetObservers()) {
if (observer != nullptr) {
observer->HardwareErrorReported(this);
}
}
NL_LOG(ERROR) << __func__
<< ": FastInit BLE scanning failed due to unknown reasons.";
break;
default:
break;
}
}
void NearbyFastInitiationImpl::AdvertisingErrorCodeCallbackHandler(
FastInitiationManager::Error error) {
switch (error) {
case FastInitiationManager::Error::kBluetoothRadioUnavailable:
for (Observer* observer : observer_list_.GetObservers()) {
if (observer != nullptr) {
observer->HardwareErrorReported(this);
}
}
NL_LOG(ERROR)
<< __func__
<< ": FastInit BLE advertising failed due to bluetooth radio "
"unavailable.";
break;
case FastInitiationManager::Error::kResourceInUse:
for (Observer* observer : observer_list_.GetObservers()) {
if (observer != nullptr) {
observer->HardwareErrorReported(this);
}
}
NL_LOG(ERROR)
<< __func__
<< ": FastInit BLE advertising failed due to bluetooth resources are "
"in use/at full capacity.";
break;
case FastInitiationManager::Error::kDisabledByPolicy:
NL_LOG(ERROR) << __func__
<< ": FastInit BLE advertising failed due to being "
"disabled by policy.";
break;
case FastInitiationManager::Error::kDisabledByUser:
NL_LOG(ERROR)
<< __func__
<< ": FastInit BLE advertising failed due to being disabled by user.";
break;
case FastInitiationManager::Error::kHardwareNotSupported:
for (Observer* observer : observer_list_.GetObservers()) {
if (observer != nullptr) {
observer->HardwareErrorReported(this);
}
}
NL_LOG(ERROR)
<< __func__
<< ": FastInit BLE advertising failed due to hardware not supported.";
break;
case FastInitiationManager::Error::kTransportNotSupported:
for (Observer* observer : observer_list_.GetObservers()) {
if (observer != nullptr) {
observer->HardwareErrorReported(this);
}
}
NL_LOG(ERROR) << __func__
<< ": FastInit BLE advertising failed due to transport not "
"supported.";
break;
case FastInitiationManager::Error::kConsentRequired:
NL_LOG(ERROR)
<< __func__
<< ": FastInit BLE advertising failed due to consent required.";
break;
case FastInitiationManager::Error::kUnknown:
for (Observer* observer : observer_list_.GetObservers()) {
if (observer != nullptr) {
observer->HardwareErrorReported(this);
}
}
NL_LOG(ERROR)
<< __func__
<< ": FastInit BLE advertising failed due to unknown reasons.";
break;
default:
break;
}
}
void NearbyFastInitiationImpl::AddObserver(Observer* observer) {
observer_list_.AddObserver(observer);
NL_LOG(INFO) << __func__ << ": Fast Initiation observer added.";
}
void NearbyFastInitiationImpl::RemoveObserver(Observer* observer) {
observer_list_.RemoveObserver(observer);
NL_LOG(INFO) << __func__ << ": Fast Initiation observer removed.";
}
bool NearbyFastInitiationImpl::HasObserver(Observer* observer) {
return observer_list_.HasObserver(observer);
}
} // namespace sharing
} // namespace nearby
@@ -0,0 +1,86 @@
// 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.
#ifndef THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_NEARBY_FAST_INITIATION_IMPL_H_
#define THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_NEARBY_FAST_INITIATION_IMPL_H_
#include <functional>
#include <memory>
#include "internal/base/observer_list.h"
#include "sharing/fast_initiation/nearby_fast_initiation.h"
#include "sharing/internal/api/fast_initiation_manager.h"
#include "sharing/internal/public/context.h"
namespace nearby {
namespace sharing {
class NearbyFastInitiationImpl : public NearbyFastInitiation {
public:
class Factory {
public:
static std::unique_ptr<NearbyFastInitiation> Create(Context* context);
static void SetFactoryForTesting(Factory* test_factory);
protected:
virtual ~Factory() = default;
virtual std::unique_ptr<NearbyFastInitiation> CreateInstance(
Context* context) = 0;
private:
static Factory* test_factory_;
};
explicit NearbyFastInitiationImpl(Context* context);
bool IsLowEnergySupported() override;
bool IsScanOffloadSupported() override;
bool IsAdvertisementOffloadSupported() override;
void StartScanning(std::function<void()> devices_discovered_callback,
std::function<void()> devices_not_discovered_callback,
std::function<void()> error_callback) override;
void StopScanning(std::function<void()> callback) override;
void StartAdvertising(FastInitType type, std::function<void()> callback,
std::function<void()> error_callback) override;
void StopAdvertising(std::function<void()> callback) override;
bool IsScanning() const override;
bool IsAdvertising() const override;
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
bool HasObserver(Observer* observer) override;
private:
// Handle the scanning error codes and print out to logs
void ScanningErrorCodeCallbackHandler(
nearby::api::FastInitiationManager::Error error);
// Handle the advertising error codes and print out to logs
void AdvertisingErrorCodeCallbackHandler(
nearby::api::FastInitiationManager::Error error);
Context* const context_;
ObserverList<NearbyFastInitiation::Observer> observer_list_;
};
} // namespace sharing
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_SHARING_FAST_INITIATION_NEARBY_FAST_INITIATION_IMPL_H_
@@ -0,0 +1,240 @@
// 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 "sharing/fast_initiation/nearby_fast_initiation_impl.h"
#include <functional>
#include <memory>
#include <string>
#include "gtest/gtest.h"
#include "sharing/fast_initiation/fake_nearby_fast_initiation_observer.h"
#include "sharing/fast_initiation/nearby_fast_initiation.h"
#include "sharing/internal/api/fast_initiation_manager.h"
#include "sharing/internal/test/fake_context.h"
#include "sharing/internal/test/fake_fast_initiation_manager.h"
namespace nearby {
namespace sharing {
namespace {
TEST(NearbyFastInitiationImpl, IsLowEnergySupported) {
auto fake_context = std::make_unique<FakeContext>();
NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get());
EXPECT_TRUE(nearby_fast_initiation_impl.IsLowEnergySupported());
}
TEST(NearbyFastInitiationImpl, IsScanOffloadSupported) {
auto fake_context = std::make_unique<FakeContext>();
NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get());
EXPECT_TRUE(nearby_fast_initiation_impl.IsScanOffloadSupported());
}
TEST(NearbyFastInitiationImpl, IsAdvertisementOffloadSupported) {
auto fake_context = std::make_unique<FakeContext>();
NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get());
EXPECT_TRUE(nearby_fast_initiation_impl.IsAdvertisementOffloadSupported());
}
TEST(NearbyFastInitiationImpl, HasObserverReturnsFalseAfterRemovingObserver) {
auto fake_context = std::make_unique<FakeContext>();
NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get());
FakeNearbyFastInitiationObserver fake_observer(&nearby_fast_initiation_impl);
nearby_fast_initiation_impl.AddObserver(&fake_observer);
EXPECT_TRUE(nearby_fast_initiation_impl.HasObserver(&fake_observer));
nearby_fast_initiation_impl.RemoveObserver(&fake_observer);
EXPECT_FALSE(nearby_fast_initiation_impl.HasObserver(&fake_observer));
}
TEST(NearbyFastInitiationImpl, HasObserver) {
auto fake_context = std::make_unique<FakeContext>();
NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get());
FakeNearbyFastInitiationObserver fake_observer(&nearby_fast_initiation_impl);
FakeNearbyFastInitiationObserver fake_observer_1(
&nearby_fast_initiation_impl);
FakeNearbyFastInitiationObserver fake_observer_2(
&nearby_fast_initiation_impl);
nearby_fast_initiation_impl.AddObserver(&fake_observer_1);
EXPECT_TRUE(nearby_fast_initiation_impl.HasObserver(&fake_observer_1));
EXPECT_FALSE(nearby_fast_initiation_impl.HasObserver(&fake_observer_2));
}
TEST(NearbyFastInitiationImpl, StartAdvertising) {
bool success_callback_called = false;
std::function<void()> success_callback = [&]() {
success_callback_called = true;
};
std::function<void()> error_callback = []() {};
auto fake_context = std::make_unique<FakeContext>();
NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get());
nearby_fast_initiation_impl.StartAdvertising(
NearbyFastInitiation::FastInitType::kNotify, success_callback,
error_callback);
FakeFastInitiationManager& fake_fast_initiation_manager =
dynamic_cast<FakeFastInitiationManager&>(
fake_context->GetFastInitiationManager());
fake_fast_initiation_manager.SetAdvertisingStarted();
EXPECT_TRUE(success_callback_called);
}
TEST(NearbyFastInitiationImpl, StartAdvertisingAndGetHardwareError) {
bool error_callback_called = false;
std::function<void()> success_callback = []() {};
std::function<void()> error_callback = [&]() {
error_callback_called = true;
};
auto fake_context = std::make_unique<FakeContext>();
NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get());
FakeNearbyFastInitiationObserver fake_observer(&nearby_fast_initiation_impl);
nearby_fast_initiation_impl.AddObserver(&fake_observer);
nearby_fast_initiation_impl.StartAdvertising(
NearbyFastInitiation::FastInitType::kNotify, success_callback,
error_callback);
FakeFastInitiationManager& fake_fast_initiation_manager =
dynamic_cast<FakeFastInitiationManager&>(
fake_context->GetFastInitiationManager());
// Mocking OS hardware error event on Windows
fake_fast_initiation_manager.SetAdvertisingError(
nearby::api::FastInitiationManager::Error::kBluetoothRadioUnavailable);
EXPECT_TRUE(error_callback_called);
EXPECT_EQ(fake_observer.GetNumHardwareErrorReported(), 1);
}
TEST(NearbyFastInitiationImpl, StopAdvertisingNotStart) {
bool success_callback_called = false;
std::function<void()> success_callback = [&]() {
success_callback_called = true;
};
auto fake_context = std::make_unique<FakeContext>();
NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get());
nearby_fast_initiation_impl.StopAdvertising(success_callback);
EXPECT_TRUE(success_callback_called);
}
TEST(NearbyFastInitiationImpl, StopStartedAdvertising) {
bool start_callback_called = false;
bool stop_callback_called = false;
auto fake_context = std::make_unique<FakeContext>();
FakeFastInitiationManager& fake_fast_initiation_manager =
dynamic_cast<FakeFastInitiationManager&>(
fake_context->GetFastInitiationManager());
NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get());
nearby_fast_initiation_impl.StartAdvertising(
NearbyFastInitiation::FastInitType::kNotify,
[&]() { start_callback_called = true; }, [&]() {});
fake_fast_initiation_manager.SetAdvertisingStarted();
EXPECT_TRUE(start_callback_called);
EXPECT_TRUE(nearby_fast_initiation_impl.IsAdvertising());
nearby_fast_initiation_impl.StopAdvertising(
[&]() { stop_callback_called = true; });
fake_fast_initiation_manager.SetAdvertisingStopped();
EXPECT_TRUE(stop_callback_called);
}
TEST(NearbyFastInitiationImpl, StartScanningSucceed) {
bool devices_discovered = false;
std::function<void()> devices_discovered_callback = [&devices_discovered]() {
devices_discovered = true;
};
std::function<void()> devices_not_discovered_callback = []() {};
std::function<void()> error_callback = []() {};
auto fake_context = std::make_unique<FakeContext>();
NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get());
nearby_fast_initiation_impl.StartScanning(devices_discovered_callback,
devices_not_discovered_callback,
error_callback);
FakeFastInitiationManager& fake_fast_initiation_manager =
dynamic_cast<FakeFastInitiationManager&>(
fake_context->GetFastInitiationManager());
fake_fast_initiation_manager.SetScanningDiscovered();
EXPECT_TRUE(devices_discovered);
}
TEST(NearbyFastInitiationImpl, StartScanningAndGetHardwareError) {
bool error_callback_called = false;
std::function<void()> devices_discovered_callback = []() {};
std::function<void()> devices_not_discovered_callback = []() {};
std::function<void()> error_callback = [&]() {
error_callback_called = true;
};
auto fake_context = std::make_unique<FakeContext>();
NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get());
FakeNearbyFastInitiationObserver fake_observer(&nearby_fast_initiation_impl);
nearby_fast_initiation_impl.AddObserver(&fake_observer);
nearby_fast_initiation_impl.StartScanning(devices_discovered_callback,
devices_not_discovered_callback,
error_callback);
FakeFastInitiationManager& fake_fast_initiation_manager =
dynamic_cast<FakeFastInitiationManager&>(
fake_context->GetFastInitiationManager());
// Mocking OS hardware error event on Windows
fake_fast_initiation_manager.SetScanningError(
nearby::api::FastInitiationManager::Error::kBluetoothRadioUnavailable);
EXPECT_TRUE(error_callback_called);
EXPECT_EQ(fake_observer.GetNumHardwareErrorReported(), 1);
}
TEST(NearbyFastInitiationImpl, StopScanningNotStart) {
bool stop_callback_called = false;
std::function<void()> success_callback = [&]() {
stop_callback_called = true;
};
auto fake_context = std::make_unique<FakeContext>();
NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get());
nearby_fast_initiation_impl.StopScanning(success_callback);
EXPECT_TRUE(stop_callback_called);
}
TEST(NearbyFastInitiationImpl, StopStartedScanning) {
bool stop_callback_called = false;
auto fake_context = std::make_unique<FakeContext>();
NearbyFastInitiationImpl nearby_fast_initiation_impl(fake_context.get());
FakeFastInitiationManager& fake_fast_initiation_manager =
dynamic_cast<FakeFastInitiationManager&>(
fake_context->GetFastInitiationManager());
nearby_fast_initiation_impl.StartScanning([]() {}, []() {}, []() {});
nearby_fast_initiation_impl.StopScanning(
[&]() { stop_callback_called = true; });
fake_fast_initiation_manager.SetScanningStopped();
EXPECT_TRUE(stop_callback_called);
}
} // namespace
} // namespace sharing
} // namespace nearby