Add onSessionComplete method in ClientProxy to log session

PiperOrigin-RevId: 461772377
This commit is contained in:
hai007
2022-07-18 19:17:19 -07:00
committed by Copybara-Service
parent 7153f5e482
commit d41cd674c8
7 changed files with 1090 additions and 25 deletions
+1
View File
@@ -234,6 +234,7 @@ cc_test(
"//connections:core_types",
"//connections/implementation/mediums",
"//connections/implementation/proto:offline_wire_formats_cc_proto",
"//internal/analytics:event_logger",
"//internal/platform:base",
"//internal/platform:comm",
"//internal/platform:logging",
@@ -16,6 +16,7 @@
#include <algorithm>
#include <memory>
#include <optional>
#include <string>
#include <utility>
@@ -33,6 +34,7 @@ namespace analytics {
namespace {
const char kVersion[] = "v1.0.0";
constexpr absl::string_view kOnStartClientSession = "OnStartClientSession";
} // namespace
using ::location::nearby::analytics::proto::ConnectionsLog;
@@ -88,21 +90,41 @@ using ::nearby::analytics::EventLogger;
AnalyticsRecorder::AnalyticsRecorder(EventLogger *event_logger)
: event_logger_(event_logger) {
started_client_session_time_ = SystemClock::ElapsedRealtime();
NEARBY_LOGS(INFO) << "AnalyticsRecorder ctor event_logger_=" << event_logger_;
MutexLock lock(&mutex_);
if (CanRecordAnalyticsLocked("OnStartClientSession")) {
LogEvent(START_CLIENT_SESSION);
}
NEARBY_LOGS(INFO) << "Start AnalyticsRecorder ctor event_logger_="
<< event_logger_;
LogStartSession();
}
AnalyticsRecorder::~AnalyticsRecorder() {
serial_executor_.Shutdown();
ResetClientSessionLoggingResouces();
}
bool AnalyticsRecorder::IsSessionLogged() {
MutexLock lock(&mutex_);
return session_was_logged_;
}
void AnalyticsRecorder::ResetClientSessionLoggingResouces() {
MutexLock lock(&mutex_);
NEARBY_LOGS(INFO) << "Reset AnalyticsRecorder ctor event_logger_="
<< event_logger_;
incoming_connection_requests_.clear();
outgoing_connection_requests_.clear();
active_connections_.clear();
bandwidth_upgrade_attempts_.clear();
serial_executor_.Shutdown();
client_session_ = nullptr;
session_was_logged_ = true;
start_client_session_was_logged_ = false;
current_strategy_ =
connections::Strategy::kNone; // Need to reset since the same strategy
// should be logged separately for
// different client sessions.
current_strategy_session_ = nullptr;
current_advertising_phase_ = nullptr;
current_discovery_phase_ = nullptr;
}
void AnalyticsRecorder::OnStartAdvertising(
@@ -163,8 +185,7 @@ void AnalyticsRecorder::OnStartDiscovery(
// Initialize and set a DiscoveryPhase.
started_discovery_phase_time_ = SystemClock::ElapsedRealtime();
current_discovery_phase_ =
std::make_unique<ConnectionsLog::DiscoveryPhase>();
current_discovery_phase_ = std::make_unique<ConnectionsLog::DiscoveryPhase>();
absl::c_copy(mediums, RepeatedFieldBackInserter(
current_discovery_phase_->mutable_medium()));
// Set a DiscoveryMetadata.
@@ -632,6 +653,26 @@ void AnalyticsRecorder::OnErrorCode(const ErrorCodeParams &params) {
});
}
void AnalyticsRecorder::LogStartSession() {
MutexLock lock(&mutex_);
if (start_client_session_was_logged_) {
NEARBY_LOGS(WARNING)
<< "AnalyticsRecorder CanRecordAnalytics Unexpected call "
<< kOnStartClientSession
<< " after start client session has already been logged.";
return;
}
session_was_logged_ = false;
if (CanRecordAnalyticsLocked(kOnStartClientSession)) {
client_session_ =
std::make_unique<proto::ConnectionsLog::ClientSession>();
started_client_session_time_ = SystemClock::ElapsedRealtime();
start_client_session_was_logged_ = true;
LogEvent(START_CLIENT_SESSION);
}
}
void AnalyticsRecorder::LogSession() {
MutexLock lock(&mutex_);
if (!CanRecordAnalyticsLocked("LogSession")) {
@@ -668,7 +709,7 @@ AnalyticsRecorder::BuildConnectionAttemptMetadataParams(
}
bool AnalyticsRecorder::CanRecordAnalyticsLocked(
const std::string &method_name) {
absl::string_view method_name) {
NEARBY_LOGS(VERBOSE) << "AnalyticsRecorder LogEvent " << method_name
<< " is calling.";
if (event_logger_ == nullptr) {
@@ -681,6 +722,7 @@ bool AnalyticsRecorder::CanRecordAnalyticsLocked(
<< method_name << " after session has already been logged.";
return false;
}
return true;
}
@@ -697,6 +739,7 @@ void AnalyticsRecorder::LogClientSession() {
<< connections_log.DebugString();
event_logger_->Log(connections_log);
ResetClientSessionLoggingResouces();
});
}
@@ -717,7 +760,7 @@ void AnalyticsRecorder::UpdateStrategySessionLocked(
connections::Strategy strategy, SessionRole role) {
// If we're not switching strategies, just update the current StrategySession
// with the new role.
if (strategy == current_strategy_) {
if (strategy == current_strategy_ && current_strategy_session_ != nullptr) {
if (absl::c_linear_search(current_strategy_session_->role(), role)) {
// We've already acted as this role before, so make sure we've finished
// recording the previous round.
@@ -164,11 +164,17 @@ class AnalyticsRecorder {
// Error Code
void OnErrorCode(const ErrorCodeParams &params);
// Log the start client session event with start client session logging
// resouces setup (e.g. client_session_, started_client_session_time_)
void LogStartSession() ABSL_LOCKS_EXCLUDED(mutex_);
// Invokes event_logger_.Log() at the end of life of client. Log action is
// called in a separate thread to allow synchronous potentially lengthy
// execution.
void LogSession() ABSL_LOCKS_EXCLUDED(mutex_);
bool IsSessionLogged();
private:
// Tracks the chunks and duration of a Payload on a particular medium.
class PendingPayload {
@@ -267,7 +273,7 @@ class AnalyticsRecorder {
outgoing_payloads_;
};
bool CanRecordAnalyticsLocked(const std::string &method_name)
bool CanRecordAnalyticsLocked(absl::string_view method_name)
ABSL_SHARED_LOCKS_REQUIRED(mutex_);
// Callbacks the ConnectionsLog proto byte array data to the EventLogger with
@@ -314,6 +320,10 @@ class AnalyticsRecorder {
bool erase_item = true) ABSL_SHARED_LOCKS_REQUIRED(mutex_);
void FinishStrategySessionLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Reset the client cession's logging resources (e.g. current_strategy_,
// current_advertising_phase_, current_discovery_phase_, etc)
void ResetClientSessionLoggingResouces();
location::nearby::proto::connections::ConnectionsStrategy
StrategyToConnectionStrategy(connections::Strategy strategy);
location::nearby::proto::connections::PayloadType
@@ -328,10 +338,10 @@ class AnalyticsRecorder {
Mutex mutex_;
// ClientSession
std::unique_ptr<proto::ConnectionsLog::ClientSession> client_session_ =
std::make_unique<proto::ConnectionsLog::ClientSession>();
std::unique_ptr<proto::ConnectionsLog::ClientSession> client_session_;
absl::Time started_client_session_time_;
bool session_was_logged_ ABSL_GUARDED_BY(mutex_) = false;
bool start_client_session_was_logged_ ABSL_GUARDED_BY(mutex_) = false;
// Current StrategySession
connections::Strategy current_strategy_ ABSL_GUARDED_BY(mutex_) =
@@ -55,6 +55,7 @@ using ::location::nearby::proto::connections::LOCAL_DISCONNECTION;
using ::location::nearby::proto::connections::Medium;
using ::location::nearby::proto::connections::RESULT_ERROR;
using ::location::nearby::proto::connections::RESULT_SUCCESS;
using ::location::nearby::proto::connections::START_CLIENT_SESSION;
using ::location::nearby::proto::connections::START_STRATEGY_SESSION;
using ::location::nearby::proto::connections::STOP_CLIENT_SESSION;
using ::location::nearby::proto::connections::STOP_STRATEGY_SESSION;
@@ -67,6 +68,7 @@ using ::location::nearby::proto::connections::WIFI_LAN_SOCKET_CREATION;
using ::nearby::analytics::EventLogger;
using ::testing::Contains;
using ::protobuf_matchers::EqualsProto;
using ::testing::Not;
using ::testing::proto::Partially;
constexpr absl::Duration kDefaultTimeout = absl::Milliseconds(1000);
@@ -76,6 +78,12 @@ class FakeEventLogger : public EventLogger {
explicit FakeEventLogger(CountDownLatch& client_session_done_latch)
: client_session_done_latch_(client_session_done_latch) {}
FakeEventLogger(CountDownLatch& client_session_done_latch,
CountDownLatch* start_client_session_done_latch_ptr)
: client_session_done_latch_(client_session_done_latch),
start_client_session_done_latch_ptr_(
start_client_session_done_latch_ptr) {}
void Log(const ::google::protobuf::MessageLite& message) override {
auto connections_log = dynamic_cast<const proto::ConnectionsLog*>(&message);
if (connections_log == nullptr) {
@@ -94,6 +102,10 @@ class FakeEventLogger : public EventLogger {
if (event_type == STOP_CLIENT_SESSION) {
client_session_done_latch_.CountDown();
}
if (start_client_session_done_latch_ptr_ != nullptr &&
event_type == START_CLIENT_SESSION) {
start_client_session_done_latch_ptr_->CountDown();
}
}
int GetLoggedClientSessionCount() const {
@@ -108,14 +120,27 @@ class FakeEventLogger : public EventLogger {
std::vector<EventType> GetLoggedEventTypes() { return logged_event_types_; }
void SetClientSessionDoneLatch(
const CountDownLatch& client_session_done_latch) {
client_session_done_latch_ = client_session_done_latch;
}
void SetStartClientSessionDoneLatchPtr(
CountDownLatch* start_client_session_done_latch_ptr) {
start_client_session_done_latch_ptr_ = start_client_session_done_latch_ptr;
}
private:
int logged_client_session_count_ = 0;
CountDownLatch& client_session_done_latch_;
CountDownLatch* start_client_session_done_latch_ptr_ = nullptr;
ConnectionsLog::ClientSession logged_client_session_;
ConnectionsLog::ErrorCode error_code_;
std::vector<EventType> logged_event_types_;
};
// Test if session_was_logged_ is reset by checking if LogSession can take
// effect again or not.
TEST(AnalyticsRecorderTest, SessionOnlyLoggedOnceWorks) {
CountDownLatch client_session_done_latch(1);
FakeEventLogger event_logger(client_session_done_latch);
@@ -941,6 +966,777 @@ TEST(AnalyticsRecorderTest, SetErrorCodeFieldsCorrectlyForCommonError) {
)pb")));
}
TEST(AnalyticsRecorderTest, CheckIfSessionWasLogged) {
CountDownLatch client_session_done_latch(1);
FakeEventLogger event_logger(client_session_done_latch);
AnalyticsRecorder analytics_recorder(&event_logger);
// LogSession to count down client_session_done_latch.
analytics_recorder.LogSession();
ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result());
EXPECT_TRUE(analytics_recorder.IsSessionLogged());
}
TEST(AnalyticsRecorderTest, ConstructAnalyticsRecorder) {
CountDownLatch client_session_done_latch(0);
CountDownLatch start_client_session_done_latch(1);
FakeEventLogger event_logger(client_session_done_latch,
&start_client_session_done_latch);
// Call the constructor to count down the session_done_latch.
AnalyticsRecorder analytics_recorder(&event_logger);
ASSERT_TRUE(start_client_session_done_latch.Await(kDefaultTimeout).result());
std::vector<EventType> event_types = event_logger.GetLoggedEventTypes();
EXPECT_EQ(event_types.size(), 1);
EXPECT_THAT(event_types, Contains(START_CLIENT_SESSION).Times(1));
}
TEST(AnalyticsRecorderTest,
StartClientSessionOnlyLoggedOnceWorksAfterAnalyticsRecorderIsConstructed) {
CountDownLatch client_session_done_latch(0);
CountDownLatch start_client_session_done_latch(1);
FakeEventLogger event_logger(client_session_done_latch,
&start_client_session_done_latch);
// Call the constructor to count down the start_client_session_done_latch.
AnalyticsRecorder analytics_recorder(&event_logger);
ASSERT_TRUE(start_client_session_done_latch.Await(kDefaultTimeout).result());
// Log start client session once.
EXPECT_THAT(event_logger.GetLoggedEventTypes(),
Contains(START_CLIENT_SESSION).Times(1));
// Reset the start_client_session_done_latch. However, LogStartSession cannot
// count down the start_client_session_done_latch.
CountDownLatch new_start_client_session_done_latch(1);
event_logger.SetStartClientSessionDoneLatchPtr(
&new_start_client_session_done_latch);
analytics_recorder.LogStartSession();
ASSERT_FALSE(
new_start_client_session_done_latch.Await(kDefaultTimeout).result());
// No more start client session was logged.
EXPECT_THAT(event_logger.GetLoggedEventTypes(),
Contains(START_CLIENT_SESSION).Times(1));
}
TEST(AnalyticsRecorderTest,
CanLogStartClientSessionOnceAgainAfterSessionWasLogged) {
CountDownLatch client_session_done_latch(0);
CountDownLatch start_client_session_done_latch(1);
FakeEventLogger event_logger(client_session_done_latch,
&start_client_session_done_latch);
// Call the constructor to count down the start_client_session_done_latch.
AnalyticsRecorder analytics_recorder(&event_logger);
ASSERT_TRUE(start_client_session_done_latch.Await(kDefaultTimeout).result());
// Log start client session once.
EXPECT_THAT(event_logger.GetLoggedEventTypes(),
Contains(START_CLIENT_SESSION).Times(1));
// Reset the client_session_done_latch. Call LogSession to count down the
// client_session_done_latch.
CountDownLatch new_client_session_done_latch(1);
event_logger.SetClientSessionDoneLatch(new_client_session_done_latch);
analytics_recorder.LogSession();
ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result());
// Reset the start_client_session_done_latch. Call LogStartSession to count
// down the start_client_session_done_latch.
CountDownLatch new_start_client_session_done_latch(1);
event_logger.SetStartClientSessionDoneLatchPtr(
&new_start_client_session_done_latch);
analytics_recorder.LogStartSession();
analytics_recorder.LogStartSession();
analytics_recorder.LogStartSession();
analytics_recorder.LogStartSession();
ASSERT_TRUE(
new_start_client_session_done_latch.Await(kDefaultTimeout).result());
// Can log start client session once again.
EXPECT_THAT(event_logger.GetLoggedEventTypes(),
Contains(START_CLIENT_SESSION).Times(2));
}
TEST(AnalyticsRecorderTest,
ClearcIncomingConnectionRequestsAfterSessionWasLogged) {
connections::Strategy strategy = connections::Strategy::kP2pStar;
std::vector<Medium> mediums = {BLE, BLUETOOTH};
std::string endpoint_id_0 = "endpoint_id_0";
CountDownLatch client_session_done_latch(1);
FakeEventLogger event_logger(client_session_done_latch);
AnalyticsRecorder analytics_recorder(&event_logger);
analytics_recorder.OnStartAdvertising(strategy, mediums);
analytics_recorder.OnConnectionRequestReceived(endpoint_id_0);
analytics_recorder.OnLocalEndpointAccepted(endpoint_id_0);
analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_0);
// LogSession
analytics_recorder.LogSession(); // call ResetClientSessionLoggingResouces
ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result());
EXPECT_THAT(event_logger.GetLoggedClientSession(), Partially(EqualsProto(R"pb(
strategy_session <
strategy: P2P_STAR
role: ADVERTISER
advertising_phase <
medium: BLE
medium: BLUETOOTH
advertising_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
received_connection_request <
local_response: ACCEPTED
remote_response: ACCEPTED
>
>
>)pb")));
// LogStartSession
CountDownLatch new_start_client_session_done_latch(1);
event_logger.SetStartClientSessionDoneLatchPtr(
&new_start_client_session_done_latch);
analytics_recorder.LogStartSession();
ASSERT_TRUE(
new_start_client_session_done_latch.Await(kDefaultTimeout).result());
// LogSession again
CountDownLatch new_client_session_done_latch(1);
event_logger.SetClientSessionDoneLatch(new_client_session_done_latch);
std::string endpoint_id_1 = "endpoint_id_1";
analytics_recorder.OnConnectionRequestReceived(endpoint_id_1);
analytics_recorder.OnLocalEndpointAccepted(endpoint_id_1);
analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_1);
analytics_recorder.LogSession();
ASSERT_TRUE(new_client_session_done_latch.Await(kDefaultTimeout).result());
// - if the current_strategy_session_ and current_advertising_phase_ are not
// reset, the duplicate advertising_phase (with the additional
// received_connection_request) will append to the strategy_session)
EXPECT_THAT(event_logger.GetLoggedClientSession(),
Not(Partially(EqualsProto(R"pb(
strategy_session <
strategy: P2P_STAR
role: ADVERTISER
advertising_phase <
medium: BLE
medium: BLUETOOTH
advertising_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
received_connection_request <
local_response: ACCEPTED
remote_response: ACCEPTED
>
>
advertising_phase <
medium: BLE
medium: BLUETOOTH
advertising_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
received_connection_request <
local_response: ACCEPTED
remote_response: ACCEPTED
>
received_connection_request <
local_response: ACCEPTED
remote_response: ACCEPTED
>
>
>)pb"))));
}
TEST(AnalyticsRecorderTest,
ClearcOutgoingConnectionRequestsAfterSessionWasLogged) {
connections::Strategy strategy = connections::Strategy::kP2pStar;
std::vector<Medium> mediums = {BLE, BLUETOOTH};
std::string endpoint_id_0 = "endpoint_id_0";
CountDownLatch client_session_done_latch(1);
FakeEventLogger event_logger(client_session_done_latch);
AnalyticsRecorder analytics_recorder(&event_logger);
analytics_recorder.OnStartDiscovery(strategy, mediums);
analytics_recorder.OnConnectionRequestSent(endpoint_id_0);
analytics_recorder.OnLocalEndpointAccepted(endpoint_id_0);
analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_0);
// LogSession
analytics_recorder.LogSession(); // call ResetClientSessionLoggingResouces
ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result());
EXPECT_THAT(event_logger.GetLoggedClientSession(), Partially(EqualsProto(R"pb(
strategy_session <
strategy: P2P_STAR
role: DISCOVERER
discovery_phase <
medium: BLE
medium: BLUETOOTH
discovery_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
sent_connection_request <
local_response: ACCEPTED
remote_response: ACCEPTED
>
>
>)pb")));
// LogStartSession
CountDownLatch new_start_client_session_done_latch(1);
event_logger.SetStartClientSessionDoneLatchPtr(
&new_start_client_session_done_latch);
analytics_recorder.LogStartSession();
ASSERT_TRUE(
new_start_client_session_done_latch.Await(kDefaultTimeout).result());
// LogSession again
CountDownLatch new_client_session_done_latch(1);
event_logger.SetClientSessionDoneLatch(new_client_session_done_latch);
std::string endpoint_id_1 = "endpoint_id_1";
analytics_recorder.OnConnectionRequestSent(endpoint_id_1);
analytics_recorder.OnLocalEndpointAccepted(endpoint_id_1);
analytics_recorder.OnRemoteEndpointAccepted(endpoint_id_1);
analytics_recorder.LogSession();
ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result());
// - if the current_strategy_session_ and current_discovery_phase_ are
// not reset, the duplicate discovery_phase (with the additional
// sent_connection_request) will append to the strategy_session)
EXPECT_THAT(event_logger.GetLoggedClientSession(),
Not(Partially(EqualsProto(R"pb(
strategy_session <
strategy: P2P_STAR
role: DISCOVERER
discovery_phase <
medium: BLE
medium: BLUETOOTH
discovery_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
sent_connection_request <
local_response: ACCEPTED
remote_response: ACCEPTED
>
>
discovery_phase <
medium: BLE
medium: BLUETOOTH
discovery_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
sent_connection_request <
local_response: ACCEPTED
remote_response: ACCEPTED
>
sent_connection_request <
local_response: ACCEPTED
remote_response: ACCEPTED
>
>
>)pb"))));
}
TEST(AnalyticsRecorderTest, ClearcActiveConnectionsAfterSessionWasLogged) {
connections::Strategy strategy = connections::Strategy::kP2pStar;
std::vector<Medium> mediums = {BLE, BLUETOOTH};
std::string endpoint_id = "endpoint_id";
std::string connection_token = "connection_token";
CountDownLatch client_session_done_latch(1);
FakeEventLogger event_logger(client_session_done_latch);
AnalyticsRecorder analytics_recorder(&event_logger);
analytics_recorder.OnStartAdvertising(strategy, mediums);
analytics_recorder.OnConnectionEstablished(endpoint_id, BLUETOOTH,
connection_token);
// LogSession
analytics_recorder.LogSession(); // call ResetClientSessionLoggingResouces
ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result());
EXPECT_THAT(event_logger.GetLoggedClientSession(), Partially(EqualsProto(R"pb(
strategy_session <
strategy: P2P_STAR
role: ADVERTISER
advertising_phase <
medium: BLE
medium: BLUETOOTH
advertising_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
>
established_connection <
medium: BLUETOOTH
disconnection_reason: UNFINISHED
connection_token: "connection_token"
>
>)pb")));
// LogStartSession
CountDownLatch new_start_client_session_done_latch(1);
event_logger.SetStartClientSessionDoneLatchPtr(
&new_start_client_session_done_latch);
analytics_recorder.LogStartSession();
ASSERT_TRUE(
new_start_client_session_done_latch.Await(kDefaultTimeout).result());
// LogSession again
CountDownLatch new_client_session_done_latch(1);
event_logger.SetClientSessionDoneLatch(new_client_session_done_latch);
analytics_recorder.LogSession();
ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result());
// - if the current_strategy_session_ and advertising_phase_ are not
// reset, the duplicate advertising_phase_ (with the additional
// will append to the strategy_session), and the active connection (i.e.
// established_connection) will stay there.
EXPECT_THAT(event_logger.GetLoggedClientSession(),
Not(Partially(EqualsProto(R"pb(
strategy_session <
strategy: P2P_STAR
role: ADVERTISER
advertising_phase <
medium: BLE
medium: BLUETOOTH
advertising_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
>
advertising_phase <
medium: BLE
medium: BLUETOOTH
advertising_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
>
established_connection <
medium: BLUETOOTH
disconnection_reason: UNFINISHED
connection_token: "connection_token"
>
>)pb"))));
}
TEST(AnalyticsRecorderTest,
ClearBandwidthUpgradeAttemptsAfterSessionWasLogged) {
connections::Strategy strategy = connections::Strategy::kP2pStar;
std::vector<Medium> mediums = {BLE, BLUETOOTH};
std::string endpoint_id = "endpoint_id";
std::string endpoint_id_1 = "endpoint_id_1";
std::string endpoint_id_2 = "endpoint_id_2";
std::string connection_token = "connection_token";
CountDownLatch client_session_done_latch(1);
FakeEventLogger event_logger(client_session_done_latch);
AnalyticsRecorder analytics_recorder(&event_logger);
analytics_recorder.OnStartAdvertising(strategy, mediums);
analytics_recorder.OnBandwidthUpgradeStarted(endpoint_id, BLE, WIFI_LAN,
INCOMING, connection_token);
analytics_recorder.OnBandwidthUpgradeStarted(
endpoint_id_1, BLUETOOTH, WIFI_LAN, INCOMING, connection_token);
// - Error to upgrade.
analytics_recorder.OnBandwidthUpgradeError(endpoint_id, WIFI_LAN_MEDIUM_ERROR,
WIFI_LAN_SOCKET_CREATION);
// - Success to upgrade.
analytics_recorder.OnBandwidthUpgradeSuccess(endpoint_id_1);
// - Upgrade is unfinished.
analytics_recorder.OnBandwidthUpgradeStarted(
endpoint_id_2, BLUETOOTH, WIFI_LAN, INCOMING, connection_token);
// LogSession
analytics_recorder.LogSession(); // call ResetClientSessionLoggingResouces
ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result());
// - if the current_strategy_session_ and advertising_phase_ are not
// reset, the duplicate advertising_phase_, and the upgrade_attempts (i.e.
// bandwidth_upgrade_attempts_) will stay there.
EXPECT_THAT(event_logger.GetLoggedClientSession(), Partially(EqualsProto(R"pb(
strategy_session <
strategy: P2P_STAR
role: ADVERTISER
advertising_phase <
medium: BLE
medium: BLUETOOTH
advertising_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
>
upgrade_attempt <
direction: INCOMING
from_medium: BLE
to_medium: WIFI_LAN
upgrade_result: WIFI_LAN_MEDIUM_ERROR
error_stage: WIFI_LAN_SOCKET_CREATION
connection_token: "connection_token"
>
upgrade_attempt <
direction: INCOMING
from_medium: BLUETOOTH
to_medium: WIFI_LAN
upgrade_result: UPGRADE_RESULT_SUCCESS
error_stage: UPGRADE_SUCCESS
connection_token: "connection_token"
>
upgrade_attempt {
direction: INCOMING
from_medium: BLUETOOTH
to_medium: WIFI_LAN
upgrade_result: UNFINISHED_ERROR
error_stage: UPGRADE_UNFINISHED
connection_token: "connection_token"
}
>)pb")));
// LogStartSession
CountDownLatch new_start_client_session_done_latch(1);
event_logger.SetStartClientSessionDoneLatchPtr(
&new_start_client_session_done_latch);
analytics_recorder.LogStartSession();
ASSERT_TRUE(
new_start_client_session_done_latch.Await(kDefaultTimeout).result());
// LogSession again
CountDownLatch new_client_session_done_latch(1);
event_logger.SetClientSessionDoneLatch(new_client_session_done_latch);
analytics_recorder.LogSession();
ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result());
EXPECT_THAT(event_logger.GetLoggedClientSession(),
Not(Partially(EqualsProto(R"pb(
strategy_session <
strategy: P2P_STAR
role: ADVERTISER
advertising_phase <
medium: BLE
medium: BLUETOOTH
advertising_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
>
advertising_phase <
medium: BLE
medium: BLUETOOTH
advertising_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
>
upgrade_attempt <
direction: INCOMING
from_medium: BLE
to_medium: WIFI_LAN
upgrade_result: WIFI_LAN_MEDIUM_ERROR
error_stage: WIFI_LAN_SOCKET_CREATION
connection_token: "connection_token"
>
upgrade_attempt <
direction: INCOMING
from_medium: BLUETOOTH
to_medium: WIFI_LAN
upgrade_result: UPGRADE_RESULT_SUCCESS
error_stage: UPGRADE_SUCCESS
connection_token: "connection_token"
>
upgrade_attempt {
direction: INCOMING
from_medium: BLUETOOTH
to_medium: WIFI_LAN
upgrade_result: UNFINISHED_ERROR
error_stage: UPGRADE_UNFINISHED
connection_token: "connection_token"
}
>)pb"))));
}
// Test if current_strategy_ is reset by checking if the same strategy would
// be logged for different client sessions or not. If yes, it should be logged.
// Otherwise, not.
TEST(AnalyticsRecorderTest,
CanLogSeparateStartStrategySessionForSameStrategyAfterSessionWasLogged) {
connections::Strategy strategy = connections::Strategy::kP2pStar;
CountDownLatch client_session_done_latch(1);
FakeEventLogger event_logger(client_session_done_latch);
AnalyticsRecorder analytics_recorder(&event_logger);
analytics_recorder.OnStartAdvertising(strategy, {BLUETOOTH});
analytics_recorder.OnStopAdvertising();
// LogSession
analytics_recorder.LogSession();
ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result());
EXPECT_THAT(event_logger.GetLoggedEventTypes(),
Contains(START_STRATEGY_SESSION)
.Times(1)); // the same strategy session shouldn't be logged
// again with the same client sesssion.
// LogStartSession
CountDownLatch new_start_client_session_done_latch(1);
event_logger.SetStartClientSessionDoneLatchPtr(
&new_start_client_session_done_latch);
analytics_recorder.LogStartSession();
ASSERT_TRUE(
new_start_client_session_done_latch.Await(kDefaultTimeout).result());
// LogSession again
CountDownLatch new_client_session_done_latch(1);
event_logger.SetClientSessionDoneLatch(new_client_session_done_latch);
analytics_recorder.OnStartAdvertising(strategy, {BLUETOOTH});
analytics_recorder.OnStopAdvertising();
analytics_recorder.LogSession();
ASSERT_TRUE(new_client_session_done_latch.Await(kDefaultTimeout).result());
EXPECT_THAT(event_logger.GetLoggedEventTypes(),
Contains(START_STRATEGY_SESSION).Times(2));
}
// Test if current_strategy_session_ is reset. If not, the same strategy session
// proto will be logged.
TEST(AnalyticsRecorderTest,
NotLogSameStrategySessionProtoAfterSessionWasLogged) {
connections::Strategy strategy = connections::Strategy::kP2pStar;
std::vector<Medium> mediums = {BLE, BLUETOOTH};
std::string endpoint_id = "endpoint_id";
std::string connection_token = "";
CountDownLatch client_session_done_latch(1);
FakeEventLogger event_logger(client_session_done_latch);
AnalyticsRecorder analytics_recorder{&event_logger};
analytics_recorder.OnStartAdvertising(
strategy, mediums); // via OnStartAdvertising, current_strategy_session_
// is set in UpdateStrategySessionLocked.
analytics_recorder.OnStopAdvertising();
// LogSession
analytics_recorder.LogSession();
ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result());
std::string strategy_session_proto = R"pb(
strategy_session <
strategy: P2P_STAR
role: ADVERTISER
advertising_phase <
medium: BLE
medium: BLUETOOTH
advertising_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
>
>)pb";
EXPECT_THAT(event_logger.GetLoggedClientSession(),
Partially(EqualsProto(strategy_session_proto)));
// LogStartSession
CountDownLatch new_start_client_session_done_latch(1);
event_logger.SetStartClientSessionDoneLatchPtr(
&new_start_client_session_done_latch);
analytics_recorder.LogStartSession();
ASSERT_TRUE(
new_start_client_session_done_latch.Await(kDefaultTimeout).result());
// LogSession again
// - if current_strategy_session_ is reset, the same strategy_session_proto
// will be logged.
CountDownLatch new_client_session_done_latch(1);
event_logger.SetClientSessionDoneLatch(new_client_session_done_latch);
analytics_recorder.LogSession();
ASSERT_TRUE(new_client_session_done_latch.Await(kDefaultTimeout).result());
EXPECT_THAT(event_logger.GetLoggedClientSession(),
Not(Partially(EqualsProto(strategy_session_proto))));
}
// Test if current_advertising_phase_ is reset.
TEST(AnalyticsRecorderTest,
NotLogDuplicateAdvertisingPhaseAfterSessionWasLogged) {
connections::Strategy strategy = connections::Strategy::kP2pStar;
CountDownLatch client_session_done_latch(1);
FakeEventLogger event_logger(client_session_done_latch);
AnalyticsRecorder analytics_recorder(&event_logger);
analytics_recorder.OnStartAdvertising(
strategy, {BLUETOOTH}); // set current_advertising_phase_
analytics_recorder.OnStopAdvertising();
// LogSession
analytics_recorder.LogSession();
ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result());
EXPECT_THAT(event_logger.GetLoggedClientSession(), Partially(EqualsProto(R"pb(
strategy_session <
strategy: P2P_STAR
role: ADVERTISER
advertising_phase <
medium: BLUETOOTH
advertising_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
>
>)pb")));
// LogStartSession
CountDownLatch new_start_client_session_done_latch(1);
event_logger.SetStartClientSessionDoneLatchPtr(
&new_start_client_session_done_latch);
analytics_recorder.LogStartSession();
ASSERT_TRUE(
new_start_client_session_done_latch.Await(kDefaultTimeout).result());
// LogSession again
// - if the current_strategy_session_ and current_advertising_phase_ are
// not reset, the same strategy_session with two same advertising_phase will
// be logged.
CountDownLatch new_client_session_done_latch(1);
event_logger.SetClientSessionDoneLatch(new_client_session_done_latch);
analytics_recorder.LogSession();
ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result());
EXPECT_THAT(event_logger.GetLoggedClientSession(),
Not(Partially(EqualsProto(R"pb(
strategy_session <
strategy: P2P_STAR
role: ADVERTISER
advertising_phase <
medium: BLUETOOTH
advertising_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
>
advertising_phase <
medium: BLUETOOTH
advertising_metadata <
supports_extended_ble_advertisements: false
connected_ap_frequency: 0
supports_nfc_technology: false
>
>
>)pb"))));
}
// Test if current_discovery_phase_ is reset.
TEST(AnalyticsRecorderTest,
NotLogDuplicateDiscoveryPhaseAfterSessionWasLogged) {
connections::Strategy strategy = connections::Strategy::kP2pStar;
CountDownLatch client_session_done_latch(1);
FakeEventLogger event_logger(client_session_done_latch);
AnalyticsRecorder analytics_recorder(&event_logger);
analytics_recorder.OnStartDiscovery(
strategy, {BLUETOOTH}, /*is_extended_advertisement_supported=*/true,
/*connected_ap_frequency=*/1,
/*is_nfc_available=*/false); // set current_discovery_phase_
analytics_recorder.OnStopDiscovery();
analytics_recorder.OnEndpointFound(BLUETOOTH);
// LogSession
analytics_recorder.LogSession();
ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result());
EXPECT_THAT(event_logger.GetLoggedClientSession(), Partially(EqualsProto(R"pb(
strategy_session <
strategy: P2P_STAR
role: DISCOVERER
discovery_phase <
medium: BLUETOOTH
discovery_metadata <
supports_extended_ble_advertisements: true
connected_ap_frequency: 1
supports_nfc_technology: false
>
>
>)pb")));
// LogStartSession
CountDownLatch new_start_client_session_done_latch(1);
event_logger.SetStartClientSessionDoneLatchPtr(
&new_start_client_session_done_latch);
analytics_recorder.LogStartSession();
ASSERT_TRUE(
new_start_client_session_done_latch.Await(kDefaultTimeout).result());
// LogSession again
// - if the current_strategy_session_ and current_discovery_phase_ are not
// reset, the same strategy_session with two same discovery_phase will be
// logged.
CountDownLatch new_client_session_done_latch(1);
event_logger.SetClientSessionDoneLatch(new_client_session_done_latch);
analytics_recorder.LogSession();
ASSERT_TRUE(client_session_done_latch.Await(kDefaultTimeout).result());
EXPECT_THAT(event_logger.GetLoggedClientSession(),
Not(Partially(EqualsProto(R"pb(
strategy_session <
strategy: P2P_STAR
role: DISCOVERER
discovery_phase <
medium: BLUETOOTH
discovery_metadata <
supports_extended_ble_advertisements: true
connected_ap_frequency: 1
supports_nfc_technology: false
>
>
discovery_phase <
medium: BLUETOOTH
discovery_metadata <
supports_extended_ble_advertisements: true
connected_ap_frequency: 1
supports_nfc_technology: false
>
>
>)pb"))));
}
} // namespace
} // namespace analytics
} // namespace nearby
+10 -6
View File
@@ -17,10 +17,12 @@
#include <cstdlib>
#include <functional>
#include <limits>
#include <memory>
#include <sstream>
#include <string>
#include <utility>
#include "internal/analytics/event_logger.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/escaping.h"
@@ -104,7 +106,6 @@ void ClientProxy::Reset() {
StoppedDiscovery();
RemoveAllEndpoints();
ExitHighVisibilityMode();
analytics_recorder_->LogSession();
}
void ClientProxy::StartedAdvertising(
@@ -143,7 +144,7 @@ void ClientProxy::StoppedAdvertising() {
analytics_recorder_->OnStopAdvertising();
}
// advertising_options_ is purposefully not cleared here.
ResetLocalEndpointIdIfNeeded();
OnSessionComplete();
ExitHighVisibilityMode();
}
@@ -182,7 +183,7 @@ void ClientProxy::StoppedDiscovery() {
analytics_recorder_->OnStopDiscovery();
}
// discovery_options_ is purposefully not cleared here.
ResetLocalEndpointIdIfNeeded();
OnSessionComplete();
}
bool ClientProxy::IsDiscoveringServiceId(const std::string& service_id) const {
@@ -357,7 +358,7 @@ void ClientProxy::OnDisconnected(const std::string& endpoint_id, bool notify) {
item->connection_listener.disconnected_cb({endpoint_id});
}
connections_.erase(endpoint_id);
ResetLocalEndpointIdIfNeeded();
OnSessionComplete();
}
CancelEndpoint(endpoint_id);
@@ -657,13 +658,16 @@ void ClientProxy::RemoveAllEndpoints() {
// just remove without notifying.
connections_.clear();
cancellation_flags_.clear();
local_endpoint_id_.clear();
OnSessionComplete();
}
void ClientProxy::ResetLocalEndpointIdIfNeeded() {
void ClientProxy::OnSessionComplete() {
MutexLock lock(&mutex_);
if (connections_.empty() && !IsAdvertising() && !IsDiscovering()) {
local_endpoint_id_.clear();
analytics_recorder_->LogSession();
analytics_recorder_->LogStartSession();
}
}
+1 -1
View File
@@ -236,7 +236,7 @@ class ClientProxy final {
};
void RemoveAllEndpoints();
void ResetLocalEndpointIdIfNeeded();
void OnSessionComplete();
bool ConnectionStatusesContains(const std::string& endpoint_id,
Connection::Status status_to_match) const;
void AppendConnectionStatus(const std::string& endpoint_id,
+215 -4
View File
@@ -27,6 +27,7 @@
#include "absl/types/span.h"
#include "connections/listeners.h"
#include "connections/strategy.h"
#include "internal/analytics/event_logger.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/feature_flags.h"
#include "internal/platform/medium_environment.h"
@@ -48,6 +49,13 @@ constexpr FeatureFlags::Flags kTestCases[] = {
},
};
class FakeEventLogger : public ::nearby::analytics::EventLogger {
public:
explicit FakeEventLogger() = default;
void Log(const ::google::protobuf::MessageLite& message) override {}
};
class ClientProxyTest : public ::testing::TestWithParam<FeatureFlags::Flags> {
protected:
struct MockDiscoveryListener {
@@ -107,7 +115,23 @@ class ClientProxyTest : public ::testing::TestWithParam<FeatureFlags::Flags> {
return endpoint;
}
void StopAdvertising(ClientProxy* client) { client->StoppedAdvertising(); }
void StopAdvertising(ClientProxy* client) {
client->StoppedAdvertising();
EXPECT_FALSE(client->IsAdvertising());
}
void OnAdvertisingConnectionInitiated(ClientProxy* client,
const Endpoint& endpoint) {
EXPECT_CALL(mock_advertising_connection_.initiated_cb, Call).Times(1);
const std::string auth_token{"auth_token"};
const ByteArray raw_auth_token{auth_token};
const std::string connection_token{"conntokn"};
discovery_connection_info_.remote_endpoint_info = endpoint.info;
client->OnConnectionInitiated(
endpoint.id, discovery_connection_info_, connection_options_,
advertising_connection_listener_, connection_token);
EXPECT_TRUE(client->HasPendingConnectionToEndpoint(endpoint.id));
}
Endpoint StartDiscovery(ClientProxy* client, DiscoveryListener listener) {
Endpoint endpoint{
@@ -119,6 +143,11 @@ class ClientProxyTest : public ::testing::TestWithParam<FeatureFlags::Flags> {
return endpoint;
}
void StopDiscovery(ClientProxy* client) {
client->StoppedDiscovery();
EXPECT_FALSE(client->IsDiscovering());
}
void OnDiscoveryEndpointFound(ClientProxy* client, const Endpoint& endpoint) {
EXPECT_CALL(mock_discovery_.endpoint_found_cb, Call).Times(1);
client->OnEndpointFound(service_id_, endpoint.id, endpoint.info, medium_);
@@ -214,6 +243,8 @@ class ClientProxyTest : public ::testing::TestWithParam<FeatureFlags::Flags> {
client->OnPayloadProgress(endpoint.id, {});
}
MockConnectionListener mock_advertising_connection_;
MockDiscoveryListener mock_discovery_;
MockConnectionListener mock_discovery_connection_;
MockPayloadListener mock_discovery_payload_;
@@ -224,8 +255,10 @@ class ClientProxyTest : public ::testing::TestWithParam<FeatureFlags::Flags> {
};
Strategy strategy_{Strategy::kP2pPointToPoint};
const std::string service_id_{"service"};
ClientProxy client1_;
ClientProxy client2_;
FakeEventLogger event_logger1_;
FakeEventLogger event_logger2_;
ClientProxy client1_{&event_logger1_};
ClientProxy client2_{&event_logger2_};
std::string auth_token_ = "auth_token";
ByteArray raw_auth_token_ = ByteArray(auth_token_);
ByteArray payload_bytes_{"bytes"};
@@ -234,7 +267,14 @@ class ClientProxyTest : public ::testing::TestWithParam<FeatureFlags::Flags> {
.raw_authentication_token = raw_auth_token_,
.is_incoming_connection = true,
};
ConnectionListener advertising_connection_listener_;
ConnectionListener advertising_connection_listener_{
.initiated_cb = mock_advertising_connection_.initiated_cb.AsStdFunction(),
};
ConnectionResponseInfo discovery_connection_info_{
.authentication_token = auth_token_,
.raw_authentication_token = raw_auth_token_,
.is_incoming_connection = false,
};
ConnectionListener discovery_connection_listener_{
.initiated_cb = mock_discovery_connection_.initiated_cb.AsStdFunction(),
.accepted_cb = mock_discovery_connection_.accepted_cb.AsStdFunction(),
@@ -686,6 +726,177 @@ TEST_F(ClientProxyTest, EndpointIdRotateWhenLowVizAdvertisementWithLowPower) {
EXPECT_NE(advertising_endpoint_1.id, advertising_endpoint_2.id);
}
TEST_F(ClientProxyTest, NotLogSessionForStoppedAdvertisingWithConnection) {
Endpoint advertising_endpoint =
StartAdvertising(&client1_, advertising_connection_listener_);
OnAdvertisingConnectionInitiated(&client1_, advertising_endpoint);
StartDiscovery(&client2_, discovery_listener_);
OnDiscoveryEndpointFound(&client2_, advertising_endpoint);
OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint);
// Before
EXPECT_TRUE(client1_.HasPendingConnectionToEndpoint(
advertising_endpoint.id)); // Connections are available
EXPECT_FALSE(client1_.IsDiscovering()); // No Discovery
EXPECT_TRUE(client1_.IsAdvertising()); // Advertising
EXPECT_FALSE(client1_.GetAnalyticsRecorder().IsSessionLogged());
// After
StopAdvertising(&client1_); // No Advertising
EXPECT_FALSE(client1_.GetAnalyticsRecorder().IsSessionLogged());
}
TEST_F(ClientProxyTest,
LogSessionForStoppedAdvertisingWhenNoConnectionsAndNoDiscovering) {
Endpoint advertising_endpoint =
StartAdvertising(&client1_, advertising_connection_listener_);
// Before
EXPECT_FALSE(client1_.HasPendingConnectionToEndpoint(
advertising_endpoint.id)); // No Connections
EXPECT_FALSE(client1_.IsDiscovering()); // No Discovery
EXPECT_TRUE(client1_.IsAdvertising()); // Advertising
EXPECT_FALSE(client1_.GetAnalyticsRecorder().IsSessionLogged());
// After
StopAdvertising(&client1_);
EXPECT_TRUE(client1_.GetAnalyticsRecorder().IsSessionLogged());
}
TEST_F(ClientProxyTest, NotLogSessionForStoppedDiscoveryWithConnection) {
Endpoint advertising_endpoint =
StartAdvertising(&client1_, advertising_connection_listener_);
StartDiscovery(&client2_, discovery_listener_);
OnDiscoveryEndpointFound(&client2_, advertising_endpoint);
// Before
OnDiscoveryConnectionInitiated(
&client2_, advertising_endpoint); // Connections are available
EXPECT_FALSE(client2_.IsAdvertising()); // No Advertising
EXPECT_TRUE(client2_.IsDiscovering()); // Discovering
EXPECT_FALSE(client2_.GetAnalyticsRecorder().IsSessionLogged());
// After
StopDiscovery(&client2_);
EXPECT_FALSE(client2_.GetAnalyticsRecorder().IsSessionLogged());
}
TEST_F(ClientProxyTest,
NotLogSessionForStoppedDiscoveryWithoutConnectionsAndAdvertising) {
Endpoint advertising_endpoint =
StartAdvertising(&client1_, advertising_connection_listener_);
StartDiscovery(&client2_, discovery_listener_);
// Before
EXPECT_FALSE(client2_.IsAdvertising()); // No Advertising
EXPECT_TRUE(client2_.IsDiscovering()); // Discoverying
EXPECT_FALSE(client2_.HasPendingConnectionToEndpoint(
advertising_endpoint.id)); // No Connections
// After
StopDiscovery(&client2_);
EXPECT_TRUE(client2_.GetAnalyticsRecorder().IsSessionLogged());
}
TEST_F(ClientProxyTest, LogSessionOnDisconnectedWithOneConnection) {
Endpoint advertising_endpoint =
StartAdvertising(&client1_, advertising_connection_listener_);
StartDiscovery(&client2_, discovery_listener_);
OnDiscoveryEndpointFound(&client2_, advertising_endpoint);
OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint);
// Before
EXPECT_FALSE(client2_.IsAdvertising()); // No Advertising
StopDiscovery(&client2_); // No Discovery
EXPECT_TRUE(client2_.HasPendingConnectionToEndpoint(
advertising_endpoint.id)); // One Connection
// After
OnDiscoveryConnectionDisconnected(&client2_, advertising_endpoint);
EXPECT_TRUE(client2_.GetAnalyticsRecorder().IsSessionLogged());
}
TEST_F(ClientProxyTest,
NotLogSessionOnDisconnectedWithoutConnectionsDiscoveringAdvertising) {
Endpoint advertising_endpoint =
StartAdvertising(&client1_, advertising_connection_listener_);
// Before
EXPECT_FALSE(client2_.IsAdvertising()); // No Advertising
EXPECT_FALSE(client2_.IsDiscovering()); // No Discovery
EXPECT_FALSE(client2_.HasPendingConnectionToEndpoint(
advertising_endpoint.id)); // No Connections
// After
client2_.OnDisconnected(advertising_endpoint.id, /*notify=*/false);
EXPECT_FALSE(client2_.GetAnalyticsRecorder().IsSessionLogged());
}
TEST_F(ClientProxyTest, NotLogSessionOnDisconnectedWhenMoreThanOneConnection) {
ClientProxy client3;
Endpoint advertising_endpoint_1 =
StartAdvertising(&client1_, advertising_connection_listener_);
Endpoint advertising_endpoint_2 =
StartAdvertising(&client2_, advertising_connection_listener_);
StartDiscovery(&client3, discovery_listener_);
OnDiscoveryEndpointFound(&client3, advertising_endpoint_1);
OnDiscoveryConnectionInitiated(&client3, advertising_endpoint_1);
OnDiscoveryEndpointFound(&client3, advertising_endpoint_2);
OnDiscoveryConnectionInitiated(&client3, advertising_endpoint_2);
// Before
// - More than one Connection
EXPECT_TRUE(
client3.HasPendingConnectionToEndpoint(advertising_endpoint_1.id));
EXPECT_TRUE(
client3.HasPendingConnectionToEndpoint(advertising_endpoint_2.id));
EXPECT_FALSE(client3.IsAdvertising()); // No Advertising
StopDiscovery(&client3); // No Discovery
// After
client2_.OnDisconnected(advertising_endpoint_1.id, /*notify=*/false);
EXPECT_FALSE(client2_.GetAnalyticsRecorder().IsSessionLogged());
}
TEST_F(ClientProxyTest,
NotLogSessionOnDisconnectedForDiscoveringWithOnlyOneConnection) {
Endpoint advertising_endpoint =
StartAdvertising(&client1_, advertising_connection_listener_);
StartDiscovery(&client2_, discovery_listener_);
OnDiscoveryEndpointFound(&client2_, advertising_endpoint);
OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint);
// Before
EXPECT_FALSE(client2_.IsAdvertising()); // No Advertising
EXPECT_TRUE(client2_.IsDiscovering()); // Discovering
EXPECT_TRUE(client2_.HasPendingConnectionToEndpoint(
advertising_endpoint.id)); // One Connection
// After
OnDiscoveryConnectionDisconnected(&client2_, advertising_endpoint);
EXPECT_FALSE(client2_.GetAnalyticsRecorder().IsSessionLogged());
}
TEST_F(ClientProxyTest, LogSessionForResetClientProxy) {
Endpoint advertising_endpoint =
StartAdvertising(&client1_, advertising_connection_listener_);
StartDiscovery(&client2_, discovery_listener_);
OnDiscoveryEndpointFound(&client2_, advertising_endpoint);
OnDiscoveryConnectionInitiated(&client2_, advertising_endpoint);
EXPECT_FALSE(client1_.GetAnalyticsRecorder().IsSessionLogged());
client1_.Reset();
EXPECT_TRUE(client1_.GetAnalyticsRecorder().IsSessionLogged());
EXPECT_FALSE(client2_.GetAnalyticsRecorder().IsSessionLogged());
client2_.Reset();
EXPECT_TRUE(client2_.GetAnalyticsRecorder().IsSessionLogged());
}
} // namespace
} // namespace connections
} // namespace nearby