Create Fast Pair repository to manage server access API.

PiperOrigin-RevId: 506162700
This commit is contained in:
hai007
2023-01-31 17:32:21 -08:00
committed by Copybara-Service
parent 9fef440925
commit 72f0b1d323
11 changed files with 401 additions and 29 deletions
+52
View File
@@ -0,0 +1,52 @@
licenses(["notice"])
cc_library(
name = "server_access",
srcs = [
"fast_pair_metadata_downloader.cc",
"fast_pair_metadata_downloader_impl.cc",
"fast_pair_repository.cc",
"fast_pair_repository_impl.cc",
],
hdrs = [
"fast_pair_metadata_downloader.h",
"fast_pair_metadata_downloader_impl.h",
"fast_pair_repository.h",
"fast_pair_repository_impl.h",
],
visibility = [
"//fastpair:__subpackages__",
],
deps = [
"//fastpair/common",
"//fastpair/proto:fastpair_cc_proto",
"//fastpair/repository",
"//internal/network:nearby_http_client",
"//internal/network:types",
"//internal/platform:logging",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/strings",
],
)
cc_test(
name = "server_access_test",
srcs = [
"fast_pair_metadata_downloader_impl_test.cc",
"fast_pair_repository_impl_test.cc",
],
copts = [
"-Ithird_party",
],
deps = [
":server_access",
"//fastpair/common",
"//fastpair/proto:fastpair_cc_proto",
"//fastpair/repository",
"//fastpair/repository:fake_fast_pair_metadata_repository",
"//internal/platform/implementation/g3",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/strings",
"@com_google_googletest//:gtest_main",
],
)
@@ -14,17 +14,19 @@
#include "fastpair/server_access/fast_pair_metadata_downloader.h"
#include <optional>
#include <string>
#include <utility>
#include <optional>
#include "fastpair/proto/fastpair_rpcs.pb.h"
#include "fastpair/repository/device_metadata.h"
#include "internal/platform/logging.h"
#include "absl/strings/string_view.h"
namespace nearby {
namespace fastpair {
FastPairMetadataDownloader::FastPairMetadataDownloader(
std::optional<std::string> model_id, SuccessCallback success_callback,
absl::string_view model_id, SuccessCallback success_callback,
FailureCallback failure_callback)
: model_id_(model_id),
success_callback_(std::move(success_callback)),
@@ -38,11 +40,11 @@ void FastPairMetadataDownloader::Run() {
OnRun();
}
void FastPairMetadataDownloader::Succeed(proto::Device device) {
void FastPairMetadataDownloader::Succeed(DeviceMetadata& device_metadata) {
DCHECK(was_run_);
DCHECK(success_callback_);
std::move(success_callback_)(std::move(device));
std::move(success_callback_)(device_metadata);
}
void FastPairMetadataDownloader::Fail() {
@@ -19,18 +19,19 @@
#include <optional>
#include <string>
#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "fastpair/proto/fastpair_rpcs.proto.h"
#include "fastpair/repository/device_metadata.h"
namespace nearby {
namespace fastpair {
class FastPairMetadataDownloader {
public:
using SuccessCallback = std::function<void(proto::Device device)>;
using FailureCallback = std::function<void()>;
using SuccessCallback = absl::AnyInvocable<void(DeviceMetadata&)>;
using FailureCallback = absl::AnyInvocable<void()>;
FastPairMetadataDownloader(std::optional<std::string> model_id,
FastPairMetadataDownloader(absl::string_view model_id,
SuccessCallback success_callback,
FailureCallback failure_callback);
virtual ~FastPairMetadataDownloader();
@@ -39,13 +40,13 @@ class FastPairMetadataDownloader {
void Run();
protected:
std::optional<std::string> model_id() const { return model_id_; }
absl::string_view model_id() const { return model_id_; }
virtual void OnRun() = 0;
void Succeed(proto::Device device);
void Succeed(DeviceMetadata& device_metadata);
void Fail();
private:
const std::optional<std::string> model_id_;
absl::string_view model_id_;
SuccessCallback success_callback_;
FailureCallback failure_callback_;
bool was_run_ = false;
@@ -15,12 +15,15 @@
#include "fastpair/server_access/fast_pair_metadata_downloader_impl.h"
#include <algorithm>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include "absl/strings/numbers.h"
#include "absl/strings/string_view.h"
#include "fastpair/repository/device_metadata.h"
#include "fastpair/repository/fast_pair_metadata_repository.h"
#include "fastpair/server_access/fast_pair_metadata_downloader.h"
#include "internal/platform/logging.h"
@@ -33,7 +36,7 @@ FastPairMetadataDownloaderImpl::Factory*
std::unique_ptr<FastPairMetadataDownloader>
FastPairMetadataDownloaderImpl::Factory::Create(
std::optional<std::string> model_id,
absl::string_view model_id,
FastPairMetadataRepositoryFactory* repository_factory,
SuccessCallback success_callback, FailureCallback failure_callback) {
if (test_factory_) {
@@ -57,7 +60,7 @@ FastPairMetadataDownloaderImpl::Factory::~Factory() = default;
FastPairMetadataDownloaderImpl::~FastPairMetadataDownloaderImpl() = default;
FastPairMetadataDownloaderImpl::FastPairMetadataDownloaderImpl(
std::optional<std::string> model_id,
absl::string_view model_id,
FastPairMetadataRepositoryFactory* repository_factory,
SuccessCallback success_callback, FailureCallback failure_callback)
: FastPairMetadataDownloader(model_id, std::move(success_callback),
@@ -70,14 +73,16 @@ void FastPairMetadataDownloaderImpl::OnRun() {
}
void FastPairMetadataDownloaderImpl::CallAccessServer(
const std::optional<std::string>& model_id) {
absl::string_view model_id) {
NEARBY_LOGS(VERBOSE) << __func__
<< ": Making server accessing RPC call to fetch device "
"information with model ID: "
<< model_id.value_or("[null]");
<< model_id;
proto::GetObservedDeviceRequest request;
request.set_device_id(std::stoi(model_id.value_or("[null]"), nullptr, 16));
int64_t device_id;
CHECK(absl::SimpleHexAtoi(model_id, &device_id));
request.set_device_id(device_id);
request.set_mode(proto::GetObservedDeviceRequest::MODE_RELEASE);
repository_ = repository_factory_->CreateInstance();
@@ -107,11 +112,11 @@ void FastPairMetadataDownloaderImpl::OnAccessServerFailure(
}
void FastPairMetadataDownloaderImpl::OnAccessServerSuccess(
const proto::GetObservedDeviceResponse& response) {
device_ = response.device();
DeviceMetadata device_metadata(response);
NEARBY_LOGS(VERBOSE) << __func__ << ": Download " << device_.name()
<< " succeeded.";
Succeed(std::move(device_));
NEARBY_LOGS(VERBOSE) << __func__ << ": Download "
<< device_metadata.GetDetails().name() << " succeeded.";
Succeed(device_metadata);
}
} // namespace fastpair
@@ -35,7 +35,7 @@ class FastPairMetadataDownloaderImpl : public FastPairMetadataDownloader {
class Factory {
public:
static std::unique_ptr<FastPairMetadataDownloader> Create(
std::optional<std::string> model_id,
absl::string_view model_id,
FastPairMetadataRepositoryFactory* repository_factory,
SuccessCallback success_callback, FailureCallback failure_callback);
@@ -44,7 +44,7 @@ class FastPairMetadataDownloaderImpl : public FastPairMetadataDownloader {
protected:
virtual ~Factory();
virtual std::unique_ptr<FastPairMetadataDownloader> CreateInstance(
std::optional<std::string> model_id,
absl::string_view model_id,
FastPairMetadataRepositoryFactory* repository_factory,
SuccessCallback success_callback, FailureCallback failure_callback) = 0;
@@ -56,16 +56,15 @@ class FastPairMetadataDownloaderImpl : public FastPairMetadataDownloader {
private:
FastPairMetadataDownloaderImpl(
std::optional<std::string> model_id,
absl::string_view model_id,
FastPairMetadataRepositoryFactory* repository_factory,
SuccessCallback success_callback, FailureCallback failure_callback);
void OnRun() override;
void CallAccessServer(const std::optional<std::string>& model_id);
void CallAccessServer(absl::string_view model_id);
void OnAccessServerSuccess(const proto::GetObservedDeviceResponse& response);
void OnAccessServerFailure(FastPairHttpError error);
proto::Device device_;
std::unique_ptr<FastPairMetadataRepository> repository_;
FastPairMetadataRepositoryFactory* repository_factory_ = nullptr;
};
@@ -24,8 +24,9 @@
#include "gtest/gtest.h"
#include "fastpair/common/fast_pair_http_result.h"
#include "fastpair/proto/fastpair_rpcs.proto.h"
#include "fastpair/server_access/fast_pair_metadata_downloader.h"
#include "fastpair/repository/device_metadata.h"
#include "fastpair/repository/fake_fast_pair_metadata_repository.h"
#include "fastpair/server_access/fast_pair_metadata_downloader.h"
namespace nearby {
namespace fastpair {
@@ -72,7 +73,8 @@ class FastPairMetadataDownloaderImplTest : public ::testing::Test {
}
// The callbacks passed into NearbyShareContactDownloader ctor.
void OnSuccess(proto::Device device) {
void OnSuccess(DeviceMetadata& device_metadata) {
const proto::Device device = device_metadata.GetDetails();
result_ = Result();
result_->success = true;
result_->device = std::move(device);
@@ -91,7 +93,8 @@ class FastPairMetadataDownloaderImplTest : public ::testing::Test {
TEST_F(FastPairMetadataDownloaderImplTest, GetObservedDeviceDownloadSuccess) {
downloader_ = FastPairMetadataDownloaderImpl::Factory::Create(
kModelId, &fake_repository_factory_,
[&](proto::Device device) { OnSuccess(device); }, [&]() { OnFailure(); });
[&](DeviceMetadata& device_metadata) { OnSuccess(device_metadata); },
[&]() { OnFailure(); });
downloader_->Run();
proto::GetObservedDeviceResponse response;
response.mutable_device()->set_id(kDeviceId);
@@ -107,7 +110,8 @@ TEST_F(FastPairMetadataDownloaderImplTest, GetObservedDeviceDownloadSuccess) {
TEST_F(FastPairMetadataDownloaderImplTest, GetObservedDeviceDownloadFailure) {
downloader_ = FastPairMetadataDownloaderImpl::Factory::Create(
kModelId, &fake_repository_factory_,
[&](proto::Device device) { OnSuccess(device); }, [&]() { OnFailure(); });
[&](DeviceMetadata& device_metadata) { OnSuccess(device_metadata); },
[&]() { OnFailure(); });
downloader_->Run();
proto::GetObservedDeviceResponse response;
response.mutable_device()->set_id(kDeviceId);
@@ -0,0 +1,42 @@
// Copyright 2023 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 "fastpair/server_access/fast_pair_repository.h"
#include <utility>
#include "internal/platform/logging.h"
namespace nearby {
namespace fastpair {
namespace {
FastPairRepository* g_instance = nullptr;
}
FastPairRepository* FastPairRepository::Get() {
CHECK(g_instance);
return g_instance;
}
void FastPairRepository::SetInstance(FastPairRepository* instance) {
DCHECK(!g_instance || !instance);
g_instance = instance;
}
FastPairRepository::FastPairRepository() { SetInstance(this); }
FastPairRepository::~FastPairRepository() { SetInstance(nullptr); }
} // namespace fastpair
} // namespace nearby
@@ -0,0 +1,43 @@
// Copyright 2023 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_FASTPAIR_SERVER_ACCESS_FAST_PAIR_REPOSITORY_H_
#define THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_REPOSITORY_H_
#include <functional>
#include <optional>
#include <string>
#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "fastpair/repository/device_metadata.h"
namespace nearby {
namespace fastpair {
using DeviceMetadataCallback = absl::AnyInvocable<void(DeviceMetadata&)>;
class FastPairRepository {
public:
static FastPairRepository* Get();
FastPairRepository();
virtual ~FastPairRepository();
virtual void GetDeviceMetadata(absl::string_view hex_model_id,
DeviceMetadataCallback callback) = 0;
protected:
static void SetInstance(FastPairRepository* instance);
};
} // namespace fastpair
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_REPOSITORY_H_
@@ -0,0 +1,64 @@
// Copyright 2023 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 "fastpair/server_access/fast_pair_repository_impl.h"
#include <algorithm>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include "fastpair/repository/fast_pair_metadata_repository.h"
#include "fastpair/repository/fast_pair_metadata_repository_impl.h"
#include "fastpair/server_access/fast_pair_metadata_downloader_impl.h"
#include "internal/network/http_client_factory.h"
#include "internal/network/http_client_factory_impl.h"
#include "internal/platform/logging.h"
#include "absl/strings/string_view.h"
namespace nearby {
namespace fastpair {
FastPairRepositoryImpl::FastPairRepositoryImpl()
: http_factory_(std::make_unique<nearby::network::HttpClientFactoryImpl>()),
repository_factory_(
std::make_unique<FastPairMetadataRepositoryFactoryImpl>(
http_factory_.get())) {}
FastPairRepositoryImpl::FastPairRepositoryImpl(
std::unique_ptr<FastPairMetadataRepositoryFactory> repository)
: repository_factory_(std::move(repository)) {}
void FastPairRepositoryImpl::GetDeviceMetadata(
absl::string_view hex_model_id,
DeviceMetadataCallback callback) {
callback_ = std::move(callback);
downloader_ = FastPairMetadataDownloaderImpl::Factory::Create(
hex_model_id, repository_factory_.get(),
[&](DeviceMetadata& device_metadata) {
NEARBY_LOGS(INFO) << __func__ << ": Fast Pair download of "
<< device_metadata.GetDetails().name()
<< " succeeded.";
DCHECK(callback_);
std::move(callback_)(device_metadata);
},
[&]() {
NEARBY_LOGS(INFO) << __func__
<< ": Fast Pair Metadata download failed.";
});
downloader_->Run();
}
} // namespace fastpair
} // namespace nearby
@@ -0,0 +1,52 @@
// Copyright 2023 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_FASTPAIR_SERVER_ACCESS_FAST_PAIR_REPOSITORY_IMPL_H_
#define THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_REPOSITORY_IMPL_H_
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include "fastpair/repository/fast_pair_metadata_repository.h"
#include "fastpair/server_access/fast_pair_metadata_downloader.h"
#include "fastpair/server_access/fast_pair_repository.h"
#include "internal/network/http_client_factory.h"
#include "absl/strings/string_view.h"
namespace nearby {
namespace fastpair {
class FastPairRepositoryImpl : public FastPairRepository {
public:
FastPairRepositoryImpl();
explicit FastPairRepositoryImpl(
std::unique_ptr<FastPairMetadataRepositoryFactory> repository);
FastPairRepositoryImpl(const FastPairRepositoryImpl&) = delete;
FastPairRepositoryImpl& operator=(const FastPairRepositoryImpl&) = delete;
~FastPairRepositoryImpl() override = default;
void GetDeviceMetadata(absl::string_view hex_model_id,
DeviceMetadataCallback callback) override;
private:
std::unique_ptr<FastPairMetadataDownloader> downloader_;
std::unique_ptr<network::HttpClientFactory> http_factory_;
std::unique_ptr<FastPairMetadataRepositoryFactory> repository_factory_;
DeviceMetadataCallback callback_;
};
} // namespace fastpair
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_FASTPAIR_SERVER_ACCESS_FAST_PAIR_REPOSITORY_IMPL_H_
@@ -0,0 +1,108 @@
// Copyright 2023 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 "fastpair/server_access/fast_pair_repository_impl.h"
#include <cstddef>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "fastpair/proto/fastpair_rpcs.proto.h"
#include "fastpair/repository/device_metadata.h"
#include "fastpair/repository/fake_fast_pair_metadata_repository.h"
#include "fastpair/server_access/fast_pair_metadata_downloader.h"
#include "fastpair/server_access/fast_pair_metadata_downloader_impl.h"
namespace nearby {
namespace fastpair {
constexpr absl::Duration kWaitTimeout = absl::Milliseconds(500);
const int64_t kDeviceId = 10148625;
const char kModelId[] = "9adb11";
const char kDeviceName[] = "Pixel Buds Pro";
class FakeFastPairMetadataRepositoryFactory;
namespace {
class FastPairRepositoryImplTest : public ::testing::Test {
protected:
struct Result {
bool success;
std::optional<proto::Device> device;
};
FastPairRepositoryImplTest() {}
~FastPairRepositoryImplTest() override = default;
void GetObservedDataRequestSuccess(
const proto::GetObservedDeviceResponse& response) {
FakeFastPairMetadataRepository* repository =
fake_repository_factory_->fake_repository();
std::move(repository->get_observed_device_request()->callback)(response);
}
void OnSuccess(DeviceMetadata& device_metadata) {
result_ = Result();
result_->success = true;
result_->device = device_metadata.GetDetails();
}
std::optional<Result> result_;
FakeFastPairMetadataRepositoryFactory*
fake_repository_factory_;
std::unique_ptr<FastPairRepositoryImpl> repository_;
};
TEST_F(FastPairRepositoryImplTest, MetadataDownloadSuccess) {
absl::Notification notification;
auto fake_repository_factory =
std::make_unique<FakeFastPairMetadataRepositoryFactory>();
fake_repository_factory_ = fake_repository_factory.get();
repository_ = std::make_unique<FastPairRepositoryImpl>(
std::move(fake_repository_factory));
repository_->Get()->GetDeviceMetadata(kModelId,
[&](DeviceMetadata& device_metadata) {
OnSuccess(device_metadata);
notification.Notify();
});
ASSERT_TRUE(fake_repository_factory_->fake_repository() != nullptr);
FakeFastPairMetadataRepository* repository =
fake_repository_factory_->fake_repository();
const proto::GetObservedDeviceRequest& request =
repository->get_observed_device_request()->request;
EXPECT_EQ(request.device_id(), kDeviceId);
proto::GetObservedDeviceResponse response;
response.mutable_device()->set_id(kDeviceId);
response.mutable_device()->set_name(kDeviceName);
GetObservedDataRequestSuccess(response);
ASSERT_TRUE(result_);
EXPECT_TRUE(result_->success);
ASSERT_TRUE(result_->device);
EXPECT_EQ(result_->device->name(), kDeviceName);
EXPECT_EQ(result_->device->id(), kDeviceId);
EXPECT_TRUE(notification.WaitForNotificationWithTimeout(kWaitTimeout));
}
} // namespace
} // namespace fastpair
} // namespace nearby