summaryrefslogtreecommitdiff
path: root/chromium/third_party/nearby/src/internal/analytics/analytics_recorder.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/nearby/src/internal/analytics/analytics_recorder.h')
-rw-r--r--chromium/third_party/nearby/src/internal/analytics/analytics_recorder.h369
1 files changed, 369 insertions, 0 deletions
diff --git a/chromium/third_party/nearby/src/internal/analytics/analytics_recorder.h b/chromium/third_party/nearby/src/internal/analytics/analytics_recorder.h
new file mode 100644
index 00000000000..866574c0c51
--- /dev/null
+++ b/chromium/third_party/nearby/src/internal/analytics/analytics_recorder.h
@@ -0,0 +1,369 @@
+// Copyright 2020 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 ANALYTICS_ANALYTICS_RECORDER_H_
+#define ANALYTICS_ANALYTICS_RECORDER_H_
+
+#include <string>
+
+#include "absl/container/btree_map.h"
+#include "absl/time/time.h"
+#include "connections/event_logger.h"
+#include "connections/payload.h"
+#include "connections/strategy.h"
+#include "internal/platform/error_code_params.h"
+#include "internal/platform/mutex.h"
+#include "internal/platform/single_thread_executor.h"
+#include "internal/analytics/connection_attempt_metadata_params.h"
+#include "internal/proto/analytics/connections_log.pb.h"
+#include "proto/connections_enums.pb.h"
+
+namespace location {
+namespace nearby {
+namespace analytics {
+
+class AnalyticsRecorder {
+ public:
+ explicit AnalyticsRecorder(EventLogger *event_logger);
+ virtual ~AnalyticsRecorder();
+
+ // TODO(edwinwu): Implement to pass real values for AdvertisingMetadata and
+ // DiscoveryMetaData: is_extended_advertisement_supported,
+ // connected_ap_frequency, and is_nfc_available. Set as default values for
+ // analytics recorder.
+ // Advertising phase
+ void OnStartAdvertising(
+ connections::Strategy strategy,
+ const std::vector<location::nearby::proto::connections::Medium> &mediums,
+ bool is_extended_advertisement_supported = false,
+ int connected_ap_frequency = 0, bool is_nfc_available = false)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnStopAdvertising() ABSL_LOCKS_EXCLUDED(mutex_);
+
+ // Discovery phase
+ void OnStartDiscovery(
+ connections::Strategy strategy,
+ const std::vector<location::nearby::proto::connections::Medium> &mediums,
+ bool is_extended_advertisement_supported = false,
+ int connected_ap_frequency = 0, bool is_nfc_available = false)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnStopDiscovery() ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnEndpointFound(location::nearby::proto::connections::Medium medium)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+
+ // Connection request
+ void OnConnectionRequestReceived(const std::string &remote_endpoint_id)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnConnectionRequestSent(const std::string &remote_endpoint_id)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnRemoteEndpointAccepted(const std::string &remote_endpoint_id)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnLocalEndpointAccepted(const std::string &remote_endpoint_id)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnRemoteEndpointRejected(const std::string &remote_endpoint_id)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnLocalEndpointRejected(const std::string &remote_endpoint_id)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+
+ // Connection attempt
+ void OnIncomingConnectionAttempt(
+ location::nearby::proto::connections::ConnectionAttemptType type,
+ location::nearby::proto::connections::Medium medium,
+ location::nearby::proto::connections::ConnectionAttemptResult result,
+ absl::Duration duration, const std::string &connection_token,
+ ConnectionAttemptMetadataParams *connection_attempt_metadata_params)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnOutgoingConnectionAttempt(
+ const std::string &remote_endpoint_id,
+ location::nearby::proto::connections::ConnectionAttemptType type,
+ location::nearby::proto::connections::Medium medium,
+ location::nearby::proto::connections::ConnectionAttemptResult result,
+ absl::Duration duration, const std::string &connection_token,
+ ConnectionAttemptMetadataParams *connection_attempt_metadata_params)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+ // TODO(edwinwu): Implement network operator, country code, tdls, wifi hotspot
+ //, max wifi tx/rx speed and channel width. Set as default values for
+ // analytics recorder.
+ static std::unique_ptr<ConnectionAttemptMetadataParams>
+ BuildConnectionAttemptMetadataParams(
+ location::nearby::proto::connections::ConnectionTechnology technology,
+ location::nearby::proto::connections::ConnectionBand band, int frequency,
+ int try_count, const std::string &network_operator = {},
+ const std::string &country_code = {}, bool is_tdls_used = false,
+ bool wifi_hotspot_enabled = false, int max_wifi_tx_speed = 0,
+ int max_wifi_rx_speed = 0, int channel_width = -1);
+
+ // Connection established
+ void OnConnectionEstablished(
+ const std::string &endpoint_id,
+ location::nearby::proto::connections::Medium medium,
+ const std::string &connection_token) ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnConnectionClosed(
+ const std::string &endpoint_id,
+ location::nearby::proto::connections::Medium medium,
+ location::nearby::proto::connections ::DisconnectionReason reason)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+
+ // Payload
+ void OnIncomingPayloadStarted(const std::string &endpoint_id,
+ std::int64_t payload_id,
+ connections::Payload::Type type,
+ std::int64_t total_size_bytes)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnPayloadChunkReceived(const std::string &endpoint_id,
+ std::int64_t payload_id,
+ std::int64_t chunk_size_bytes)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnIncomingPayloadDone(
+ const std::string &endpoint_id, std::int64_t payload_id,
+ location::nearby::proto::connections::PayloadStatus status)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnOutgoingPayloadStarted(const std::vector<std::string> &endpoint_ids,
+ std::int64_t payload_id,
+ connections::Payload::Type type,
+ std::int64_t total_size_bytes)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnPayloadChunkSent(const std::string &endpoint_id,
+ std::int64_t payload_id,
+ std::int64_t chunk_size_bytes)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnOutgoingPayloadDone(
+ const std::string &endpoint_id, std::int64_t payload_id,
+ location::nearby::proto::connections::PayloadStatus status)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+
+ // BandwidthUpgrade
+ void OnBandwidthUpgradeStarted(
+ const std::string &endpoint_id,
+ location::nearby::proto::connections::Medium from_medium,
+ location::nearby::proto::connections::Medium to_medium,
+ location::nearby::proto::connections::ConnectionAttemptDirection
+ direction,
+ const std::string &connection_token) ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnBandwidthUpgradeError(
+ const std::string &endpoint_id,
+ location::nearby::proto::connections::BandwidthUpgradeResult result,
+ location::nearby::proto::connections::BandwidthUpgradeErrorStage
+ error_stage) ABSL_LOCKS_EXCLUDED(mutex_);
+ void OnBandwidthUpgradeSuccess(const std::string &endpoint_id)
+ ABSL_LOCKS_EXCLUDED(mutex_);
+
+ // Error Code
+ void OnErrorCode(const ErrorCodeParams &params);
+
+ // 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_);
+
+ private:
+ // Tracks the chunks and duration of a Payload on a particular medium.
+ class PendingPayload {
+ public:
+ PendingPayload(location::nearby::proto::connections::PayloadType type,
+ std::int64_t total_size_bytes)
+ : start_time_(SystemClock::ElapsedRealtime()),
+ type_(type),
+ total_size_bytes_(total_size_bytes),
+ num_bytes_transferred_(0),
+ num_chunks_(0) {}
+ ~PendingPayload() = default;
+
+ void AddChunk(std::int64_t chunk_size_bytes);
+
+ proto::ConnectionsLog::Payload GetProtoPayload(
+ location::nearby::proto::connections::PayloadStatus status);
+
+ location::nearby::proto::connections::PayloadType type() const {
+ return type_;
+ }
+
+ std::int64_t total_size_bytes() const { return total_size_bytes_; }
+
+ private:
+ absl::Time start_time_;
+ location::nearby::proto::connections::PayloadType type_;
+ std::int64_t total_size_bytes_;
+ std::int64_t num_bytes_transferred_;
+ int num_chunks_;
+ };
+
+ class LogicalConnection {
+ public:
+ LogicalConnection(
+ location::nearby::proto::connections::Medium initial_medium,
+ const std::string &connection_token) {
+ PhysicalConnectionEstablished(initial_medium, connection_token);
+ }
+ LogicalConnection(const LogicalConnection &) = delete;
+ LogicalConnection(LogicalConnection &&other)
+ : current_medium_(std::move(other.current_medium_)),
+ physical_connections_(std::move(other.physical_connections_)),
+ incoming_payloads_(std::move(other.incoming_payloads_)),
+ outgoing_payloads_(std::move(other.outgoing_payloads_)) {}
+ LogicalConnection &operator=(const LogicalConnection &) = delete;
+ LogicalConnection &&operator=(LogicalConnection &&) = delete;
+ ~LogicalConnection() = default;
+
+ void PhysicalConnectionEstablished(
+ location::nearby::proto::connections::Medium medium,
+ const std::string &connection_token);
+ void PhysicalConnectionClosed(
+ location::nearby::proto::connections::Medium medium,
+ location::nearby::proto::connections::DisconnectionReason reason);
+ void CloseAllPhysicalConnections();
+
+ void IncomingPayloadStarted(
+ std::int64_t payload_id,
+ location::nearby::proto::connections::PayloadType type,
+ std::int64_t total_size_bytes);
+ void ChunkReceived(std::int64_t payload_id, std::int64_t size_bytes);
+ void IncomingPayloadDone(
+ std::int64_t payload_id,
+ location::nearby::proto::connections::PayloadStatus status);
+ void OutgoingPayloadStarted(
+ std::int64_t payload_id,
+ location::nearby::proto::connections::PayloadType type,
+ std::int64_t total_size_bytes);
+ void ChunkSent(std::int64_t payload_id, std::int64_t size_bytes);
+ void OutgoingPayloadDone(
+ std::int64_t payload_id,
+ location::nearby::proto::connections::PayloadStatus status);
+
+ std::vector<proto::ConnectionsLog::EstablishedConnection>
+ GetEstablisedConnections();
+
+ private:
+ void FinishPhysicalConnection(
+ proto::ConnectionsLog::EstablishedConnection *established_connection,
+ location::nearby::proto::connections::DisconnectionReason reason);
+ std::vector<proto::ConnectionsLog::Payload> ResolvePendingPayloads(
+ absl::btree_map<std::int64_t, std::unique_ptr<PendingPayload>>
+ &pending_payloads,
+ location::nearby::proto::connections::DisconnectionReason reason);
+
+ location::nearby::proto::connections::Medium current_medium_ =
+ location::nearby::proto::connections::UNKNOWN_MEDIUM;
+ absl::btree_map<
+ location::nearby::proto::connections::Medium,
+ std::unique_ptr<proto::ConnectionsLog::EstablishedConnection>>
+ physical_connections_;
+ absl::btree_map<std::int64_t, std::unique_ptr<PendingPayload>>
+ incoming_payloads_;
+ absl::btree_map<std::int64_t, std::unique_ptr<PendingPayload>>
+ outgoing_payloads_;
+ };
+
+ bool CanRecordAnalyticsLocked(const std::string &method_name)
+ ABSL_SHARED_LOCKS_REQUIRED(mutex_);
+
+ // Callbacks the ConnectionsLog proto byte array data to the EventLogger with
+ // ClientSession sub-proto.
+ void LogClientSession();
+ // Callbacks the ConnectionsLog proto byte array data to the EventLogger.
+ void LogEvent(location::nearby::proto::connections::EventType event_type);
+
+ void UpdateStrategySessionLocked(
+ connections::Strategy strategy,
+ location::nearby::proto::connections::SessionRole role)
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+ void RecordAdvertisingPhaseDurationLocked() const
+ ABSL_SHARED_LOCKS_REQUIRED(mutex_);
+ void FinishAdvertisingPhaseLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+ void RecordDiscoveryPhaseDurationLocked() const
+ ABSL_SHARED_LOCKS_REQUIRED(mutex_);
+ void FinishDiscoveryPhaseLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+ bool UpdateAdvertiserConnectionRequestLocked(
+ proto::ConnectionsLog::ConnectionRequest *request)
+ ABSL_SHARED_LOCKS_REQUIRED(mutex_);
+ bool UpdateDiscovererConnectionRequestLocked(
+ proto::ConnectionsLog::ConnectionRequest *request)
+ ABSL_SHARED_LOCKS_REQUIRED(mutex_);
+ bool BothEndpointsRespondedLocked(
+ proto::ConnectionsLog::ConnectionRequest *request)
+ ABSL_SHARED_LOCKS_REQUIRED(mutex_);
+ void LocalEndpointRespondedLocked(
+ const std::string &remote_endpoint_id,
+ location::nearby::proto::connections::ConnectionRequestResponse response)
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+ void RemoteEndpointRespondedLocked(
+ const std::string &remote_endpoint_id,
+ location::nearby::proto::connections::ConnectionRequestResponse response)
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+ void MarkConnectionRequestIgnoredLocked(
+ proto::ConnectionsLog::ConnectionRequest *request)
+ ABSL_SHARED_LOCKS_REQUIRED(mutex_);
+ void FinishUpgradeAttemptLocked(
+ const std::string &endpoint_id,
+ location::nearby::proto::connections::BandwidthUpgradeResult result,
+ location::nearby::proto::connections::BandwidthUpgradeErrorStage
+ error_stage,
+ bool erase_item = true) ABSL_SHARED_LOCKS_REQUIRED(mutex_);
+ void FinishStrategySessionLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+
+ location::nearby::proto::connections::ConnectionsStrategy
+ StrategyToConnectionStrategy(connections::Strategy strategy);
+ location::nearby::proto::connections::PayloadType
+ PayloadTypeToProtoPayloadType(connections::Payload::Type type);
+
+ // Not owned by AnalyticsRecorder. Pointer must refer to a valid object
+ // that outlives the one constructed.
+ EventLogger *event_logger_;
+
+ SingleThreadExecutor serial_executor_;
+ // Protects all sub-protos reading and writing in ConnectionLog.
+ Mutex mutex_;
+
+ // ClientSession
+ std::unique_ptr<proto::ConnectionsLog::ClientSession> client_session_ =
+ absl::make_unique<proto::ConnectionsLog::ClientSession>();
+ absl::Time started_client_session_time_;
+ bool session_was_logged_ ABSL_GUARDED_BY(mutex_) = false;
+
+ // Current StrategySession
+ connections::Strategy current_strategy_ ABSL_GUARDED_BY(mutex_) =
+ connections::Strategy::kNone;
+ std::unique_ptr<proto::ConnectionsLog::StrategySession>
+ current_strategy_session_ ABSL_GUARDED_BY(mutex_);
+ absl::Time started_strategy_session_time_ ABSL_GUARDED_BY(mutex_);
+
+ // Current AdvertisingPhase
+ std::unique_ptr<proto::ConnectionsLog::AdvertisingPhase>
+ current_advertising_phase_;
+ absl::Time started_advertising_phase_time_;
+
+ // Current DiscoveryPhase
+ std::unique_ptr<proto::ConnectionsLog::DiscoveryPhase>
+ current_discovery_phase_;
+ absl::Time started_discovery_phase_time_;
+
+ absl::btree_map<std::string,
+ std::unique_ptr<proto::ConnectionsLog::ConnectionRequest>>
+ incoming_connection_requests_ ABSL_GUARDED_BY(mutex_);
+ absl::btree_map<std::string,
+ std::unique_ptr<proto::ConnectionsLog::ConnectionRequest>>
+ outgoing_connection_requests_ ABSL_GUARDED_BY(mutex_);
+ absl::btree_map<std::string, std::unique_ptr<LogicalConnection>>
+ active_connections_ ABSL_GUARDED_BY(mutex_);
+ absl::btree_map<
+ std::string,
+ std::unique_ptr<proto::ConnectionsLog::BandwidthUpgradeAttempt>>
+ bandwidth_upgrade_attempts_ ABSL_GUARDED_BY(mutex_);
+};
+
+} // namespace analytics
+} // namespace nearby
+} // namespace location
+
+#endif // ANALYTICS_ANALYTICS_RECORDER_H_