From 0803db861f8db6873b6db96a999ed2254b13836d Mon Sep 17 00:00:00 2001 From: Suet-Fei Li Date: Fri, 22 Nov 2024 17:03:46 -0800 Subject: [PATCH] migrate QueryShareCredentials. PiperOrigin-RevId: 699329477 --- sharing/certificates/BUILD | 5 + .../nearby_share_certificate_manager_impl.cc | 81 +++++++++++++++- .../nearby_share_certificate_manager_impl.h | 10 ++ ...rby_share_certificate_manager_impl_test.cc | 94 +++++++++++++++++++ .../internal/api/fake_nearby_share_client.cc | 9 +- .../internal/api/fake_nearby_share_client.h | 20 ++-- 6 files changed, 206 insertions(+), 13 deletions(-) diff --git a/sharing/certificates/BUILD b/sharing/certificates/BUILD index 40f09113..33443108 100644 --- a/sharing/certificates/BUILD +++ b/sharing/certificates/BUILD @@ -44,12 +44,15 @@ cc_library( "//internal/flags:nearby_flags", "//internal/platform:types", "//internal/platform/implementation:account_manager", + "//proto/identity/v1:resources_cc_proto", + "//proto/identity/v1:rpcs_cc_proto", "//sharing/common", "//sharing/common:enum", "//sharing/contacts", "//sharing/flags/generated:generated_flags", "//sharing/internal/api:platform", "//sharing/internal/base", + "//sharing/internal/impl/common:nearby_identity_grpc_client", "//sharing/internal/public:logging", "//sharing/internal/public:types", "//sharing/local_device_data", @@ -119,6 +122,8 @@ cc_test( "//internal/platform/implementation:account_manager", "//internal/platform/implementation/g3", # fixdeps: keep "//internal/test", + "//proto/identity/v1:resources_cc_proto", + "//proto/identity/v1:rpcs_cc_proto", "//sharing/common", "//sharing/common:enum", "//sharing/contacts:test_support", diff --git a/sharing/certificates/nearby_share_certificate_manager_impl.cc b/sharing/certificates/nearby_share_certificate_manager_impl.cc index 4736cfe4..96006261 100644 --- a/sharing/certificates/nearby_share_certificate_manager_impl.cc +++ b/sharing/certificates/nearby_share_certificate_manager_impl.cc @@ -32,13 +32,17 @@ #include "absl/functional/bind_front.h" #include "absl/memory/memory.h" #include "absl/status/statusor.h" +#include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" +#include "absl/strings/strip.h" #include "absl/synchronization/notification.h" #include "absl/time/time.h" #include "absl/types/span.h" #include "internal/flags/nearby_flags.h" #include "internal/platform/implementation/account_manager.h" +#include "proto/identity/v1/resources.pb.h" +#include "proto/identity/v1/rpcs.pb.h" #include "sharing/certificates/common.h" #include "sharing/certificates/constants.h" #include "sharing/certificates/nearby_share_certificate_manager.h" @@ -71,6 +75,8 @@ namespace nearby { namespace sharing { namespace { +using ::google::nearby::identity::v1::QuerySharedCredentialsRequest; +using ::google::nearby::identity::v1::QuerySharedCredentialsResponse; using ::nearby::sharing::api::PreferenceManager; using ::nearby::sharing::api::PublicCertificateDatabase; using ::nearby::sharing::api::SharingPlatform; @@ -227,6 +233,7 @@ NearbyShareCertificateManagerImpl::NearbyShareCertificateManagerImpl( local_device_data_manager_(local_device_data_manager), contact_manager_(contact_manager), nearby_client_(client_factory->CreateInstance()), + nearby_identity_client_(client_factory->CreateIdentityInstance()), certificate_storage_(NearbyShareCertificateStorageImpl::Factory::Create( preference_manager, std::move(public_certificate_database))), private_certificate_expiration_scheduler_( @@ -295,9 +302,8 @@ void NearbyShareCertificateManagerImpl::CertificateDownloadContext:: request.set_page_token(*next_page_token_); } nearby_share_client_->ListPublicCertificates( - request, [this]( - const absl::StatusOr& - response) mutable { + request, [this](const absl::StatusOr& + response) mutable { if (!response.ok()) { NL_LOG(WARNING) << __func__ << ": Failed to download certificates: " << response.status(); @@ -321,6 +327,65 @@ void NearbyShareCertificateManagerImpl::CertificateDownloadContext:: }); } +void NearbyShareCertificateManagerImpl::CertificateDownloadContext:: + QuerySharedCredentialsFetchNextPage() { + page_number_++; + LOG(INFO) << __func__ + << ": [Call Identity API] Downloading page=" << page_number_; + QuerySharedCredentialsRequest request; + request.set_name( + absl::StrCat("devices/", absl::StripPrefix(device_id_, kDeviceIdPrefix))); + if (next_page_token_.has_value()) { + request.set_page_token(*next_page_token_); + } + nearby_identity_client_->QuerySharedCredentials( + request, [this](const absl::StatusOr& + response) mutable { + if (!response.ok()) { + LOG(WARNING) + << __func__ + << ": [Call Identity API] Failed to download certificates: " + << response.status(); + std::move(download_failure_callback_)(); + return; + } + for (const auto& credential : response->shared_credentials()) { + if (credential.data_type() != + google::nearby::identity::v1::SharedCredential:: + DATA_TYPE_PUBLIC_CERTIFICATE) { + LOG(WARNING) << __func__ + << ": [Call Identity API] skipping non " + "DATA_TYPE_PUBLIC_CERTIFICATE, credential.id: " + << credential.id(); + continue; + } + PublicCertificate certificate; + if (!certificate.ParseFromString(credential.data())) { + LOG(ERROR) << __func__ + << ": [Call Identity API] Failed parsing to " + "PublicCertificate, credential.id: " + << credential.id() << " data: " + << absl::BytesToHexString(credential.data()); + continue; + } + VLOG(1) << __func__ + << ": [Call Identity API] Successfully parsed credential: " + << credential.id(); + certificates_.push_back(certificate); + } + + if (response->next_page_token().empty()) { + LOG(INFO) << __func__ + << ": [Call Identity API] Completed to download " + << certificates_.size() << " certificates"; + std::move(download_success_callback_)(certificates_); + return; + } + next_page_token_ = response->next_page_token(); + QuerySharedCredentialsFetchNextPage(); + }); +} + void NearbyShareCertificateManagerImpl::OnPublicCertificatesDownloadSuccess( const std::vector& certificates) { // Save certificates to store. @@ -373,7 +438,7 @@ void NearbyShareCertificateManagerImpl::DownloadPublicCertificates() { // Currently certificates download is synchronous. It completes after // FetchNextPage() returns. auto context = std::make_unique( - nearby_client_.get(), + nearby_client_.get(), nearby_identity_client_.get(), kDeviceIdPrefix + local_device_data_manager_->GetId(), absl::bind_front(&NearbyShareCertificateManagerImpl:: OnPublicCertificatesDownloadFailure, @@ -381,7 +446,13 @@ void NearbyShareCertificateManagerImpl::DownloadPublicCertificates() { absl::bind_front(&NearbyShareCertificateManagerImpl:: OnPublicCertificatesDownloadSuccess, this)); - context->FetchNextPage(); + if (NearbyFlags::GetInstance().GetBoolFlag( + config_package_nearby::nearby_sharing_feature:: + kCallNearbyIdentityApi)) { + context->QuerySharedCredentialsFetchNextPage(); + } else { + context->FetchNextPage(); + } }); } diff --git a/sharing/certificates/nearby_share_certificate_manager_impl.h b/sharing/certificates/nearby_share_certificate_manager_impl.h index f8580359..e7f8468a 100644 --- a/sharing/certificates/nearby_share_certificate_manager_impl.h +++ b/sharing/certificates/nearby_share_certificate_manager_impl.h @@ -38,6 +38,7 @@ #include "sharing/internal/api/public_certificate_database.h" #include "sharing/internal/api/sharing_platform.h" #include "sharing/internal/api/sharing_rpc_client.h" +#include "sharing/internal/impl/common/nearby_identity_grpc_client.h" #include "sharing/internal/public/context.h" #include "sharing/local_device_data/nearby_share_local_device_data_manager.h" #include "sharing/proto/enums.pb.h" @@ -98,6 +99,7 @@ class NearbyShareCertificateManagerImpl public: CertificateDownloadContext( nearby::sharing::api::SharingRpcClient* nearby_share_client, + nearby::sharing::api::IdentityRpcClient* nearby_identity_client, std::string device_id, absl::AnyInvocable download_failure_callback, absl::AnyInvocable< @@ -105,6 +107,7 @@ class NearbyShareCertificateManagerImpl certificates) &&> download_success_callback) : nearby_share_client_(nearby_share_client), + nearby_identity_client_(nearby_identity_client), device_id_(std::move(device_id)), download_failure_callback_(std::move(download_failure_callback)), download_success_callback_(std::move(download_success_callback)) {} @@ -115,8 +118,13 @@ class NearbyShareCertificateManagerImpl // |download_success_callback_| is invoked with all downloaded certificates. void FetchNextPage(); + // Fetches the next page of certificates by calling Identity API + // QuerySharedCredentials. + void QuerySharedCredentialsFetchNextPage(); + private: nearby::sharing::api::SharingRpcClient* const nearby_share_client_; + nearby::sharing::api::IdentityRpcClient* const nearby_identity_client_; std::string device_id_; std::optional next_page_token_; int page_number_ = 1; @@ -202,6 +210,8 @@ class NearbyShareCertificateManagerImpl NearbyShareContactManager* const contact_manager_; int32_t vendor_id_ = 0; // Defaults to GOOGLE. std::unique_ptr< nearby::sharing::api::SharingRpcClient> nearby_client_; + std::unique_ptr + nearby_identity_client_; std::shared_ptr certificate_storage_; std::unique_ptr diff --git a/sharing/certificates/nearby_share_certificate_manager_impl_test.cc b/sharing/certificates/nearby_share_certificate_manager_impl_test.cc index 3cc0876e..44e2c66d 100644 --- a/sharing/certificates/nearby_share_certificate_manager_impl_test.cc +++ b/sharing/certificates/nearby_share_certificate_manager_impl_test.cc @@ -38,6 +38,8 @@ #include "internal/flags/nearby_flags.h" #include "internal/platform/implementation/account_manager.h" #include "internal/test/fake_account_manager.h" +#include "proto/identity/v1/resources.pb.h" +#include "proto/identity/v1/rpcs.pb.h" #include "sharing/certificates/constants.h" #include "sharing/certificates/fake_nearby_share_certificate_storage.h" #include "sharing/certificates/nearby_share_certificate_manager.h" @@ -67,6 +69,8 @@ namespace nearby { namespace sharing { namespace { +using ::google::nearby::identity::v1::QuerySharedCredentialsRequest; +using ::google::nearby::identity::v1::QuerySharedCredentialsResponse; using ::nearby::sharing::proto::DeviceVisibility; using ::nearby::sharing::proto::PublicCertificate; using ::testing::ReturnRef; @@ -395,6 +399,55 @@ class NearbyShareCertificateManagerImplTest initial_num_public_cert_exp_reschedules + (success ? 1u : 0u)); } + void QuerySharedCredentialsFlow(size_t num_pages, + DownloadPublicCertificatesResult result) { + size_t prev_num_results = download_scheduler_->handled_results().size(); + cert_store_->SetPublicCertificateIds(kPublicCertificateIds); + + size_t initial_num_notifications = + num_public_certs_downloaded_notifications_; + size_t initial_num_public_cert_exp_reschedules = + public_cert_exp_scheduler_->num_reschedule_calls(); + + std::vector> responses; + std::string page_token; + for (size_t page_number = 0; page_number < num_pages; ++page_number) { + bool last_page = page_number == num_pages - 1; + if (last_page && result == DownloadPublicCertificatesResult::kHttpError) { + responses.push_back(absl::InternalError("")); + break; + } + page_token = last_page ? std::string() + : absl::StrCat(kPageTokenPrefix, page_number); + responses.push_back( + BuildQuerySharedCredentialsResponse(page_number, page_token)); + } + + client_factory_.identity_instances() + .back() + ->SetQuerySharedCredentialsResponses(responses); + cert_store_->SetAddPublicCertificatesResult( + result != DownloadPublicCertificatesResult::kStorageError); + download_scheduler_->InvokeRequestCallback(); + Sync(); + + std::vector requests = + client_factory_.identity_instances() + .back() + ->query_shared_credentials_requests(); + EXPECT_EQ(requests.size(), num_pages); + EXPECT_EQ(requests.back().name(), absl::StrCat("devices/", kDeviceId)); + ASSERT_EQ(download_scheduler_->handled_results().size(), + prev_num_results + 1); + + bool success = result == DownloadPublicCertificatesResult::kSuccess; + EXPECT_EQ(download_scheduler_->handled_results().back(), success); + EXPECT_EQ(num_public_certs_downloaded_notifications_, + initial_num_notifications + (success ? 1u : 0u)); + EXPECT_EQ(public_cert_exp_scheduler_->num_reschedule_calls(), + initial_num_public_cert_exp_reschedules + (success ? 1u : 0u)); + } + void CheckRpcRequest(int num_pages) { std::vector requests = client_factory_.instances().back()->list_public_certificates_requests(); @@ -414,6 +467,30 @@ class NearbyShareCertificateManagerImplTest return response; } + QuerySharedCredentialsResponse BuildQuerySharedCredentialsResponse( + size_t page_number, absl::string_view page_token) { + QuerySharedCredentialsResponse response; + int i = 0; + for (auto public_certificate : public_certificates_) { + auto* shared_credential = response.add_shared_credentials(); + shared_credential->set_id(page_number * 100 + i); + if (i % 2 == 0) { + shared_credential->set_data_type( + google::nearby::identity::v1::SharedCredential:: + DATA_TYPE_PUBLIC_CERTIFICATE); + } else { + shared_credential->set_data_type( + google::nearby::identity::v1::SharedCredential:: + DATA_TYPE_SHARED_CREDENTIAL); + } + *shared_credential->mutable_data() = + public_certificate.SerializeAsString(); + i++; + } + response.set_next_page_token(page_token); + return response; + } + void CheckStorageAddCertificates( const FakeNearbyShareCertificateStorage::AddPublicCertificatesCall& add_cert_call) { @@ -697,6 +774,23 @@ TEST_F(NearbyShareCertificateManagerImplTest, /*num_pages=*/2, DownloadPublicCertificatesResult::kHttpError)); } +TEST_F(NearbyShareCertificateManagerImplTest, QuerySharedCredentialsSuccess) { + NearbyFlags::GetInstance().OverrideBoolFlagValue( + config_package_nearby::nearby_sharing_feature::kCallNearbyIdentityApi, + true); + ASSERT_NO_FATAL_FAILURE(QuerySharedCredentialsFlow( + /*num_pages=*/2, DownloadPublicCertificatesResult::kSuccess)); +} + +TEST_F(NearbyShareCertificateManagerImplTest, + QuerySharedCredentialsRPCFailure) { + NearbyFlags::GetInstance().OverrideBoolFlagValue( + config_package_nearby::nearby_sharing_feature::kCallNearbyIdentityApi, + true); + ASSERT_NO_FATAL_FAILURE(QuerySharedCredentialsFlow( + /*num_pages=*/2, DownloadPublicCertificatesResult::kHttpError)); +} + TEST_F(NearbyShareCertificateManagerImplTest, ClearPublicCertificates) { cert_manager_->ClearPublicCertificates([&](bool result) {}); EXPECT_THAT(cert_store_->clear_public_certificates_callbacks(), diff --git a/sharing/internal/api/fake_nearby_share_client.cc b/sharing/internal/api/fake_nearby_share_client.cc index ac69fefd..8827c292 100644 --- a/sharing/internal/api/fake_nearby_share_client.cc +++ b/sharing/internal/api/fake_nearby_share_client.cc @@ -77,7 +77,14 @@ void FakeNearbyIdentityClient::QuerySharedCredentials( response) &&> callback) { query_shared_credentials_requests_.emplace_back(request); - std::move(callback)(query_shared_credentials_response_); + if (query_shared_credentials_responses_.empty()) { + std::move(callback)(absl::NotFoundError("")); + return; + } + auto response = query_shared_credentials_responses_[0]; + query_shared_credentials_responses_.erase( + query_shared_credentials_responses_.begin()); + std::move(callback)(response); } void FakeNearbyIdentityClient::PublishDevice( diff --git a/sharing/internal/api/fake_nearby_share_client.h b/sharing/internal/api/fake_nearby_share_client.h index 33947371..a77b5486 100644 --- a/sharing/internal/api/fake_nearby_share_client.h +++ b/sharing/internal/api/fake_nearby_share_client.h @@ -115,6 +115,11 @@ class FakeNearbyIdentityClient return publish_device_requests_; } + std::vector& + query_shared_credentials_requests() { + return query_shared_credentials_requests_; + } + void PublishDevice( const google::nearby::identity::v1::PublishDeviceRequest& request, absl::AnyInvocable< @@ -137,11 +142,11 @@ class FakeNearbyIdentityClient response) &&> callback) override; - void SetQuerySharedCredentialsResponse( - absl::StatusOr< - google::nearby::identity::v1::QuerySharedCredentialsResponse> - response) { - query_shared_credentials_response_ = response; + void SetQuerySharedCredentialsResponses( + std::vector> + responses) { + query_shared_credentials_responses_ = responses; } std::vector @@ -151,8 +156,9 @@ class FakeNearbyIdentityClient std::vector query_shared_credentials_requests_; - absl::StatusOr - query_shared_credentials_response_; + std::vector> + query_shared_credentials_responses_; }; class FakeNearbyShareClientFactory