mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Create an interface to make API requests which pass Client ID, Released mode and Model ID to Nearby Devices.
PiperOrigin-RevId: 500053224
This commit is contained in:
@@ -17,7 +17,7 @@ syntax = "proto3";
|
||||
// Proto defined in this file needs be consistent with proto defined in
|
||||
// google3/google/internal/location/nearby/device/v1/rpcs.proto.
|
||||
|
||||
package location.nearby.fastpair.proto;
|
||||
package nearby.fastpair.proto;
|
||||
|
||||
option optimize_for = LITE_RUNTIME;
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
licenses(["notice"])
|
||||
|
||||
cc_library(
|
||||
name = "repository",
|
||||
srcs = [
|
||||
"fast_pair_metadata_fetcher_impl.cc",
|
||||
"fast_pair_metadata_repository_impl.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"fast_pair_metadata_fetcher.h",
|
||||
"fast_pair_metadata_fetcher_impl.h",
|
||||
"fast_pair_metadata_repository.h",
|
||||
"fast_pair_metadata_repository_impl.h",
|
||||
],
|
||||
copts = [
|
||||
"-Ithird_party",
|
||||
],
|
||||
visibility = ["//fastpair:__subpackages__"],
|
||||
deps = [
|
||||
"//fastpair/common",
|
||||
"//fastpair/internal/api:platform",
|
||||
"//fastpair/proto:fastpair_cc_proto",
|
||||
"//internal/network:types",
|
||||
"//internal/platform:logging",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "repository_test",
|
||||
srcs = [
|
||||
"fast_pair_metadata_fetcher_impl_test.cc",
|
||||
"fast_pair_metadata_repository_impl_test.cc",
|
||||
],
|
||||
copts = [
|
||||
"-Ithird_party",
|
||||
],
|
||||
deps = [
|
||||
":repository",
|
||||
"//fastpair/common",
|
||||
"//fastpair/internal/test:nearby_fastpair_test",
|
||||
"//fastpair/proto:fastpair_cc_proto",
|
||||
"//internal/network:types",
|
||||
"//internal/platform/implementation/g3",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/status:statusor",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
@@ -31,8 +31,7 @@ namespace fastpair {
|
||||
|
||||
class FastPairMetadataFetcher {
|
||||
public:
|
||||
using ResultCallback =
|
||||
std::function<void(absl::string_view serialized_response)>;
|
||||
using ResultCallback = std::function<void(absl::string_view result_response)>;
|
||||
using ErrorCallback = std::function<void(FastPairHttpError error)>;
|
||||
using QueryParameters = std::vector<std::pair<std::string, std::string>>;
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
// 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_FASTPAIR_REPOSITORY_FAST_PAIR_METADATA_REPOSITORY_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAST_PAIR_METADATA_REPOSITORY_H_
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "fastpair/common/fast_pair_http_result.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
namespace proto {
|
||||
|
||||
class GetObservedDeviceRequest;
|
||||
class GetObservedDeviceResponse;
|
||||
|
||||
} // namespace proto
|
||||
|
||||
class FastPairMetadataRepository {
|
||||
public:
|
||||
using ErrorCallback = std::function<void(FastPairHttpError)>;
|
||||
using ObservedDeviceCallback =
|
||||
std::function<void(const proto::GetObservedDeviceResponse&)>;
|
||||
FastPairMetadataRepository() = default;
|
||||
virtual ~FastPairMetadataRepository() = default;
|
||||
|
||||
virtual void GetObservedDevice(const proto::GetObservedDeviceRequest& request,
|
||||
ObservedDeviceCallback callback,
|
||||
ErrorCallback error_callback) = 0;
|
||||
};
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAST_PAIR_METADATA_REPOSITORY_H_
|
||||
@@ -0,0 +1,120 @@
|
||||
// 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 "fastpair/repository/fast_pair_metadata_repository_impl.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "fastpair/common/fast_pair_http_result.h"
|
||||
#include "fastpair/proto/fastpair_rpcs.proto.h"
|
||||
#include "fastpair/repository/fast_pair_metadata_fetcher.h"
|
||||
#include "fastpair/repository/fast_pair_metadata_repository.h"
|
||||
#include "internal/network/url.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
const char kDefaultNearbyDeviceV1HTTPHost[] =
|
||||
"https://nearbydevices-pa.googleapis.com";
|
||||
|
||||
const char kNearbyShareV1Path[] = "v1";
|
||||
const char kListDevicePath[] = "device";
|
||||
const char kClientId[] = "AIzaSyBv7ZrOlX5oIJLVQrZh-WkZFKm5L6FlStQ";
|
||||
const char kMode[] = "mode";
|
||||
const char* GetObservedDeviceMode[3] = {"MODE_UNKNOWN", "MODE_RELEASE",
|
||||
"MODE_DEBUG"};
|
||||
FastPairMetadataRepositoryImpl::FastPairMetadataRepositoryImpl(
|
||||
std::unique_ptr<FastPairMetadataFetcher> fetcher,
|
||||
std::unique_ptr<network::HttpClient> http_client)
|
||||
: fetcher_(std::move(fetcher)), http_client_(std::move(http_client)) {}
|
||||
|
||||
FastPairMetadataRepositoryImpl::~FastPairMetadataRepositoryImpl() = default;
|
||||
|
||||
// Create full fastpair v1 URL
|
||||
nearby::network::Url CreateV1DeviceRequestUrlPath(
|
||||
const proto::GetObservedDeviceRequest& request) {
|
||||
std::string path = absl::StrFormat(
|
||||
"%s/%s/%s/%s", kDefaultNearbyDeviceV1HTTPHost, kNearbyShareV1Path,
|
||||
kListDevicePath, std::to_string(request.device_id()));
|
||||
return nearby::network::Url::Create(path).value();
|
||||
}
|
||||
|
||||
FastPairMetadataFetcher::QueryParameters
|
||||
GetObservedDeviceRequestToQueryParameters(
|
||||
const proto::GetObservedDeviceRequest& request) {
|
||||
FastPairMetadataFetcher::QueryParameters params;
|
||||
params.push_back({"key", kClientId});
|
||||
params.push_back({kMode, GetObservedDeviceMode[request.mode()]});
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
void FastPairMetadataRepositoryImpl::GetObservedDevice(
|
||||
const proto::GetObservedDeviceRequest& request,
|
||||
ObservedDeviceCallback callback, ErrorCallback error_callback) {
|
||||
ObservedDeviceCallback new_callback =
|
||||
[=](const proto::GetObservedDeviceResponse& response) {
|
||||
callback(response);
|
||||
};
|
||||
ErrorCallback new_error_callback = [=](FastPairHttpError error) {
|
||||
error_callback(error);
|
||||
};
|
||||
|
||||
MakeUnauthFetcher(CreateV1DeviceRequestUrlPath(request),
|
||||
GetObservedDeviceRequestToQueryParameters(request),
|
||||
new_callback, new_error_callback);
|
||||
}
|
||||
|
||||
void FastPairMetadataRepositoryImpl::MakeUnauthFetcher(
|
||||
const nearby::network::Url& request_url,
|
||||
const std::optional<FastPairMetadataFetcher::QueryParameters>&
|
||||
request_as_query_parameters,
|
||||
ObservedDeviceCallback response_callback, ErrorCallback error_callback) {
|
||||
has_call_started_ = true;
|
||||
request_url_ = request_url;
|
||||
error_callback_ = std::move(error_callback);
|
||||
fetcher_->StartGetUnauthRequest(
|
||||
request_url_, *request_as_query_parameters, http_client_.get(),
|
||||
[&, response_callback =
|
||||
std::move(response_callback)](absl::string_view result_response) {
|
||||
OnFetcherSuccess(response_callback, result_response);
|
||||
},
|
||||
[&](FastPairHttpError error) { OnFetcherFailed(error); });
|
||||
}
|
||||
|
||||
void FastPairMetadataRepositoryImpl::OnFetcherSuccess(
|
||||
ObservedDeviceCallback callback, absl::string_view result_response) {
|
||||
proto::GetObservedDeviceResponse response;
|
||||
if (!response.ParseFromString(result_response)) {
|
||||
OnFetcherFailed(FastPairHttpError::kHttpErrorOtherFailure);
|
||||
return;
|
||||
}
|
||||
callback(response);
|
||||
}
|
||||
|
||||
void FastPairMetadataRepositoryImpl::OnFetcherFailed(FastPairHttpError error) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< "Fast pair server accessing RPC call failed with error. " << error;
|
||||
error_callback_(error);
|
||||
}
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,70 @@
|
||||
// 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_FASTPAIR_REPOSITORY_FAST_PAIR_METADATA_REPOSITORY_IMPL_H_
|
||||
#define THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAST_PAIR_METADATA_REPOSITORY_IMPL_H_
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "fastpair/repository/fast_pair_metadata_fetcher.h"
|
||||
#include "fastpair/repository/fast_pair_metadata_repository.h"
|
||||
#include "internal/network/http_client.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
class FastPairMetadataRepositoryImpl : public FastPairMetadataRepository {
|
||||
public:
|
||||
FastPairMetadataRepositoryImpl(
|
||||
std::unique_ptr<FastPairMetadataFetcher> fetcher,
|
||||
std::unique_ptr<network::HttpClient> http_client);
|
||||
~FastPairMetadataRepositoryImpl() override;
|
||||
|
||||
FastPairMetadataRepositoryImpl(FastPairMetadataRepositoryImpl&) = delete;
|
||||
FastPairMetadataRepositoryImpl& operator=(FastPairMetadataRepositoryImpl&) =
|
||||
delete;
|
||||
void GetObservedDevice(const proto::GetObservedDeviceRequest& request,
|
||||
ObservedDeviceCallback response_callback,
|
||||
ErrorCallback error_callback) override;
|
||||
|
||||
private:
|
||||
void MakeUnauthFetcher(
|
||||
const nearby::network::Url& request_url,
|
||||
const std::optional<FastPairMetadataFetcher::QueryParameters>&
|
||||
request_as_query_parameters,
|
||||
ObservedDeviceCallback response_callback, ErrorCallback error_callback);
|
||||
|
||||
// Called when the fetcher success fails at any step.
|
||||
void OnFetcherSuccess(ObservedDeviceCallback callback,
|
||||
absl::string_view result_response);
|
||||
|
||||
// Called when the fetcher fails at any step.
|
||||
void OnFetcherFailed(FastPairHttpError error);
|
||||
|
||||
bool has_call_started_;
|
||||
std::unique_ptr<FastPairMetadataFetcher> fetcher_;
|
||||
std::unique_ptr<nearby::network::HttpClient> http_client_;
|
||||
nearby::network::Url request_url_;
|
||||
ErrorCallback error_callback_;
|
||||
};
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_FASTPAIR_REPOSITORY_FAST_PAIR_METADATA_REPOSITORY_IMPL_H_
|
||||
@@ -0,0 +1,167 @@
|
||||
// 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 "fastpair/repository/fast_pair_metadata_repository_impl.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "fastpair/common/fast_pair_http_result.h"
|
||||
#include "fastpair/internal/test/fast_pair_fake_http_client.h"
|
||||
#include "fastpair/proto/fastpair_rpcs.proto.h"
|
||||
#include "fastpair/repository/fast_pair_metadata_fetcher.h"
|
||||
#include "fastpair/repository/fast_pair_metadata_repository.h"
|
||||
#include "internal/network/url.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace fastpair {
|
||||
|
||||
using ::nearby::network::HttpClient;
|
||||
using ::nearby::network::Url;
|
||||
|
||||
const char kImageUrl[] = "https://example.com/image.jpg";
|
||||
const char kListDevicePath[] = "device/";
|
||||
const char kClientId[] = "AIzaSyBv7ZrOlX5oIJLVQrZh-WkZFKm5L6FlStQ";
|
||||
const char kTestGoogleApisUrl[] = "https://nearbydevices-pa.googleapis.com";
|
||||
constexpr int64_t kDeviceId = 10148625;
|
||||
const char kDeviceName[] = "devicename";
|
||||
|
||||
class FakeFastPairMetadataFetcher : public FastPairMetadataFetcher {
|
||||
public:
|
||||
FakeFastPairMetadataFetcher() = default;
|
||||
~FakeFastPairMetadataFetcher() override = default;
|
||||
FakeFastPairMetadataFetcher(const FakeFastPairMetadataFetcher&) = delete;
|
||||
FakeFastPairMetadataFetcher& operator=(const FakeFastPairMetadataFetcher&) =
|
||||
delete;
|
||||
|
||||
void StartGetUnauthRequest(const Url& request_url,
|
||||
const QueryParameters& request_as_query_parameters,
|
||||
HttpClient* http_client,
|
||||
ResultCallback result_callback,
|
||||
ErrorCallback error_callback) override {
|
||||
request_url_ = request_url;
|
||||
request_as_query_parameters_ = request_as_query_parameters;
|
||||
http_client_ = http_client;
|
||||
result_callback_ = result_callback;
|
||||
error_callback_ = error_callback;
|
||||
}
|
||||
Url request_url_;
|
||||
QueryParameters request_as_query_parameters_;
|
||||
HttpClient* http_client_;
|
||||
ResultCallback result_callback_;
|
||||
ErrorCallback error_callback_;
|
||||
};
|
||||
std::vector<std::string> ExpectQueryStringValues(
|
||||
const FastPairMetadataFetcher::QueryParameters& query_parameters,
|
||||
absl::string_view key) {
|
||||
std::vector<std::string> values;
|
||||
for (const auto& pair : query_parameters) {
|
||||
const auto& query_key = pair.first;
|
||||
const auto& query_value = pair.second;
|
||||
if (query_key == key) {
|
||||
values.push_back(query_value);
|
||||
}
|
||||
}
|
||||
EXPECT_GT(values.size(), 0);
|
||||
return values;
|
||||
}
|
||||
class FastPairMetadataRepositoryImplTest : public ::testing::Test {
|
||||
protected:
|
||||
FastPairMetadataRepositoryImplTest() = default;
|
||||
|
||||
void SetUp() override {
|
||||
http_client_ = std::make_unique<network::FastPairFakeHttpClient>();
|
||||
SetNearbySharedHttpHost(kTestGoogleApisUrl);
|
||||
|
||||
auto fetcher = std::make_unique<FakeFastPairMetadataFetcher>();
|
||||
fetcher_ = fetcher.get();
|
||||
|
||||
repository_ = std::make_unique<FastPairMetadataRepositoryImpl>(
|
||||
std::move(fetcher), std::move(http_client_));
|
||||
}
|
||||
|
||||
void SetNearbySharedHttpHost(const std::string& host) {
|
||||
int global_host_size = 0;
|
||||
char global_host[256];
|
||||
if (host.size() > 256) {
|
||||
return;
|
||||
}
|
||||
global_host_size = host.size();
|
||||
memcpy(global_host, host.c_str(), global_host_size);
|
||||
}
|
||||
|
||||
const FastPairMetadataFetcher::QueryParameters&
|
||||
request_as_query_parameters() {
|
||||
return fetcher_->request_as_query_parameters_;
|
||||
}
|
||||
|
||||
const Url& request_url() { return fetcher_->request_url_; }
|
||||
|
||||
Url GetUrl(absl::string_view path) {
|
||||
return Url::Create(
|
||||
absl::StrCat(kTestGoogleApisUrl, "/v1/", kListDevicePath, path))
|
||||
.value();
|
||||
}
|
||||
|
||||
FakeFastPairMetadataFetcher* fetcher_;
|
||||
std::unique_ptr<HttpClient> http_client_;
|
||||
std::unique_ptr<FastPairMetadataRepository> repository_;
|
||||
|
||||
Url request_url_;
|
||||
FastPairMetadataFetcher::QueryParameters request_as_query_parameters_;
|
||||
FastPairMetadataFetcher::ResultCallback result_callback_;
|
||||
FastPairMetadataFetcher::ErrorCallback error_callback_;
|
||||
};
|
||||
|
||||
TEST_F(FastPairMetadataRepositoryImplTest, GetObservedDeviceSuccess) {
|
||||
proto::GetObservedDeviceRequest request;
|
||||
proto::GetObservedDeviceResponse result;
|
||||
|
||||
request.set_device_id(kDeviceId);
|
||||
request.set_mode(proto::GetObservedDeviceRequest::MODE_RELEASE);
|
||||
|
||||
repository_->GetObservedDevice(
|
||||
request,
|
||||
[&result](const proto::GetObservedDeviceResponse& response) {
|
||||
result = response;
|
||||
},
|
||||
[&](FastPairHttpError error) {});
|
||||
|
||||
EXPECT_EQ(request_url(), GetUrl(std::to_string(request.device_id())));
|
||||
EXPECT_EQ(std::vector<std::string>{"MODE_RELEASE"},
|
||||
ExpectQueryStringValues(request_as_query_parameters(), "mode"));
|
||||
EXPECT_EQ(std::vector<std::string>{kClientId},
|
||||
ExpectQueryStringValues(request_as_query_parameters(), "key"));
|
||||
|
||||
proto::GetObservedDeviceResponse test_response;
|
||||
test_response.mutable_device()->set_id(kDeviceId);
|
||||
test_response.mutable_device()->set_name(kDeviceName);
|
||||
test_response.mutable_device()->set_image_url(kImageUrl);
|
||||
|
||||
EXPECT_EQ(test_response.device().id(), kDeviceId);
|
||||
EXPECT_EQ(test_response.device().name(), kDeviceName);
|
||||
EXPECT_EQ(test_response.device().image_url(), kImageUrl);
|
||||
}
|
||||
|
||||
} // namespace fastpair
|
||||
} // namespace nearby
|
||||
Reference in New Issue
Block a user