blob: 1a64d90cc4382b428b4c676a8bab640b7c39db01 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/components/tether/ble_connection_metrics_logger.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/default_clock.h"
#include "chromeos/components/proximity_auth/logging/logging.h"
namespace chromeos {
namespace tether {
BleConnectionMetricsLogger::BleConnectionMetricsLogger()
: clock_(base::DefaultClock::GetInstance()) {}
BleConnectionMetricsLogger::~BleConnectionMetricsLogger() = default;
void BleConnectionMetricsLogger::OnConnectionAttemptStarted(
const std::string& device_id) {
device_id_to_started_scan_time_map_[device_id] = clock_->Now();
}
void BleConnectionMetricsLogger::OnAdvertisementReceived(
const std::string& device_id,
bool is_background_advertisement) {
device_id_to_received_advertisement_time_map_[device_id] = clock_->Now();
RecordStartScanToReceiveAdvertisementDuration(device_id,
is_background_advertisement);
}
void BleConnectionMetricsLogger::OnConnection(
const std::string& device_id,
bool is_background_advertisement) {
device_id_to_status_connected_time_map_[device_id] = clock_->Now();
RecordStartScanToConnectionDuration(device_id, is_background_advertisement);
}
void BleConnectionMetricsLogger::OnSecureChannelCreated(
const std::string& device_id,
bool is_background_advertisement) {
RecordConnectionToAuthenticationDuration(device_id,
is_background_advertisement);
RecordGattConnectionAttemptSuccessRate(true /* success */,
is_background_advertisement);
device_id_to_status_authenticated_map_[device_id] = true;
}
void BleConnectionMetricsLogger::OnDeviceDisconnected(
const std::string& device_id,
BleConnectionManager::StateChangeDetail state_change_detail,
bool is_background_advertisement) {
if (state_change_detail ==
BleConnectionManager::StateChangeDetail::
STATE_CHANGE_DETAIL_GATT_CONNECTION_WAS_ATTEMPTED) {
RecordGattConnectionAttemptSuccessRate(false /* success */,
is_background_advertisement);
} else if (state_change_detail ==
BleConnectionManager::StateChangeDetail::
STATE_CHANGE_DETAIL_DEVICE_WAS_UNREGISTERED) {
bool did_device_disconnect_after_success =
base::ContainsKey(device_id_to_status_authenticated_map_, device_id) &&
device_id_to_status_authenticated_map_[device_id];
RecordGattConnectionAttemptEffectiveSuccessRateWithRetries(
did_device_disconnect_after_success /* success */,
is_background_advertisement);
}
device_id_to_started_scan_time_map_.erase(device_id);
device_id_to_received_advertisement_time_map_.erase(device_id);
device_id_to_status_connected_time_map_.erase(device_id);
device_id_to_status_authenticated_map_.erase(device_id);
}
void BleConnectionMetricsLogger::RecordStartScanToReceiveAdvertisementDuration(
const std::string device_id,
bool is_background_advertisement) {
if (!base::ContainsKey(device_id_to_started_scan_time_map_, device_id) ||
!base::ContainsKey(device_id_to_received_advertisement_time_map_,
device_id)) {
PA_LOG(ERROR) << "Failed to record start scan to advertisement duration: "
<< "times are invalid";
NOTREACHED();
return;
}
base::TimeDelta start_scan_to_received_advertisment_duration =
device_id_to_received_advertisement_time_map_[device_id] -
device_id_to_started_scan_time_map_[device_id];
if (is_background_advertisement) {
UMA_HISTOGRAM_TIMES(
"InstantTethering.Performance.StartScanToReceiveAdvertisementDuration."
"Background",
start_scan_to_received_advertisment_duration);
} else {
UMA_HISTOGRAM_TIMES(
"InstantTethering.Performance.StartScanToReceiveAdvertisementDuration",
start_scan_to_received_advertisment_duration);
}
}
void BleConnectionMetricsLogger::RecordStartScanToConnectionDuration(
const std::string device_id,
bool is_background_advertisement) {
if (!base::ContainsKey(device_id_to_started_scan_time_map_, device_id) ||
!base::ContainsKey(device_id_to_received_advertisement_time_map_,
device_id) ||
!base::ContainsKey(device_id_to_status_connected_time_map_, device_id)) {
PA_LOG(ERROR) << "Failed to record start scan to connection duration: "
<< "times are invalid";
NOTREACHED();
return;
}
base::TimeDelta received_advertisment_to_connection_duration =
device_id_to_status_connected_time_map_[device_id] -
device_id_to_received_advertisement_time_map_[device_id];
base::TimeDelta start_scan_to_connection_duration =
device_id_to_status_connected_time_map_[device_id] -
device_id_to_started_scan_time_map_[device_id];
if (is_background_advertisement) {
UMA_HISTOGRAM_MEDIUM_TIMES(
"InstantTethering.Performance.ReceiveAdvertisementToConnectionDuration."
"Background",
received_advertisment_to_connection_duration);
UMA_HISTOGRAM_MEDIUM_TIMES(
"InstantTethering.Performance.StartScanToConnectionDuration.Background",
start_scan_to_connection_duration);
} else {
UMA_HISTOGRAM_MEDIUM_TIMES(
"InstantTethering.Performance.ReceiveAdvertisementToConnectionDuration",
received_advertisment_to_connection_duration);
UMA_HISTOGRAM_MEDIUM_TIMES(
"InstantTethering.Performance.AdvertisementToConnectionDuration",
start_scan_to_connection_duration);
}
device_id_to_started_scan_time_map_.erase(device_id);
device_id_to_received_advertisement_time_map_.erase(device_id);
}
void BleConnectionMetricsLogger::RecordConnectionToAuthenticationDuration(
const std::string device_id,
bool is_background_advertisement) {
if (!base::ContainsKey(device_id_to_status_connected_time_map_, device_id)) {
PA_LOG(ERROR) << "Failed to record connection to authentication duration: "
<< "connection start time is invalid";
NOTREACHED();
return;
}
base::TimeDelta connection_to_authentication_duration =
clock_->Now() - device_id_to_status_connected_time_map_[device_id];
if (is_background_advertisement) {
UMA_HISTOGRAM_TIMES(
"InstantTethering.Performance.ConnectionToAuthenticationDuration."
"Background",
connection_to_authentication_duration);
} else {
UMA_HISTOGRAM_TIMES(
"InstantTethering.Performance.ConnectionToAuthenticationDuration",
connection_to_authentication_duration);
}
device_id_to_status_connected_time_map_.erase(device_id);
}
void BleConnectionMetricsLogger::RecordGattConnectionAttemptSuccessRate(
bool success,
bool is_background_advertisement) {
if (is_background_advertisement) {
UMA_HISTOGRAM_BOOLEAN(
"InstantTethering.GattConnectionAttempt.SuccessRate.Background",
success);
} else {
UMA_HISTOGRAM_BOOLEAN("InstantTethering.GattConnectionAttempt.SuccessRate",
success);
}
}
void BleConnectionMetricsLogger::
RecordGattConnectionAttemptEffectiveSuccessRateWithRetries(
bool success,
bool is_background_advertisement) {
if (is_background_advertisement) {
UMA_HISTOGRAM_BOOLEAN(
"InstantTethering.GattConnectionAttempt."
"EffectiveSuccessRateWithRetries.Background",
success);
} else {
UMA_HISTOGRAM_BOOLEAN(
"InstantTethering.GattConnectionAttempt."
"EffectiveSuccessRateWithRetries",
success);
}
}
void BleConnectionMetricsLogger::SetClockForTesting(base::Clock* test_clock) {
clock_ = test_clock;
}
} // namespace tether
} // namespace chromeos