Fix dependency between PresenceClient and PresenceService

Give PresenceClient a borrowable reference to PresenceService. Benefits:
1. PresenceClient can verify if PresenceService is alive before trying to access it.
2. The calls to PresenceService are serialized.
3. PresenceService will not be destroyed while a PresenceClient is using it.

PiperOrigin-RevId: 489590767
This commit is contained in:
Janusz Sobczak
2022-11-18 16:52:35 -08:00
committed by Copybara-Service
parent a11733988f
commit 49d47d8e16
6 changed files with 59 additions and 11 deletions
+1
View File
@@ -27,6 +27,7 @@ cc_library(
],
deps = [
":types",
"//internal/platform:types",
"//presence/implementation:internal", # build_cleaner: keep
"@com_google_absl//absl/log:die_if_null",
],
+11 -6
View File
@@ -17,22 +17,27 @@
#include <memory>
#include <vector>
#include "absl/log/die_if_null.h"
#include "internal/platform/borrowable.h"
#include "presence/presence_service.h"
namespace nearby {
namespace presence {
PresenceClient::PresenceClient(PresenceService* service)
: service_(*ABSL_DIE_IF_NULL(service)) {}
std::unique_ptr<ScanSession> PresenceClient::StartScan(ScanRequest scan_request,
ScanCallback callback) {
return service_.StartScan(scan_request, callback);
::location::nearby::Borrowed<PresenceService*> borrowed = service_.Borrow();
if (!borrowed) {
return nullptr;
}
return (*borrowed)->StartScan(scan_request, callback);
}
std::unique_ptr<BroadcastSession> PresenceClient::StartBroadcast(
BroadcastRequest broadcast_request, BroadcastCallback callback) {
return service_.StartBroadcast(broadcast_request, callback);
::location::nearby::Borrowed<PresenceService*> borrowed = service_.Borrow();
if (!borrowed) {
return nullptr;
}
return (*borrowed)->StartBroadcast(broadcast_request, callback);
}
} // namespace presence
+9 -3
View File
@@ -19,6 +19,7 @@
#include <memory>
#include <vector>
#include "internal/platform/borrowable.h"
#include "presence/broadcast_request.h"
#include "presence/data_types.h"
#include "presence/scan_request.h"
@@ -33,10 +34,15 @@ class PresenceService;
*/
class PresenceClient {
public:
explicit PresenceClient(PresenceService* service);
using BorrowablePresenceService =
::location::nearby::Borrowable<PresenceService*>;
explicit PresenceClient(BorrowablePresenceService service)
: service_(service) {}
PresenceClient(const PresenceClient&) = delete;
PresenceClient(PresenceClient&&) = default;
PresenceClient& operator=(const PresenceClient&) = delete;
~PresenceClient() = default;
/**
* Starts a Nearby Presence scan and registers {@link ScanCallback}
* which will be invoked when a matching {@link PresenceDevice} is detected,
@@ -69,7 +75,7 @@ class PresenceClient {
BroadcastRequest broadcast_request, BroadcastCallback callback);
private:
PresenceService& service_;
BorrowablePresenceService service_;
};
} // namespace presence
+33
View File
@@ -24,6 +24,13 @@ namespace nearby {
namespace presence {
namespace {
// Creates a PresenceClient and destroys PresenceService that was used to create
// it.
PresenceClient CreateDefunctPresenceClient() {
PresenceService presence_service;
return presence_service.CreatePresenceClient();
}
class PresenceClientTest : public testing::Test {
protected:
location::nearby::MediumEnvironment& env_{
@@ -45,6 +52,19 @@ TEST_F(PresenceClientTest, StartBroadcastWithDefaultConstructor) {
env_.Stop();
}
TEST_F(PresenceClientTest, StartBroadcastFailsWhenPresenceServiceIsGone) {
env_.Start();
Status broadcast_result = {Status::Value::kError};
BroadcastCallback broadcast_callback = {
.start_broadcast_cb = [&](Status status) { broadcast_result = status; },
};
CreateDefunctPresenceClient().StartBroadcast({}, broadcast_callback);
EXPECT_FALSE(broadcast_result.Ok());
env_.Stop();
}
TEST_F(PresenceClientTest, StartScanWithDefaultConstructor) {
env_.Start();
Status scan_result = {Status::Value::kError};
@@ -60,6 +80,19 @@ TEST_F(PresenceClientTest, StartScanWithDefaultConstructor) {
env_.Stop();
}
TEST_F(PresenceClientTest, StartScanFailsWhenPresenceServiceIsGone) {
env_.Start();
Status scan_result = {Status::Value::kError};
ScanCallback scan_callback = {
.start_scan_cb = [&](Status status) { scan_result = status; },
};
CreateDefunctPresenceClient().StartScan({}, scan_callback);
EXPECT_FALSE(scan_result.Ok());
env_.Stop();
}
} // namespace
} // namespace presence
} // namespace nearby
+2 -1
View File
@@ -16,6 +16,7 @@
#include <memory>
#include "internal/platform/borrowable.h"
#include "presence/data_types.h"
#include "presence/implementation/service_controller_impl.h"
@@ -26,7 +27,7 @@ PresenceService::PresenceService() {
}
PresenceClient PresenceService::CreatePresenceClient() {
return PresenceClient(this);
return PresenceClient(lender_.GetBorrowable());
}
std::unique_ptr<ScanSession> PresenceService::StartScan(
+3 -1
View File
@@ -17,6 +17,7 @@
#include <memory>
#include "internal/platform/borrowable.h"
#include "presence/data_types.h"
#include "presence/implementation/service_controller.h"
#include "presence/presence_client.h"
@@ -32,7 +33,7 @@ namespace presence {
class PresenceService {
public:
PresenceService();
~PresenceService() = default;
~PresenceService() { lender_.Release(); }
PresenceClient CreatePresenceClient();
@@ -43,6 +44,7 @@ class PresenceService {
private:
std::unique_ptr<ServiceController> service_controller_;
::location::nearby::Lender<PresenceService *> lender_{this};
};
} // namespace presence