Commit eef344fe authored by Ryan Hansberry's avatar Ryan Hansberry Committed by Commit Bot

Add metrics for various Bluetooth operations.

Adds metrics around advertisement registration/unregistration,
scanning, creating a GATT connection, and the StartNotify operation.

These metrics are being created in addition to existing similar
Bluetooth metrics in order to gauge Tether's stability as a client
versus Bluetooth as a whole.

Bug: 
Change-Id: Idf719394e4193591230cc765d48a8ceb0a0f4b88
Reviewed-on: https://chromium-review.googlesource.com/701373Reviewed-by: default avatarTim Song <tengs@chromium.org>
Reviewed-by: default avatarSteven Holte <holte@chromium.org>
Reviewed-by: default avatarJeremy Klein <jlklein@chromium.org>
Commit-Queue: Ryan Hansberry <hansberry@chromium.org>
Cr-Commit-Position: refs/heads/master@{#506784}
parent b352cae4
......@@ -5,6 +5,7 @@
#include "chromeos/components/tether/ble_synchronizer.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/default_clock.h"
#include "components/proximity_auth/logging/logging.h"
......@@ -137,6 +138,8 @@ void BleSynchronizer::SetTestDoubles(
void BleSynchronizer::OnAdvertisementRegistered(
scoped_refptr<device::BluetoothAdvertisement> advertisement) {
RecordBluetoothAdvertisementRegistrationResult(
BluetoothAdvertisementResult::SUCCESS);
ScheduleCommandCompletion();
RegisterArgs* register_args = current_command_->register_args.get();
DCHECK(register_args);
......@@ -145,6 +148,8 @@ void BleSynchronizer::OnAdvertisementRegistered(
void BleSynchronizer::OnErrorRegisteringAdvertisement(
device::BluetoothAdvertisement::ErrorCode error_code) {
RecordBluetoothAdvertisementRegistrationResult(
BluetoothAdvertisementErrorCodeToResult(error_code));
ScheduleCommandCompletion();
RegisterArgs* register_args = current_command_->register_args.get();
DCHECK(register_args);
......@@ -152,6 +157,8 @@ void BleSynchronizer::OnErrorRegisteringAdvertisement(
}
void BleSynchronizer::OnAdvertisementUnregistered() {
RecordBluetoothAdvertisementUnregistrationResult(
BluetoothAdvertisementResult::SUCCESS);
ScheduleCommandCompletion();
UnregisterArgs* unregister_args = current_command_->unregister_args.get();
DCHECK(unregister_args);
......@@ -160,6 +167,8 @@ void BleSynchronizer::OnAdvertisementUnregistered() {
void BleSynchronizer::OnErrorUnregisteringAdvertisement(
device::BluetoothAdvertisement::ErrorCode error_code) {
RecordBluetoothAdvertisementUnregistrationResult(
BluetoothAdvertisementErrorCodeToResult(error_code));
ScheduleCommandCompletion();
UnregisterArgs* unregister_args = current_command_->unregister_args.get();
DCHECK(unregister_args);
......@@ -168,6 +177,7 @@ void BleSynchronizer::OnErrorUnregisteringAdvertisement(
void BleSynchronizer::OnDiscoverySessionStarted(
std::unique_ptr<device::BluetoothDiscoverySession> discovery_session) {
RecordDiscoverySessionStarted(true);
ScheduleCommandCompletion();
StartDiscoveryArgs* start_discovery_args =
current_command_->start_discovery_args.get();
......@@ -176,6 +186,7 @@ void BleSynchronizer::OnDiscoverySessionStarted(
}
void BleSynchronizer::OnErrorStartingDiscoverySession() {
RecordDiscoverySessionStarted(false);
ScheduleCommandCompletion();
StartDiscoveryArgs* start_discovery_args =
current_command_->start_discovery_args.get();
......@@ -217,6 +228,55 @@ void BleSynchronizer::CompleteCurrentCommand() {
ProcessQueue();
}
void BleSynchronizer::RecordBluetoothAdvertisementRegistrationResult(
BluetoothAdvertisementResult result) {
UMA_HISTOGRAM_ENUMERATION(
"InstantTethering.BluetoothAdvertisementRegistrationResult", result,
BluetoothAdvertisementResult::BLUETOOTH_ADVERTISEMENT_RESULT_MAX);
}
void BleSynchronizer::RecordBluetoothAdvertisementUnregistrationResult(
BluetoothAdvertisementResult result) {
UMA_HISTOGRAM_ENUMERATION(
"InstantTethering.BluetoothAdvertisementUnregistrationResult", result,
BluetoothAdvertisementResult::BLUETOOTH_ADVERTISEMENT_RESULT_MAX);
}
BleSynchronizer::BluetoothAdvertisementResult
BleSynchronizer::BluetoothAdvertisementErrorCodeToResult(
device::BluetoothAdvertisement::ErrorCode error_code) {
switch (error_code) {
case device::BluetoothAdvertisement::ErrorCode::ERROR_UNSUPPORTED_PLATFORM:
return BluetoothAdvertisementResult::ERROR_UNSUPPORTED_PLATFORM;
case device::BluetoothAdvertisement::ErrorCode::
ERROR_ADVERTISEMENT_ALREADY_EXISTS:
return BluetoothAdvertisementResult::ERROR_ADVERTISEMENT_ALREADY_EXISTS;
case device::BluetoothAdvertisement::ErrorCode::
ERROR_ADVERTISEMENT_DOES_NOT_EXIST:
return BluetoothAdvertisementResult::ERROR_ADVERTISEMENT_DOES_NOT_EXIST;
case device::BluetoothAdvertisement::ErrorCode::
ERROR_ADVERTISEMENT_INVALID_LENGTH:
return BluetoothAdvertisementResult::ERROR_ADVERTISEMENT_INVALID_LENGTH;
case device::BluetoothAdvertisement::ErrorCode::
ERROR_INVALID_ADVERTISEMENT_INTERVAL:
return BluetoothAdvertisementResult::ERROR_INVALID_ADVERTISEMENT_INTERVAL;
case device::BluetoothAdvertisement::ErrorCode::ERROR_RESET_ADVERTISING:
return BluetoothAdvertisementResult::ERROR_RESET_ADVERTISING;
case device::BluetoothAdvertisement::ErrorCode::
INVALID_ADVERTISEMENT_ERROR_CODE:
return BluetoothAdvertisementResult::INVALID_ADVERTISEMENT_ERROR_CODE;
default:
break;
}
return BluetoothAdvertisementResult::BLUETOOTH_ADVERTISEMENT_RESULT_MAX;
}
void BleSynchronizer::RecordDiscoverySessionStarted(bool success) {
UMA_HISTOGRAM_BOOLEAN("InstantTethering.BluetoothDiscoverySessionStarted",
success);
}
} // namespace tether
} // namespace chromeos
......@@ -39,6 +39,18 @@ class BleSynchronizer : public BleSynchronizerBase {
private:
friend class BleSynchronizerTest;
enum BluetoothAdvertisementResult {
SUCCESS = 0,
ERROR_UNSUPPORTED_PLATFORM = 1,
ERROR_ADVERTISEMENT_ALREADY_EXISTS = 2,
ERROR_ADVERTISEMENT_DOES_NOT_EXIST = 3,
ERROR_ADVERTISEMENT_INVALID_LENGTH = 4,
ERROR_INVALID_ADVERTISEMENT_INTERVAL = 5,
ERROR_RESET_ADVERTISING = 6,
INVALID_ADVERTISEMENT_ERROR_CODE = 7,
BLUETOOTH_ADVERTISEMENT_RESULT_MAX
};
void SetTestDoubles(std::unique_ptr<base::Timer> test_timer,
std::unique_ptr<base::Clock> test_clock,
scoped_refptr<base::TaskRunner> test_task_runner);
......@@ -59,6 +71,14 @@ class BleSynchronizer : public BleSynchronizerBase {
void ScheduleCommandCompletion();
void CompleteCurrentCommand();
void RecordBluetoothAdvertisementRegistrationResult(
BluetoothAdvertisementResult result);
void RecordBluetoothAdvertisementUnregistrationResult(
BluetoothAdvertisementResult result);
BluetoothAdvertisementResult BluetoothAdvertisementErrorCodeToResult(
device::BluetoothAdvertisement::ErrorCode error_code);
void RecordDiscoverySessionStarted(bool success);
scoped_refptr<device::BluetoothAdapter> bluetooth_adapter_;
std::unique_ptr<Command> current_command_;
......
......@@ -9,6 +9,7 @@
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/test/histogram_tester.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/simple_test_clock.h"
#include "base/test/test_simple_task_runner.h"
......@@ -248,20 +249,29 @@ class BleSynchronizerTest : public testing::Test {
void InvokeRegisterCallback(bool success,
const std::string& expected_id,
size_t reg_arg_index) {
size_t reg_arg_index,
size_t expected_registration_result_count) {
EXPECT_TRUE(register_args_list_.size() >= reg_arg_index);
EXPECT_EQ(*CreateUUIDList(expected_id),
register_args_list_[reg_arg_index]->service_uuids);
BleSynchronizer::BluetoothAdvertisementResult expected_result;
if (success) {
register_args_list_[reg_arg_index]->callback.Run(
base::MakeRefCounted<device::MockBluetoothAdvertisement>());
expected_result = BleSynchronizer::BluetoothAdvertisementResult::SUCCESS;
} else {
register_args_list_[reg_arg_index]->error_callback.Run(
device::BluetoothAdvertisement::ErrorCode::
INVALID_ADVERTISEMENT_ERROR_CODE);
expected_result = BleSynchronizer::BluetoothAdvertisementResult::
INVALID_ADVERTISEMENT_ERROR_CODE;
}
histogram_tester_.ExpectBucketCount(
"InstantTethering.BluetoothAdvertisementRegistrationResult",
expected_result, expected_registration_result_count);
// Reset to make sure that this callback is never double-invoked.
register_args_list_[reg_arg_index].reset();
test_task_runner_->RunUntilIdle();
......@@ -289,14 +299,22 @@ class BleSynchronizerTest : public testing::Test {
void InvokeUnregisterCallback(bool success, size_t unreg_arg_index) {
EXPECT_TRUE(unregister_args_list_.size() >= unreg_arg_index);
BleSynchronizer::BluetoothAdvertisementResult expected_result;
if (success) {
unregister_args_list_[unreg_arg_index]->callback.Run();
expected_result = BleSynchronizer::BluetoothAdvertisementResult::SUCCESS;
} else {
unregister_args_list_[unreg_arg_index]->error_callback.Run(
device::BluetoothAdvertisement::ErrorCode::
INVALID_ADVERTISEMENT_ERROR_CODE);
expected_result = BleSynchronizer::BluetoothAdvertisementResult::
INVALID_ADVERTISEMENT_ERROR_CODE;
}
histogram_tester_.ExpectBucketCount(
"InstantTethering.BluetoothAdvertisementUnregistrationResult",
expected_result, 1);
// Reset to make sure that this callback is never double-invoked.
unregister_args_list_[unreg_arg_index].reset();
test_task_runner_->RunUntilIdle();
......@@ -327,6 +345,10 @@ class BleSynchronizerTest : public testing::Test {
start_discovery_args_list_[start_arg_index]->error_callback.Run();
}
histogram_tester_.ExpectUniqueSample(
"InstantTethering.BluetoothDiscoverySessionStarted", success ? 1 : 0,
1);
// Reset to make sure that this callback is never double-invoked.
start_discovery_args_list_[start_arg_index].reset();
test_task_runner_->RunUntilIdle();
......@@ -419,19 +441,23 @@ class BleSynchronizerTest : public testing::Test {
std::unique_ptr<BleSynchronizer> synchronizer_;
base::HistogramTester histogram_tester_;
private:
DISALLOW_COPY_AND_ASSIGN(BleSynchronizerTest);
};
TEST_F(BleSynchronizerTest, TestRegisterSuccess) {
RegisterAdvertisement(kId1);
InvokeRegisterCallback(true /* success */, kId1, 0u /* reg_arg_index */);
InvokeRegisterCallback(true /* success */, kId1, 0u /* reg_arg_index */,
1u /* expected_registration_result_count */);
EXPECT_EQ(1, num_register_success_);
}
TEST_F(BleSynchronizerTest, TestRegisterError) {
RegisterAdvertisement(kId1);
InvokeRegisterCallback(false /* success */, kId1, 0u /* reg_arg_index */);
InvokeRegisterCallback(false /* success */, kId1, 0u /* reg_arg_index */,
1u /* expected_registration_result_count */);
EXPECT_EQ(1, num_register_error_);
}
......@@ -481,13 +507,15 @@ TEST_F(BleSynchronizerTest, TestStop_DeletedDiscoverySession) {
// The RegisterAdvertisement() command should be sent without the need for a
// delay, since the previous command was not actually sent.
InvokeRegisterCallback(true /* success */, kId1, 0u /* reg_arg_index */);
InvokeRegisterCallback(true /* success */, kId1, 0u /* reg_arg_index */,
1u /* expected_registration_result_count */);
EXPECT_EQ(1, num_register_success_);
}
TEST_F(BleSynchronizerTest, TestThrottling) {
RegisterAdvertisement(kId1);
InvokeRegisterCallback(true /* success */, kId1, 0u /* reg_arg_index */);
InvokeRegisterCallback(true /* success */, kId1, 0u /* reg_arg_index */,
1u /* expected_registration_result_count */);
EXPECT_EQ(1, num_register_success_);
// Advance to one millisecond before the limit.
......@@ -520,7 +548,8 @@ TEST_F(BleSynchronizerTest, TestThrottling) {
mock_timer_->Fire();
EXPECT_EQ(2u, register_args_list_.size());
InvokeRegisterCallback(false /* success */, kId2, 1u /* reg_arg_index */);
InvokeRegisterCallback(false /* success */, kId2, 1u /* reg_arg_index */,
1u /* expected_registration_result_count */);
EXPECT_EQ(1, num_register_error_);
// Advance the clock and fire the timer. This should result in the next
......@@ -529,7 +558,8 @@ TEST_F(BleSynchronizerTest, TestThrottling) {
mock_timer_->Fire();
EXPECT_EQ(3u, register_args_list_.size());
InvokeRegisterCallback(true /* success */, kId3, 2u /* reg_arg_index */);
InvokeRegisterCallback(true /* success */, kId3, 2u /* reg_arg_index */,
2u /* expected_registration_result_count */);
EXPECT_EQ(2, num_register_success_);
// Advance the clock before doing anything else. The next request should not
......
......@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
......@@ -256,6 +257,7 @@ void BluetoothLowEnergyWeaveClientConnection::SetSubStatus(
SubStatus new_sub_status) {
sub_status_ = new_sub_status;
timer_->Stop();
RecordSetSubStatus(true /* success */);
base::TimeDelta timeout_for_sub_status = GetTimeoutForSubStatus(sub_status_);
if (!timeout_for_sub_status.is_max()) {
......@@ -280,6 +282,7 @@ void BluetoothLowEnergyWeaveClientConnection::OnTimeoutForSubStatus(
// Ensure that |sub_status| is still the active status.
DCHECK(status == sub_status());
RecordSetSubStatus(false /* success */);
PA_LOG(ERROR) << "Timed out waiting during SubStatus "
<< SubStatusToString(status) << ". Destroying connection.";
DestroyConnection();
......@@ -430,6 +433,8 @@ void BluetoothLowEnergyWeaveClientConnection::OnSetConnectionLatencyError() {
void BluetoothLowEnergyWeaveClientConnection::OnCreateGattConnectionError(
device::BluetoothDevice::ConnectErrorCode error_code) {
DCHECK(sub_status_ == SubStatus::WAITING_GATT_CONNECTION);
RecordGattConnectionResult(
BluetoothDeviceConnectErrorCodeToGattConnectionResult(error_code));
PA_LOG(WARNING) << "Error creating GATT connection to "
<< GetDeviceInfoLogString() << ". Error code: " << error_code;
DestroyConnection();
......@@ -438,6 +443,8 @@ void BluetoothLowEnergyWeaveClientConnection::OnCreateGattConnectionError(
void BluetoothLowEnergyWeaveClientConnection::OnGattConnectionCreated(
std::unique_ptr<device::BluetoothGattConnection> gatt_connection) {
DCHECK(sub_status() == SubStatus::WAITING_GATT_CONNECTION);
RecordGattConnectionResult(
GattConnectionResult::GATT_CONNECTION_RESULT_SUCCESS);
gatt_connection_ = std::move(gatt_connection);
SetSubStatus(SubStatus::WAITING_CHARACTERISTICS);
......@@ -537,6 +544,8 @@ void BluetoothLowEnergyWeaveClientConnection::StartNotifySession() {
void BluetoothLowEnergyWeaveClientConnection::OnNotifySessionStarted(
std::unique_ptr<device::BluetoothGattNotifySession> notify_session) {
DCHECK(sub_status() == SubStatus::WAITING_NOTIFY_SESSION);
RecordGattNotifySessionResult(
GattServiceOperationResult::GATT_SERVICE_OPERATION_RESULT_SUCCESS);
notify_session_ = std::move(notify_session);
SetSubStatus(SubStatus::NOTIFY_SESSION_READY);
SendConnectionRequest();
......@@ -545,6 +554,9 @@ void BluetoothLowEnergyWeaveClientConnection::OnNotifySessionStarted(
void BluetoothLowEnergyWeaveClientConnection::OnNotifySessionError(
device::BluetoothRemoteGattService::GattErrorCode error) {
DCHECK(sub_status() == SubStatus::WAITING_NOTIFY_SESSION);
RecordGattNotifySessionResult(
BluetoothRemoteDeviceGattServiceGattErrorCodeToGattServiceOperationResult(
error));
PA_LOG(ERROR) << "Cannot start notification session for "
<< GetDeviceInfoLogString() << ". Error: " << error << ".";
DestroyConnection();
......@@ -604,6 +616,9 @@ void BluetoothLowEnergyWeaveClientConnection::OnRemoteCharacteristicWritten() {
DCHECK(sub_status() == SubStatus::WAITING_CONNECTION_RESPONSE ||
sub_status() == SubStatus::CONNECTED);
RecordGattWriteCharacteristicResult(
GattServiceOperationResult::GATT_SERVICE_OPERATION_RESULT_SUCCESS);
if (!pending_write_request_) {
PA_LOG(ERROR) << "OnRemoteCharacteristicWritten() called, but no pending "
<< "WriteRequest. Stopping connection to "
......@@ -655,6 +670,10 @@ void BluetoothLowEnergyWeaveClientConnection::OnWriteRemoteCharacteristicError(
DCHECK(sub_status() == SubStatus::WAITING_CONNECTION_RESPONSE ||
sub_status() == SubStatus::CONNECTED);
RecordGattWriteCharacteristicResult(
BluetoothRemoteDeviceGattServiceGattErrorCodeToGattServiceOperationResult(
error));
if (!pending_write_request_) {
PA_LOG(ERROR) << "OnWriteRemoteCharacteristicError() called, but no "
<< "pending WriteRequest. Stopping connection to "
......@@ -792,6 +811,102 @@ std::string BluetoothLowEnergyWeaveClientConnection::GetReasonForClose() {
}
}
void BluetoothLowEnergyWeaveClientConnection::RecordGattConnectionResult(
GattConnectionResult result) {
UMA_HISTOGRAM_ENUMERATION("ProximityAuth.BluetoothGattConnectionResult",
result,
GattConnectionResult::GATT_CONNECTION_RESULT_MAX);
}
BluetoothLowEnergyWeaveClientConnection::GattConnectionResult
BluetoothLowEnergyWeaveClientConnection::
BluetoothDeviceConnectErrorCodeToGattConnectionResult(
device::BluetoothDevice::ConnectErrorCode error_code) {
switch (error_code) {
case device::BluetoothDevice::ConnectErrorCode::ERROR_AUTH_CANCELED:
return GattConnectionResult::GATT_CONNECTION_RESULT_ERROR_AUTH_CANCELED;
case device::BluetoothDevice::ConnectErrorCode::ERROR_AUTH_FAILED:
return GattConnectionResult::GATT_CONNECTION_RESULT_ERROR_AUTH_FAILED;
case device::BluetoothDevice::ConnectErrorCode::ERROR_AUTH_REJECTED:
return GattConnectionResult::GATT_CONNECTION_RESULT_ERROR_AUTH_REJECTED;
case device::BluetoothDevice::ConnectErrorCode::ERROR_AUTH_TIMEOUT:
return GattConnectionResult::GATT_CONNECTION_RESULT_ERROR_AUTH_TIMEOUT;
case device::BluetoothDevice::ConnectErrorCode::ERROR_FAILED:
return GattConnectionResult::GATT_CONNECTION_RESULT_ERROR_FAILED;
case device::BluetoothDevice::ConnectErrorCode::ERROR_INPROGRESS:
return GattConnectionResult::GATT_CONNECTION_RESULT_ERROR_INPROGRESS;
case device::BluetoothDevice::ConnectErrorCode::ERROR_UNKNOWN:
return GattConnectionResult::GATT_CONNECTION_RESULT_ERROR_UNKNOWN;
case device::BluetoothDevice::ConnectErrorCode::ERROR_UNSUPPORTED_DEVICE:
return GattConnectionResult::
GATT_CONNECTION_RESULT_ERROR_UNSUPPORTED_DEVICE;
default:
break;
}
return GattConnectionResult::GATT_CONNECTION_RESULT_MAX;
}
void BluetoothLowEnergyWeaveClientConnection::RecordGattNotifySessionResult(
GattServiceOperationResult result) {
UMA_HISTOGRAM_ENUMERATION(
"ProximityAuth.BluetoothGattNotifySessionResult", result,
GattServiceOperationResult::GATT_SERVICE_OPERATION_RESULT_MAX);
}
void BluetoothLowEnergyWeaveClientConnection::
RecordGattWriteCharacteristicResult(GattServiceOperationResult result) {
UMA_HISTOGRAM_ENUMERATION(
"ProximityAuth.BluetoothGattWriteCharacteristicResult", result,
GattServiceOperationResult::GATT_SERVICE_OPERATION_RESULT_MAX);
}
BluetoothLowEnergyWeaveClientConnection::GattServiceOperationResult
BluetoothLowEnergyWeaveClientConnection::
BluetoothRemoteDeviceGattServiceGattErrorCodeToGattServiceOperationResult(
device::BluetoothRemoteGattService::GattErrorCode error_code) {
switch (error_code) {
case device::BluetoothRemoteGattService::GattErrorCode::GATT_ERROR_UNKNOWN:
return GattServiceOperationResult::
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_UNKNOWN;
case device::BluetoothRemoteGattService::GattErrorCode::GATT_ERROR_FAILED:
return GattServiceOperationResult::
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_FAILED;
case device::BluetoothRemoteGattService::GattErrorCode::
GATT_ERROR_IN_PROGRESS:
return GattServiceOperationResult::
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_IN_PROGRESS;
case device::BluetoothRemoteGattService::GattErrorCode::
GATT_ERROR_INVALID_LENGTH:
return GattServiceOperationResult::
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_INVALID_LENGTH;
case device::BluetoothRemoteGattService::GattErrorCode::
GATT_ERROR_NOT_PERMITTED:
return GattServiceOperationResult::
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_NOT_PERMITTED;
case device::BluetoothRemoteGattService::GattErrorCode::
GATT_ERROR_NOT_AUTHORIZED:
return GattServiceOperationResult::
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_NOT_AUTHORIZED;
case device::BluetoothRemoteGattService::GattErrorCode::
GATT_ERROR_NOT_PAIRED:
return GattServiceOperationResult::
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_NOT_PAIRED;
case device::BluetoothRemoteGattService::GattErrorCode::
GATT_ERROR_NOT_SUPPORTED:
return GattServiceOperationResult::
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_NOT_SUPPORTED;
default:
break;
}
return GattServiceOperationResult::GATT_SERVICE_OPERATION_RESULT_MAX;
}
void BluetoothLowEnergyWeaveClientConnection::RecordSetSubStatus(bool success) {
UMA_HISTOGRAM_BOOLEAN("ProximityAuth.BluetoothSetSubStatus", success);
}
BluetoothLowEnergyWeaveClientConnection::WriteRequest::WriteRequest(
const Packet& val,
WriteRequestType request_type,
......
......@@ -142,6 +142,8 @@ class BluetoothLowEnergyWeaveClientConnection
}
private:
friend class CryptAuthBluetoothLowEnergyWeaveClientConnectionTest;
enum WriteRequestType {
REGULAR,
MESSAGE_COMPLETE,
......@@ -149,6 +151,32 @@ class BluetoothLowEnergyWeaveClientConnection
CONNECTION_CLOSE
};
enum GattConnectionResult {
GATT_CONNECTION_RESULT_SUCCESS = 0,
GATT_CONNECTION_RESULT_ERROR_AUTH_CANCELED = 1,
GATT_CONNECTION_RESULT_ERROR_AUTH_FAILED = 2,
GATT_CONNECTION_RESULT_ERROR_AUTH_REJECTED = 3,
GATT_CONNECTION_RESULT_ERROR_AUTH_TIMEOUT = 4,
GATT_CONNECTION_RESULT_ERROR_FAILED = 5,
GATT_CONNECTION_RESULT_ERROR_INPROGRESS = 6,
GATT_CONNECTION_RESULT_ERROR_UNKNOWN = 7,
GATT_CONNECTION_RESULT_ERROR_UNSUPPORTED_DEVICE = 8,
GATT_CONNECTION_RESULT_MAX
};
enum GattServiceOperationResult {
GATT_SERVICE_OPERATION_RESULT_SUCCESS = 0,
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_UNKNOWN = 1,
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_FAILED = 2,
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_IN_PROGRESS = 3,
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_INVALID_LENGTH = 4,
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_NOT_PERMITTED = 5,
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_NOT_AUTHORIZED = 6,
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_NOT_PAIRED = 7,
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_NOT_SUPPORTED = 8,
GATT_SERVICE_OPERATION_RESULT_MAX
};
// Represents a request to write |value| to a some characteristic.
// |is_last_write_for_wire_messsage| indicates whether this request
// corresponds to the last write request for some wire message.
......@@ -214,6 +242,16 @@ class BluetoothLowEnergyWeaveClientConnection
device::BluetoothRemoteGattService::GattErrorCode error);
void ClearQueueAndSendConnectionClose();
void RecordGattConnectionResult(GattConnectionResult result);
GattConnectionResult BluetoothDeviceConnectErrorCodeToGattConnectionResult(
device::BluetoothDevice::ConnectErrorCode error_code);
void RecordGattNotifySessionResult(GattServiceOperationResult result);
void RecordGattWriteCharacteristicResult(GattServiceOperationResult result);
GattServiceOperationResult
BluetoothRemoteDeviceGattServiceGattErrorCodeToGattServiceOperationResult(
device::BluetoothRemoteGattService::GattErrorCode error_code);
void RecordSetSubStatus(bool success);
// Private getters for the Bluetooth classes corresponding to this connection.
device::BluetoothRemoteGattService* GetRemoteService();
device::BluetoothRemoteGattCharacteristic* GetGattCharacteristic(
......
......@@ -13,6 +13,7 @@
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/test/histogram_tester.h"
#include "base/test/test_simple_task_runner.h"
#include "base/timer/mock_timer.h"
#include "base/timer/timer.h"
......@@ -488,6 +489,8 @@ class CryptAuthBluetoothLowEnergyWeaveClientConnectionTest
notify_session_success_callback_.Run(std::move(notify_session));
task_runner_->RunUntilIdle();
VerifyGattNotifySessionResult(true);
// Written value contains only the mock Connection Request.
EXPECT_EQ(last_value_written_on_tx_characteristic_, kConnectionRequest);
......@@ -566,6 +569,36 @@ class CryptAuthBluetoothLowEnergyWeaveClientConnectionTest
task_runner_->RunUntilIdle();
}
void VerifyGattConnectionResultSuccess() {
histogram_tester_.ExpectUniqueSample(
"ProximityAuth.BluetoothGattConnectionResult",
BluetoothLowEnergyWeaveClientConnection::GattConnectionResult::
GATT_CONNECTION_RESULT_SUCCESS,
1);
}
void VerifyGattNotifySessionResult(bool success) {
histogram_tester_.ExpectUniqueSample(
"ProximityAuth.BluetoothGattNotifySessionResult",
GattServiceOperationResultSuccessOrFailure(success), 1);
}
void VerifyGattWriteCharacteristicResult(bool success, int num_writes) {
histogram_tester_.ExpectBucketCount(
"ProximityAuth.BluetoothGattWriteCharacteristicResult",
GattServiceOperationResultSuccessOrFailure(success), num_writes);
}
BluetoothLowEnergyWeaveClientConnection::GattServiceOperationResult
GattServiceOperationResultSuccessOrFailure(bool success) {
return success ? BluetoothLowEnergyWeaveClientConnection::
GattServiceOperationResult::
GATT_SERVICE_OPERATION_RESULT_SUCCESS
: BluetoothLowEnergyWeaveClientConnection::
GattServiceOperationResult::
GATT_SERVICE_OPERATION_RESULT_GATT_ERROR_UNKNOWN;
}
protected:
const RemoteDevice remote_device_;
const device::BluetoothUUID service_uuid_;
......@@ -610,6 +643,8 @@ class CryptAuthBluetoothLowEnergyWeaveClientConnectionTest
device::BluetoothRemoteGattCharacteristic::ErrorCallback
write_remote_characteristic_error_callback_;
base::HistogramTester histogram_tester_;
private:
DISALLOW_COPY_AND_ASSIGN(
CryptAuthBluetoothLowEnergyWeaveClientConnectionTest);
......@@ -738,6 +773,8 @@ TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
notify_session_error_callback_.Run(
device::BluetoothRemoteGattService::GATT_ERROR_UNKNOWN);
VerifyGattNotifySessionResult(false);
EXPECT_EQ(connection->sub_status(), SubStatus::DISCONNECTED);
EXPECT_EQ(connection->status(), Connection::DISCONNECTED);
}
......@@ -769,6 +806,8 @@ TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
write_remote_characteristic_error_callback_.Run(
device::BluetoothRemoteGattService::GATT_ERROR_UNKNOWN);
task_runner_->RunUntilIdle();
VerifyGattWriteCharacteristicResult(false /* success */,
i + 1 /* num_writes */);
}
EXPECT_EQ(connection->sub_status(), SubStatus::DISCONNECTED);
......@@ -831,6 +870,7 @@ TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
EXPECT_EQ(last_value_written_on_tx_characteristic_, kSmallPackets0);
RunWriteCharacteristicSuccessCallback();
VerifyGattWriteCharacteristicResult(true /* success */, 2 /* num_writes */);
EXPECT_EQ(1, connection_observer_->GetNumSendCompleted());
EXPECT_EQ(kSmallMessage, connection_observer_->GetLastDeserializedMessage());
......@@ -867,6 +907,7 @@ TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
SaveArg<2>(&write_remote_characteristic_error_callback_)));
RunWriteCharacteristicSuccessCallback();
VerifyGattWriteCharacteristicResult(true /* success */, 2 /* num_writes */);
bytes_received.insert(bytes_received.end(),
last_value_written_on_tx_characteristic_.begin() + 1,
last_value_written_on_tx_characteristic_.end());
......@@ -875,6 +916,7 @@ TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
EXPECT_EQ(expected, bytes_received);
RunWriteCharacteristicSuccessCallback();
VerifyGattWriteCharacteristicResult(true /* success */, 3 /* num_writes */);
EXPECT_EQ(1, connection_observer_->GetNumSendCompleted());
EXPECT_EQ(kLargeMessage, connection_observer_->GetLastDeserializedMessage());
......@@ -904,6 +946,8 @@ TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
write_remote_characteristic_error_callback_.Run(
device::BluetoothRemoteGattService::GATT_ERROR_UNKNOWN);
task_runner_->RunUntilIdle();
VerifyGattWriteCharacteristicResult(false /* success */,
i + 1 /* num_writes */);
if (i == kMaxNumberOfTries - 1) {
EXPECT_EQ(1, connection_observer_->GetNumSendCompleted());
EXPECT_EQ(kSmallMessage,
......@@ -953,6 +997,7 @@ TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
EXPECT_EQ(receiver_->GetReasonToClose(), ReasonForClose::APPLICATION_ERROR);
RunWriteCharacteristicSuccessCallback();
VerifyGattWriteCharacteristicResult(true /* success */, 2 /* num_writes */);
EXPECT_EQ(connection->sub_status(), SubStatus::DISCONNECTED);
EXPECT_EQ(connection->status(), Connection::DISCONNECTED);
}
......@@ -985,12 +1030,14 @@ TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
SaveArg<2>(&write_remote_characteristic_error_callback_)));
RunWriteCharacteristicSuccessCallback();
VerifyGattWriteCharacteristicResult(true /* success */, 2 /* num_writes */);
EXPECT_EQ(last_value_written_on_tx_characteristic_,
kConnectionCloseApplicationError);
EXPECT_EQ(receiver_->GetReasonToClose(), ReasonForClose::APPLICATION_ERROR);
RunWriteCharacteristicSuccessCallback();
VerifyGattWriteCharacteristicResult(true /* success */, 3 /* num_writes */);
EXPECT_EQ(connection->sub_status(), SubStatus::DISCONNECTED);
EXPECT_EQ(connection->status(), Connection::DISCONNECTED);
}
......@@ -1018,6 +1065,7 @@ TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
EXPECT_EQ(receiver_->GetReasonToClose(), ReasonForClose::APPLICATION_ERROR);
RunWriteCharacteristicSuccessCallback();
VerifyGattWriteCharacteristicResult(true /* success */, 2 /* num_writes */);
// We cannot check if connection's status and sub_status are DISCONNECTED
// because it has been deleted.
......@@ -1043,6 +1091,7 @@ TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
EXPECT_EQ(last_value_written_on_tx_characteristic_, kSmallPackets0);
RunWriteCharacteristicSuccessCallback();
VerifyGattWriteCharacteristicResult(true /* success */, 2 /* num_writes */);
task_runner_->RunUntilIdle();
EXPECT_EQ(1, connection_observer_->GetNumSendCompleted());
EXPECT_EQ(kSmallMessage, connection_observer_->GetLastDeserializedMessage());
......@@ -1085,6 +1134,8 @@ TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
write_remote_characteristic_error_callback_.Run(
device::BluetoothRemoteGattService::GATT_ERROR_UNKNOWN);
task_runner_->RunUntilIdle();
VerifyGattWriteCharacteristicResult(false /* success */,
i + 1 /* num_writes */);
}
EXPECT_EQ(connection->sub_status(), SubStatus::DISCONNECTED);
......@@ -1135,6 +1186,8 @@ TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
CharacteristicsFound(connection.get());
NotifySessionStarted(connection.get());
ConnectionResponseReceived(connection.get(), kDefaultMaxPacketSize);
VerifyGattConnectionResultSuccess();
}
TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
......@@ -1173,6 +1226,8 @@ TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
CharacteristicsFound(connection.get());
NotifySessionStarted(connection.get());
ConnectionResponseReceived(connection.get(), kDefaultMaxPacketSize);
VerifyGattConnectionResultSuccess();
}
TEST_F(CryptAuthBluetoothLowEnergyWeaveClientConnectionTest,
......
......@@ -21288,6 +21288,17 @@ uploading your change for review. These are checked by presubmit scripts.
<int value="1" label="identical"/>
</enum>
<enum name="InstantTethering_BluetoothAdvertisementResult">
<int value="0" label="Success"/>
<int value="1" label="Error: Unsupported platform"/>
<int value="2" label="Error: Advertisement already exists"/>
<int value="3" label="Error: Advertisement does not exist"/>
<int value="4" label="Error: Advertisement invalid length"/>
<int value="5" label="Error: Invalid advertisement interval"/>
<int value="6" label="Error: Reset advertising"/>
<int value="7" label="Invalid advertisement error code"/>
</enum>
<enum name="InstantTethering_ConnectionToHostResult_Failure">
<int value="0" label="Unknown error"/>
<int value="1" label="Tethering timed out"/>
......@@ -32321,6 +32332,30 @@ from previous Chrome versions.
<int value="7" label="SAVING_ON_HTTP_AFTER_HTTPS"/>
</enum>
<enum name="ProximityAuth_BluetoothGattConnectionResult">
<int value="0" label="Success"/>
<int value="1" label="Error: Auth canceled"/>
<int value="2" label="Error: Auth failed"/>
<int value="3" label="Error: Auth rejected"/>
<int value="4" label="Error: Auth timeout"/>
<int value="5" label="Error: Failed"/>
<int value="6" label="Error: In progress"/>
<int value="7" label="Error: Unknown"/>
<int value="8" label="Error: Unsupported device"/>
</enum>
<enum name="ProximityAuth_BluetoothGattServiceOperationResult">
<int value="0" label="Success"/>
<int value="1" label="Error: Unknown"/>
<int value="2" label="Error: Failed"/>
<int value="3" label="Error: In progress"/>
<int value="4" label="Error: Invalid length"/>
<int value="5" label="Error: Not permitted"/>
<int value="6" label="Error: Not authorized"/>
<int value="7" label="Error: Not paired"/>
<int value="8" label="Error: Not supported"/>
</enum>
<enum name="ProxyStatus">
<int value="0" label="PROXY_STATUS_IGNORED"/>
<int value="1" label="PROXY_UNINITIALIZED"/>
......@@ -28630,6 +28630,32 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
</summary>
</histogram>
<histogram name="InstantTethering.BluetoothAdvertisementRegistrationResult"
enum="InstantTethering_BluetoothAdvertisementResult">
<owner>hansberry@chromium.com</owner>
<summary>
Provides a breakdown of how many times each possible Bluetooth advertisement
registration result occurs.
</summary>
</histogram>
<histogram name="InstantTethering.BluetoothAdvertisementUnregistrationResult"
enum="InstantTethering_BluetoothAdvertisementResult">
<owner>hansberry@chromium.com</owner>
<summary>
Provides a breakdown of how many times each possible Bluetooth advertisement
unregistration result occurs.
</summary>
</histogram>
<histogram name="InstantTethering.BluetoothDiscoverySessionStarted"
enum="BooleanSuccess">
<owner>hansberry@chromium.com</owner>
<summary>
Provides the success rate of starting a Bluetooth discovery session.
</summary>
</histogram>
<histogram name="InstantTethering.ConnectionToHostResult.Failure"
enum="InstantTethering_ConnectionToHostResult_Failure">
<owner>hansberry@chromium.com</owner>
......@@ -64328,6 +64354,41 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
</summary>
</histogram>
<histogram name="ProximityAuth.BluetoothGattConnectionResult"
enum="ProximityAuth_BluetoothGattConnectionResult">
<owner>hansberry@chromium.com</owner>
<summary>
Provides a breakdown of how many times each possible Bluetooth GATT
connection result occurs.
</summary>
</histogram>
<histogram name="ProximityAuth.BluetoothGattNotifySessionResult"
enum="ProximityAuth_BluetoothGattServiceOperationResult">
<owner>hansberry@chromium.com</owner>
<summary>
Provides a breakdown of how many times each possible Bluetooth GATT
&quot;notify session&quot; attempt result occurs.
</summary>
</histogram>
<histogram name="ProximityAuth.BluetoothGattWriteCharacteristicResult"
enum="ProximityAuth_BluetoothGattServiceOperationResult">
<owner>hansberry@chromium.com</owner>
<summary>
Provides a breakdown of how many times each possible Bluetooth GATT
&quot;write characteristic&quot; attempt result occurs.
</summary>
</histogram>
<histogram name="ProximityAuth.BluetoothSetSubStatus" enum="BooleanTimedOut">
<owner>hansberry@chromium.com</owner>
<summary>
Provides the success rate of setting connection &quot;sub status&quot;.
Timeout indicates a Bluetooth failure.
</summary>
</histogram>
<histogram name="ProxyOverriddenBubble.ExtensionCount" units="Extensions">
<obsolete>
Deprecated 9/2016. Never added to histograms.xml and value is always 1.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment