mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
Implement start advertising in service controller.
PiperOrigin-RevId: 489584407
This commit is contained in:
committed by
Copybara-Service
parent
d4551b7187
commit
a11733988f
@@ -726,6 +726,7 @@ MediumEnvironment::GetBleV2MediumStatus(const api::ble_v2::BleMedium& medium) {
|
||||
return;
|
||||
}
|
||||
BleV2MediumContext context = it->second;
|
||||
|
||||
result = BleV2MediumStatus{.is_advertising = context.advertising,
|
||||
.is_scanning = context.scanning};
|
||||
latch.CountDown();
|
||||
|
||||
@@ -83,7 +83,7 @@ struct BroadcastSession {
|
||||
// Nearby library would provide the implementation of this callback in
|
||||
// runtime. Assiging with a default value NotImplemented to surface potential
|
||||
// issue where library failed to provide the implementation.
|
||||
std::function<Status(void)> stop_broadcast_callback = []() {
|
||||
absl::AnyInvocable<Status(void)> stop_broadcast_callback = []() {
|
||||
return Status{Status::Value::kNotImplemented};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -135,6 +135,22 @@ cc_test(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "service_controller_impl_test",
|
||||
size = "small",
|
||||
srcs = ["service_controller_impl_test.cc"],
|
||||
deps = [
|
||||
":internal",
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:test_util",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation/g3", # build_cleaner: keep
|
||||
"//internal/proto:credential_cc_proto",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "encryption_test",
|
||||
size = "small",
|
||||
|
||||
@@ -15,18 +15,75 @@
|
||||
#include "presence/implementation/service_controller_impl.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/status/statusor.h"
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
#include "presence/implementation/advertisement_factory.h"
|
||||
#include "presence/implementation/base_broadcast_request.h"
|
||||
#include "presence/implementation/mediums/advertisement_data.h"
|
||||
#include "presence/status.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace presence {
|
||||
namespace {
|
||||
|
||||
using ::location::nearby::api::ble_v2::BleOperationStatus;
|
||||
using AdvertisingCallback =
|
||||
::location::nearby::api::ble_v2::BleMedium::AdvertisingCallback;
|
||||
using AdvertisingSession =
|
||||
::location::nearby::api::ble_v2::BleMedium::AdvertisingSession;
|
||||
|
||||
Status ConvertBleStatus(BleOperationStatus status) {
|
||||
return status == BleOperationStatus::kSucceeded
|
||||
? Status{Status::Value::kSuccess}
|
||||
: Status{Status::Value::kError};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<ScanSession> ServiceControllerImpl::StartScan(
|
||||
ScanRequest scan_request, ScanCallback callback) {
|
||||
return scan_manager_.StartScan(scan_request, callback);
|
||||
}
|
||||
|
||||
std::unique_ptr<BroadcastSession> ServiceControllerImpl::StartBroadcast(
|
||||
BroadcastRequest broadcast_request, BroadcastCallback callback) {
|
||||
callback.start_broadcast_cb({Status::Value::kError});
|
||||
return nullptr;
|
||||
absl::StatusOr<BaseBroadcastRequest> request =
|
||||
BaseBroadcastRequest::Create(broadcast_request);
|
||||
if (!request.ok()) {
|
||||
NEARBY_LOGS(WARNING) << "Invalid broadcast request, reason: "
|
||||
<< request.status();
|
||||
callback.start_broadcast_cb(Status{Status::Value::kError});
|
||||
return nullptr;
|
||||
}
|
||||
absl::StatusOr<AdvertisementData> advertisement =
|
||||
AdvertisementFactory(&credential_manager_).CreateAdvertisement(*request);
|
||||
if (!advertisement.ok()) {
|
||||
NEARBY_LOGS(WARNING) << "Can't create advertisement, reason: "
|
||||
<< advertisement.status();
|
||||
callback.start_broadcast_cb(Status{Status::Value::kError});
|
||||
return nullptr;
|
||||
}
|
||||
std::unique_ptr<AdvertisingSession> session =
|
||||
mediums_.GetBle().StartAdvertising(
|
||||
*advertisement, broadcast_request.power_mode,
|
||||
AdvertisingCallback{.start_advertising_result =
|
||||
[callback](BleOperationStatus status) {
|
||||
callback.start_broadcast_cb(
|
||||
ConvertBleStatus(status));
|
||||
}});
|
||||
if (!session) {
|
||||
NEARBY_LOGS(WARNING) << "Failed to start broadcasting";
|
||||
callback.start_broadcast_cb(Status{Status::Value::kError});
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_unique<BroadcastSession>(BroadcastSession{
|
||||
.stop_broadcast_callback = [session = std::move(session)]() {
|
||||
return ConvertBleStatus(session->stop_advertising());
|
||||
}});
|
||||
}
|
||||
|
||||
} // namespace presence
|
||||
|
||||
@@ -39,6 +39,9 @@ class ServiceControllerImpl : public ServiceController {
|
||||
std::unique_ptr<BroadcastSession> StartBroadcast(
|
||||
BroadcastRequest broadcast_request, BroadcastCallback callback) override;
|
||||
|
||||
// Gives tests access to mediums.
|
||||
Mediums& GetMediums() { return mediums_; }
|
||||
|
||||
private:
|
||||
Mediums mediums_; // NOLINT: further impl will use it.
|
||||
CredentialManagerImpl
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
// 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/service_controller_impl.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/future.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
#include "internal/proto/credential.pb.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace presence {
|
||||
namespace {
|
||||
|
||||
using FeatureFlags = location::nearby::FeatureFlags::Flags;
|
||||
using internal::IdentityType;
|
||||
using location::nearby::MediumEnvironment;
|
||||
|
||||
constexpr FeatureFlags kTestCases[] = {
|
||||
FeatureFlags{},
|
||||
};
|
||||
|
||||
constexpr absl::string_view kAccountName = "Test account";
|
||||
constexpr int8_t kTxPower = 30;
|
||||
|
||||
BroadcastRequest CreateBroadcastRequest(IdentityType identity) {
|
||||
PresenceBroadcast::BroadcastSection section = {
|
||||
.identity = identity,
|
||||
.extended_properties = {DataElement(
|
||||
DataElement(ActionBit::kActiveUnlockAction))},
|
||||
.account_name = std::string(kAccountName)};
|
||||
PresenceBroadcast presence_request = {.sections = {section}};
|
||||
BroadcastRequest request = {.tx_power = kTxPower,
|
||||
.variant = presence_request};
|
||||
return request;
|
||||
}
|
||||
|
||||
class MediumEnvironmentStarter {
|
||||
public:
|
||||
MediumEnvironmentStarter() { MediumEnvironment::Instance().Start(); }
|
||||
~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); }
|
||||
};
|
||||
|
||||
class ServiceControllerImplTest : public testing::TestWithParam<FeatureFlags> {
|
||||
protected:
|
||||
// The medium environment must be initialized (started) before the service
|
||||
// controller.
|
||||
MediumEnvironmentStarter env_;
|
||||
ServiceControllerImpl service_controller_;
|
||||
location::nearby::Future<Status> start_broadcast_status_;
|
||||
BroadcastCallback broadcast_callback_{
|
||||
.start_broadcast_cb = [this](Status status) {
|
||||
start_broadcast_status_.Set(status);
|
||||
}};
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ParametrisedServiceControllerImplTest,
|
||||
ServiceControllerImplTest,
|
||||
testing::ValuesIn(kTestCases));
|
||||
|
||||
TEST_P(ServiceControllerImplTest, StartBroadcastPublicIdentity) {
|
||||
std::unique_ptr<BroadcastSession> session =
|
||||
service_controller_.StartBroadcast(
|
||||
CreateBroadcastRequest(internal::IDENTITY_TYPE_PUBLIC),
|
||||
broadcast_callback_);
|
||||
|
||||
EXPECT_TRUE(session);
|
||||
EXPECT_TRUE(start_broadcast_status_.Get().ok());
|
||||
EXPECT_EQ(start_broadcast_status_.Get().GetResult(),
|
||||
Status{Status::Value::kSuccess});
|
||||
EXPECT_TRUE(MediumEnvironment::Instance()
|
||||
.GetBleV2MediumStatus(
|
||||
*service_controller_.GetMediums().GetBle().GetImpl())
|
||||
->is_advertising);
|
||||
}
|
||||
|
||||
TEST_P(ServiceControllerImplTest, StartAndStopBroadcast) {
|
||||
std::unique_ptr<BroadcastSession> session =
|
||||
service_controller_.StartBroadcast(
|
||||
CreateBroadcastRequest(internal::IDENTITY_TYPE_PUBLIC),
|
||||
broadcast_callback_);
|
||||
|
||||
ASSERT_TRUE(session);
|
||||
EXPECT_EQ(session->stop_broadcast_callback(),
|
||||
Status{Status::Value::kSuccess});
|
||||
MediumEnvironment::Instance().Sync();
|
||||
EXPECT_FALSE(MediumEnvironment::Instance()
|
||||
.GetBleV2MediumStatus(
|
||||
*service_controller_.GetMediums().GetBle().GetImpl())
|
||||
->is_advertising);
|
||||
}
|
||||
|
||||
TEST_P(ServiceControllerImplTest, StartBroadcastInvalidRequestFails) {
|
||||
std::unique_ptr<BroadcastSession> session =
|
||||
service_controller_.StartBroadcast(BroadcastRequest{},
|
||||
broadcast_callback_);
|
||||
|
||||
EXPECT_FALSE(session);
|
||||
EXPECT_TRUE(start_broadcast_status_.Get().ok());
|
||||
EXPECT_EQ(start_broadcast_status_.Get().GetResult(),
|
||||
Status{Status::Value::kError});
|
||||
}
|
||||
|
||||
TEST_P(ServiceControllerImplTest, StartBroadcastPrivateIdentityFails) {
|
||||
// TODO(b/256249404): Support private identity.
|
||||
std::unique_ptr<BroadcastSession> session =
|
||||
service_controller_.StartBroadcast(
|
||||
CreateBroadcastRequest(internal::IDENTITY_TYPE_PRIVATE),
|
||||
broadcast_callback_);
|
||||
|
||||
EXPECT_FALSE(session);
|
||||
EXPECT_TRUE(start_broadcast_status_.Get().ok());
|
||||
EXPECT_EQ(start_broadcast_status_.Get().GetResult(),
|
||||
Status{Status::Value::kError});
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace presence
|
||||
} // namespace nearby
|
||||
Reference in New Issue
Block a user