diff options
author | 2023-03-23 02:30:09 +0000 | |
---|---|---|
committer | 2023-03-22 19:39:55 -0700 | |
commit | fc41a25bad034ea910775e32650cbc085ac8b562 (patch) | |
tree | 776ad0ef8f3b6959bb1ad9bc3997506adf1d22bf | |
parent | 5a00b850b0ebdb337effb97564d46d8ee497f307 (diff) |
Revert "Revert "[BluetoothMetrics] This covers the case for Direct LE-AC...""
This reverts commit 5a00b850b0ebdb337effb97564d46d8ee497f307.
Reason for revert: Adding the fix for the floss build
Change-Id: Ia02811feed9403643dc8d415903bfeea229c0ebb
-rw-r--r-- | system/common/metrics.cc | 18 | ||||
-rw-r--r-- | system/common/metrics.h | 11 | ||||
-rw-r--r-- | system/gd/Android.bp | 1 | ||||
-rw-r--r-- | system/gd/hci/acl_manager/le_impl.h | 47 | ||||
-rw-r--r-- | system/gd/metrics/Android.bp | 3 | ||||
-rw-r--r-- | system/gd/metrics/BUILD.gn | 2 | ||||
-rw-r--r-- | system/gd/metrics/metrics.h | 1 | ||||
-rw-r--r-- | system/gd/metrics/metrics_state.cc | 227 | ||||
-rw-r--r-- | system/gd/metrics/metrics_state.h | 122 | ||||
-rw-r--r-- | system/gd/metrics/metrics_state_unittest.cc | 196 | ||||
-rw-r--r-- | system/gd/metrics/utils.cc | 12 | ||||
-rw-r--r-- | system/gd/metrics/utils.h | 8 | ||||
-rw-r--r-- | system/gd/os/android/metrics.cc | 40 | ||||
-rw-r--r-- | system/gd/os/host/metrics.cc | 10 | ||||
-rw-r--r-- | system/gd/os/linux/metrics.cc | 7 | ||||
-rw-r--r-- | system/gd/os/metrics.h | 44 | ||||
-rw-r--r-- | system/main/shim/metrics_api.cc | 12 | ||||
-rw-r--r-- | system/main/shim/metrics_api.h | 9 | ||||
-rw-r--r-- | system/stack/acl/btm_acl.cc | 12 | ||||
-rw-r--r-- | system/test/mock/mock_main_shim_metrics_api.cc | 10 | ||||
-rw-r--r-- | system/test/mock/mock_main_shim_metrics_api.h | 36 |
21 files changed, 821 insertions, 7 deletions
diff --git a/system/common/metrics.cc b/system/common/metrics.cc index baf838b0c4..b243fd78b7 100644 --- a/system/common/metrics.cc +++ b/system/common/metrics.cc @@ -20,6 +20,7 @@ #include <base/base64.h> #include <base/logging.h> +#include <frameworks/proto_logging/stats/enums/bluetooth/le/enums.pb.h> #include <include/hardware/bt_av.h> #include <statslog_bt.h> #include <unistd.h> @@ -35,6 +36,9 @@ #include "address_obfuscator.h" #include "bluetooth/metrics/bluetooth.pb.h" +#include "gd/metrics/metrics_state.h" +#include "gd/hci/address.h" +#include "gd/os/metrics.h" #include "leaky_bonded_queue.h" #include "metric_id_allocator.h" #include "osi/include/osi.h" @@ -68,6 +72,7 @@ using bluetooth::metrics::BluetoothMetricsProto::ScanEvent_ScanEventType; using bluetooth::metrics::BluetoothMetricsProto::ScanEvent_ScanTechnologyType; using bluetooth::metrics::BluetoothMetricsProto::WakeEvent; using bluetooth::metrics::BluetoothMetricsProto::WakeEvent_WakeEventType; +using bluetooth::hci::Address; static float combine_averages(float avg_a, int64_t ct_a, float avg_b, int64_t ct_b) { @@ -969,6 +974,19 @@ void LogLeAudioBroadcastSessionReported(int64_t duration_nanos) { } } +void LogLeBluetoothConnectionMetricEventReported( + const Address& address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector<std::pair<os::ArgumentType, int>> + argument_list) { + // Log the events for the State Management + metrics::MetricsCollector::GetLEConnectionMetricsCollector() + ->AddStateChangedEvent(address, origin_type, connection_type, + transaction_state, argument_list); +} + } // namespace common } // namespace bluetooth diff --git a/system/common/metrics.h b/system/common/metrics.h index a0a34b5945..273cbdab19 100644 --- a/system/common/metrics.h +++ b/system/common/metrics.h @@ -21,13 +21,16 @@ #include <bta/include/bta_api.h> #include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h> #include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h> +#include <frameworks/proto_logging/stats/enums/bluetooth/le/enums.pb.h> #include <stdint.h> #include <memory> #include <string> #include <vector> +#include "gd/os/metrics.h" #include "types/raw_address.h" +#include "hci/address.h" namespace bluetooth { @@ -520,6 +523,14 @@ void LogLeAudioConnectionSessionReported( void LogLeAudioBroadcastSessionReported(int64_t duration_nanos); +void LogLeBluetoothConnectionMetricEventReported( + const RawAddress& raw_address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector<std::pair<os::ArgumentType, int>> + argument_list); + } // namespace common } // namespace bluetooth diff --git a/system/gd/Android.bp b/system/gd/Android.bp index 30dba93d45..13ec09bd40 100644 --- a/system/gd/Android.bp +++ b/system/gd/Android.bp @@ -426,6 +426,7 @@ cc_test { "libbt_callbacks_cxx", "libbt_shim_bridge", "libbt_shim_ffi", + "libbt-platform-protos-lite" ], shared_libs: [ "libcrypto", diff --git a/system/gd/hci/acl_manager/le_impl.h b/system/gd/hci/acl_manager/le_impl.h index 4e849e7436..b14e9a1980 100644 --- a/system/gd/hci/acl_manager/le_impl.h +++ b/system/gd/hci/acl_manager/le_impl.h @@ -38,6 +38,7 @@ #include "hci/le_address_manager.h" #include "os/alarm.h" #include "os/handler.h" +#include "os/metrics.h" #include "os/system_properties.h" #include "packet/packet_view.h" @@ -342,6 +343,16 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { AddressWithType remote_address(address, peer_address_type); AddressWithType local_address = le_address_manager_->GetInitiatorAddress(); const bool in_filter_accept_list = is_device_in_connect_list(remote_address); + auto argument_list = std::vector<std::pair<bluetooth::os::ArgumentType, int>>(); + argument_list.push_back( + std::make_pair(os::ArgumentType::ACL_STATUS_CODE, static_cast<int>(status))); + + bluetooth::os::LogMetricBluetoothLEConnectionMetricEvent( + address, + android::bluetooth::le::LeConnectionOriginType::ORIGIN_NATIVE, + android::bluetooth::le::LeConnectionType::CONNECTION_TYPE_LE_ACL, + android::bluetooth::le::LeConnectionState::STATE_LE_ACL_END, + argument_list); if (role == hci::Role::CENTRAL) { connectability_state_ = ConnectabilityState::DISARMED; @@ -353,7 +364,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { if (status == ErrorCode::UNKNOWN_CONNECTION) { if (remote_address.GetAddress() != Address::kEmpty) { LOG_INFO("Controller send non-empty address field:%s", - ADDRESS_TO_LOGGABLE_CSTR(remote_address.GetAddress())); + ADDRESS_TO_LOGGABLE_CSTR(remote_address.GetAddress())); } // direct connect canceled due to connection timeout, start background connect create_le_connection(remote_address, false, false); @@ -485,6 +496,16 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { } AddressWithType remote_address(address, remote_address_type); const bool in_filter_accept_list = is_device_in_connect_list(remote_address); + auto argument_list = std::vector<std::pair<bluetooth::os::ArgumentType, int>>(); + argument_list.push_back( + std::make_pair(os::ArgumentType::ACL_STATUS_CODE, static_cast<int>(status))); + + bluetooth::os::LogMetricBluetoothLEConnectionMetricEvent( + address, + android::bluetooth::le::LeConnectionOriginType::ORIGIN_NATIVE, + android::bluetooth::le::LeConnectionType::CONNECTION_TYPE_LE_ACL, + android::bluetooth::le::LeConnectionState::STATE_LE_ACL_END, + argument_list); if (role == hci::Role::CENTRAL) { connectability_state_ = ConnectabilityState::DISARMED; @@ -498,7 +519,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { if (status == ErrorCode::UNKNOWN_CONNECTION) { if (remote_address.GetAddress() != Address::kEmpty) { LOG_INFO("Controller send non-empty address field:%s", - ADDRESS_TO_LOGGABLE_CSTR(remote_address.GetAddress())); + ADDRESS_TO_LOGGABLE_CSTR(remote_address.GetAddress())); } // direct connect canceled due to connection timeout, start background connect create_le_connection(remote_address, false, false); @@ -792,7 +813,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { void remove_device_from_connect_list(AddressWithType address_with_type) { if (connect_list.find(address_with_type) == connect_list.end()) { LOG_WARN("Device not in acceptlist and cannot be removed:%s", - ADDRESS_TO_LOGGABLE_CSTR(address_with_type)); + ADDRESS_TO_LOGGABLE_CSTR(address_with_type)); return; } connect_list.erase(address_with_type); @@ -982,6 +1003,15 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { } void disarm_connectability() { + + auto argument_list = std::vector<std::pair<os::ArgumentType, int>>(); + bluetooth::os::LogMetricBluetoothLEConnectionMetricEvent( + Address::kEmpty, + os::LeConnectionOriginType::ORIGIN_UNSPECIFIED, + os::LeConnectionType::CONNECTION_TYPE_LE_ACL, + os::LeConnectionState::STATE_LE_ACL_CANCEL, + argument_list); + switch (connectability_state_) { case ConnectabilityState::ARMED: LOG_INFO("Disarming LE connection state machine with create connection cancel"); @@ -1078,6 +1108,17 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { if (create_connection_timeout_alarms_.find(address_with_type) != create_connection_timeout_alarms_.end()) { create_connection_timeout_alarms_.at(address_with_type).Cancel(); create_connection_timeout_alarms_.erase(address_with_type); + auto argument_list = std::vector<std::pair<os::ArgumentType, int>>(); + argument_list.push_back(std::make_pair( + os::ArgumentType::ACL_STATUS_CODE, + static_cast<int>(android::bluetooth::hci::StatusEnum::STATUS_CONNECTION_TOUT))); + bluetooth::os::LogMetricBluetoothLEConnectionMetricEvent( + address_with_type.GetAddress(), + android::bluetooth::le::LeConnectionOriginType::ORIGIN_NATIVE, + android::bluetooth::le::LeConnectionType::CONNECTION_TYPE_LE_ACL, + android::bluetooth::le::LeConnectionState::STATE_LE_ACL_TIMEOUT, + argument_list); + if (background_connections_.find(address_with_type) != background_connections_.end()) { direct_connections_.erase(address_with_type); disarm_connectability(); diff --git a/system/gd/metrics/Android.bp b/system/gd/metrics/Android.bp index 2556f89dae..5ae11f16e1 100644 --- a/system/gd/metrics/Android.bp +++ b/system/gd/metrics/Android.bp @@ -11,6 +11,8 @@ filegroup { name: "BluetoothMetricsSources", srcs: [ "counter_metrics.cc", + "metrics_state.cc", + "utils.cc" ], } @@ -18,5 +20,6 @@ filegroup { name: "BluetoothMetricsTestSources", srcs: [ "counter_metrics_unittest.cc", + "metrics_state_unittest.cc" ], } diff --git a/system/gd/metrics/BUILD.gn b/system/gd/metrics/BUILD.gn index d920fa54b7..d4a952258a 100644 --- a/system/gd/metrics/BUILD.gn +++ b/system/gd/metrics/BUILD.gn @@ -36,7 +36,7 @@ source_set("BluetoothMetricsSources") { "utils.cc", ] - configs += [ "//bt/system/gd:gd_defaults" ] + configs += [ "//bt/system/gd:gd_defaults"] deps = [ "//bt/system/gd:gd_default_deps" ] if (target_os == "chromeos") { diff --git a/system/gd/metrics/metrics.h b/system/gd/metrics/metrics.h index cb8246207d..6e22318c40 100644 --- a/system/gd/metrics/metrics.h +++ b/system/gd/metrics/metrics.h @@ -16,7 +16,6 @@ #pragma once #include <cstdint> - #include "types/raw_address.h" namespace bluetooth { diff --git a/system/gd/metrics/metrics_state.cc b/system/gd/metrics/metrics_state.cc new file mode 100644 index 0000000000..602657a2f1 --- /dev/null +++ b/system/gd/metrics/metrics_state.cc @@ -0,0 +1,227 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * 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: + * + * http://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. + */ + +#include "metrics_state.h" + +#include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h> +#include <frameworks/proto_logging/stats/enums/bluetooth/le/enums.pb.h> + +#include <chrono> +#include <climits> +#include <memory> +#include <unordered_map> +#include <utility> + +#include "common/strings.h" +#include "hci/address.h" +#include "metrics/utils.h" +#include "os/log.h" +#include "os/metrics.h" + +namespace bluetooth { +namespace metrics { + +using android::bluetooth::le::LeConnectionOriginType; +using android::bluetooth::le::LeConnectionState; +using android::bluetooth::le::LeConnectionType; + +// const static ClockTimePoint kInvalidTimePoint{}; + +/* + * This is the device level metrics state, which will be modified based on + * incoming state events. + * + */ +void LEConnectionMetricState::AddStateChangedEvent( + LeConnectionOriginType origin_type, + LeConnectionType connection_type, + LeConnectionState transaction_state, + std::vector<std::pair<os::ArgumentType, int>> argument_list) { + LOG_INFO( + "LEConnectionMetricState: Origin Type: %s, Connection Type: %s, Transaction State: " + "%s", + common::ToHexString(origin_type).c_str(), + common::ToHexString(connection_type).c_str(), + common::ToHexString(transaction_state).c_str()); + + ClockTimePoint current_timestamp = std::chrono::high_resolution_clock::now(); + state = transaction_state; + + // Assign the origin of the connection + if (connection_origin_type == LeConnectionOriginType::ORIGIN_UNSPECIFIED) { + connection_origin_type = origin_type; + } + + if (input_connection_type == LeConnectionType::CONNECTION_TYPE_UNSPECIFIED) { + input_connection_type = connection_type; + } + + if (start_timepoint == kInvalidTimePoint) { + start_timepoint = current_timestamp; + } + end_timepoint = current_timestamp; + + switch (state) { + case LeConnectionState::STATE_LE_ACL_END: { + int acl_status_code_from_args = + GetArgumentTypeFromList(argument_list, os::ArgumentType::ACL_STATUS_CODE); + acl_status_code = static_cast<android::bluetooth::hci::StatusEnum>(acl_status_code_from_args); + acl_state = LeAclConnectionState::LE_ACL_SUCCESS; + + if (acl_status_code != android::bluetooth::hci::StatusEnum::STATUS_SUCCESS) { + acl_state = LeAclConnectionState::LE_ACL_FAILED; + } + break; + } + case LeConnectionState::STATE_LE_ACL_TIMEOUT: { + int acl_status_code_from_args = + GetArgumentTypeFromList(argument_list, os::ArgumentType::ACL_STATUS_CODE); + acl_status_code = static_cast<android::bluetooth::hci::StatusEnum>(acl_status_code_from_args); + acl_state = LeAclConnectionState::LE_ACL_FAILED; + break; + } + case LeConnectionState::STATE_LE_ACL_CANCEL: { + acl_state = LeAclConnectionState::LE_ACL_FAILED; + is_cancelled = true; + break; + } + [[fallthrough]]; + default: { + // do nothing + } + } +} + +bool LEConnectionMetricState::IsEnded() { + return acl_state == LeAclConnectionState::LE_ACL_SUCCESS || + acl_state == LeAclConnectionState::LE_ACL_FAILED; +} + +bool LEConnectionMetricState::IsStarted() { + return state == LeConnectionState::STATE_LE_ACL_START; +} + +bool LEConnectionMetricState::IsCancelled() { + return is_cancelled; +} + +// Initialize the LEConnectionMetricsRemoteDevice +LEConnectionMetricsRemoteDevice::LEConnectionMetricsRemoteDevice() { + metrics_logger_module = new MetricsLoggerModule(); +} + +LEConnectionMetricsRemoteDevice::LEConnectionMetricsRemoteDevice( + BaseMetricsLoggerModule* baseMetricsLoggerModule) { + metrics_logger_module = baseMetricsLoggerModule; +} + +// Uploading the session +void LEConnectionMetricsRemoteDevice::UploadLEConnectionSession(const hci::Address& address) { + auto it = opened_devices.find(address); + if (it != opened_devices.end()) { + os::LEConnectionSessionOptions session_options; + session_options.acl_connection_state = it->second->acl_state; + session_options.origin_type = it->second->connection_origin_type; + session_options.transaction_type = it->second->input_connection_type; + session_options.latency = bluetooth::metrics::get_timedelta_nanos( + it->second->start_timepoint, it->second->end_timepoint); + session_options.remote_address = address; + session_options.status = it->second->acl_status_code; + // TODO: keep the acl latency the same as the overall latency for now + // When more events are added, we will an overall latency + session_options.acl_latency = session_options.latency; + session_options.is_cancelled = it->second->is_cancelled; + metrics_logger_module->LogMetricBluetoothLESession(session_options); + LOG_INFO( + "LEConnectionMetricsRemoteDevice: The session is uploaded for %s\n", + ADDRESS_TO_LOGGABLE_CSTR(address)); + opened_devices.erase(it); + } +} + +// Implementation of metrics per remote device +void LEConnectionMetricsRemoteDevice::AddStateChangedEvent( + const hci::Address& address, + LeConnectionOriginType origin_type, + LeConnectionType connection_type, + LeConnectionState transaction_state, + std::vector<std::pair<os::ArgumentType, int>> argument_list) { + LOG_INFO( + "LEConnectionMetricsRemoteDevice: Transaction State %s, Connection Type %s, Origin Type %s\n", + common::ToHexString(transaction_state).c_str(), + common::ToHexString(connection_type).c_str(), + common::ToHexString(origin_type).c_str()); + if (address.IsEmpty()) { + LOG_INFO( + "LEConnectionMetricsRemoteDevice: Empty Address Cancellation %s, %s, %s\n", + common::ToHexString(transaction_state).c_str(), + common::ToHexString(connection_type).c_str(), + common::ToHexString(transaction_state).c_str()); + for (auto& device_metric : device_metrics) { + if (device_metric->IsStarted() && + transaction_state == LeConnectionState::STATE_LE_ACL_CANCEL) { + LOG_INFO("LEConnectionMetricsRemoteDevice: Cancellation Begin"); + // cancel the connection + device_metric->AddStateChangedEvent( + origin_type, connection_type, transaction_state, argument_list); + continue; + } + + if (device_metric->IsCancelled() && + transaction_state == LeConnectionState::STATE_LE_ACL_END) { + LOG_INFO("LEConnectionMetricsRemoteDevice: Session is now complete after cancellation"); + // complete the connection + device_metric->AddStateChangedEvent( + origin_type, connection_type, transaction_state, argument_list); + UploadLEConnectionSession(address); + continue; + } + } + return; + } + + auto it = opened_devices.find(address); + if (it == opened_devices.end()) { + device_metrics.push_back(std::make_unique<LEConnectionMetricState>(address)); + it = opened_devices.insert(std::begin(opened_devices), {address, device_metrics.back().get()}); + } + + it->second->AddStateChangedEvent(origin_type, connection_type, transaction_state, argument_list); + + // Connection is finished + if (it->second->IsEnded()) { + UploadLEConnectionSession(address); + } +} + + +// MetricsLoggerModule class +void MetricsLoggerModule::LogMetricBluetoothLESession( + os::LEConnectionSessionOptions session_options) { + os::LogMetricBluetoothLEConnection(session_options); +} + +// Instance of Metrics Collector for LEConnectionMetricsRemoteDeviceImpl +LEConnectionMetricsRemoteDevice* MetricsCollector::le_connection_metrics_remote_device = + new LEConnectionMetricsRemoteDevice(); + +LEConnectionMetricsRemoteDevice* MetricsCollector::GetLEConnectionMetricsCollector() { + return MetricsCollector::le_connection_metrics_remote_device; +} + +} // namespace metrics + +} // namespace bluetooth diff --git a/system/gd/metrics/metrics_state.h b/system/gd/metrics/metrics_state.h new file mode 100644 index 0000000000..ca92501ce3 --- /dev/null +++ b/system/gd/metrics/metrics_state.h @@ -0,0 +1,122 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * 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: + * + * http://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. + */ + +#pragma once + +#include <frameworks/proto_logging/stats/enums/bluetooth/le/enums.pb.h> + +#include <chrono> +#include <cstdint> +#include <memory> +#include <unordered_map> +#include <utility> +#include <vector> + +#include "common/strings.h" +#include "hci/address.h" +#include "os/metrics.h" + +namespace bluetooth { + +namespace metrics { + +using android::bluetooth::le::LeAclConnectionState; +using android::bluetooth::le::LeConnectionOriginType; +using android::bluetooth::le::LeConnectionState; +using android::bluetooth::le::LeConnectionType; + +using ClockTimePoint = std::chrono::time_point<std::chrono::high_resolution_clock>; + +const static ClockTimePoint kInvalidTimePoint{}; + +inline int64_t get_timedelta_nanos(const ClockTimePoint& t1, const ClockTimePoint& t2) { + if (t1 == kInvalidTimePoint || t2 == kInvalidTimePoint) { + return -1; + } + return std::abs(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count()); +} + +class BaseMetricsLoggerModule { + public: + BaseMetricsLoggerModule() {} + virtual void LogMetricBluetoothLESession(os::LEConnectionSessionOptions session_options) = 0; + virtual ~BaseMetricsLoggerModule() {} +}; + +class MetricsLoggerModule : public BaseMetricsLoggerModule { + public: + MetricsLoggerModule() {} + void LogMetricBluetoothLESession(os::LEConnectionSessionOptions session_options); + virtual ~MetricsLoggerModule() {} +}; + +class LEConnectionMetricState { + public: + hci::Address address; + LEConnectionMetricState(const hci::Address address) : address(address) {} + LeConnectionState state; + LeAclConnectionState acl_state; + LeConnectionType input_connection_type = LeConnectionType::CONNECTION_TYPE_UNSPECIFIED; + android::bluetooth::hci::StatusEnum acl_status_code; + ClockTimePoint start_timepoint = kInvalidTimePoint; + ClockTimePoint end_timepoint = kInvalidTimePoint; + bool is_cancelled = false; + LeConnectionOriginType connection_origin_type = LeConnectionOriginType::ORIGIN_UNSPECIFIED; + + bool IsStarted(); + bool IsEnded(); + bool IsCancelled(); + + void AddStateChangedEvent( + LeConnectionOriginType origin_type, + LeConnectionType connection_type, + LeConnectionState transaction_state, + std::vector<std::pair<os::ArgumentType, int>> argument_list); + +}; + +class LEConnectionMetricsRemoteDevice { + public: + LEConnectionMetricsRemoteDevice(); + + LEConnectionMetricsRemoteDevice(BaseMetricsLoggerModule* baseMetricsLoggerModule); + + void AddStateChangedEvent( + const hci::Address& address, + LeConnectionOriginType origin_type, + LeConnectionType connection_type, + LeConnectionState transaction_state, + std::vector<std::pair<os::ArgumentType, int>> argument_list); + + void UploadLEConnectionSession(const hci::Address& address); + + private: + std::vector<std::unique_ptr<LEConnectionMetricState>> device_metrics; + std::unordered_map<hci::Address, LEConnectionMetricState*> opened_devices; + BaseMetricsLoggerModule* metrics_logger_module; +}; + +class MetricsCollector { + public: + // getting the LE Connection Metrics Collector + static LEConnectionMetricsRemoteDevice* GetLEConnectionMetricsCollector(); + + private: + static LEConnectionMetricsRemoteDevice* le_connection_metrics_remote_device; +}; + +} // namespace metrics +} // namespace bluetooth diff --git a/system/gd/metrics/metrics_state_unittest.cc b/system/gd/metrics/metrics_state_unittest.cc new file mode 100644 index 0000000000..435e5c09bb --- /dev/null +++ b/system/gd/metrics/metrics_state_unittest.cc @@ -0,0 +1,196 @@ +#include "metrics_state.h" + +#include <gmock/gmock.h> + +#include <cstdint> +#include <vector> + +#include "gtest/gtest.h" +#include "hci/address.h" +#include "metrics_state.h" +#include "os/metrics.h" + +// +using android::bluetooth::hci::StatusEnum; +using android::bluetooth::le::LeAclConnectionState; +using android::bluetooth::le::LeConnectionOriginType; +using android::bluetooth::le::LeConnectionState; +using android::bluetooth::le::LeConnectionType; + +LeAclConnectionState le_acl_state = LeAclConnectionState::LE_ACL_UNSPECIFIED; +LeConnectionOriginType origin_type = LeConnectionOriginType::ORIGIN_UNSPECIFIED; +LeConnectionType connection_type = LeConnectionType::CONNECTION_TYPE_UNSPECIFIED; +StatusEnum status = StatusEnum::STATUS_UNKNOWN; +bluetooth::hci::Address remote_address = bluetooth::hci::Address::kEmpty; +int latency = 0; +int acl_latency = 0; +bool is_cancelled = false; + +namespace bluetooth { +namespace metrics { + +const hci::Address address1 = hci::Address({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); +const hci::Address empty_address = hci::Address::kEmpty; + +class TestMetricsLoggerModule : public BaseMetricsLoggerModule { + public: + TestMetricsLoggerModule() {} + void LogMetricBluetoothLESession(os::LEConnectionSessionOptions session_options); + virtual ~TestMetricsLoggerModule() {} +}; + +void TestMetricsLoggerModule::LogMetricBluetoothLESession( + os::LEConnectionSessionOptions session_options) { + le_acl_state = session_options.acl_connection_state; + origin_type = session_options.origin_type; + connection_type = session_options.transaction_type; + is_cancelled = session_options.is_cancelled; + status = session_options.status; + remote_address = session_options.remote_address; +} + +class MockMetricsCollector { + public: + static LEConnectionMetricsRemoteDevice* GetLEConnectionMetricsCollector(); + + static LEConnectionMetricsRemoteDevice* le_connection_metrics_remote_device; +}; + + + +LEConnectionMetricsRemoteDevice* MockMetricsCollector::le_connection_metrics_remote_device = + new LEConnectionMetricsRemoteDevice(new TestMetricsLoggerModule()); + +LEConnectionMetricsRemoteDevice* MockMetricsCollector::GetLEConnectionMetricsCollector() { + return MockMetricsCollector::le_connection_metrics_remote_device; +} + +namespace { + +class LEConnectionMetricsRemoteDeviceTest : public ::testing::Test {}; + +TEST(LEConnectionMetricsRemoteDeviceTest, Initialize) { + ASSERT_EQ(0, 0); +} + +TEST(LEConnectionMetricsRemoteDeviceTest, ConnectionSuccess) { + auto argument_list = std::vector<std::pair<os::ArgumentType, int>>(); + argument_list.push_back(std::make_pair( + os::ArgumentType::ACL_STATUS_CODE, + static_cast<int>(android::bluetooth::hci::StatusEnum::STATUS_SUCCESS))); + + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_START, + argument_list); + + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_END, + argument_list); + // assert that these are equal + ASSERT_EQ(le_acl_state, LeAclConnectionState::LE_ACL_SUCCESS); + ASSERT_EQ(origin_type, LeConnectionOriginType::ORIGIN_NATIVE); + ASSERT_EQ(connection_type, LeConnectionType::CONNECTION_TYPE_LE_ACL); + ASSERT_EQ(remote_address, address1); + ASSERT_EQ(is_cancelled, false); +} + +TEST(LEConnectionMetricsRemoteDeviceTest, ConnectionFailed) { + auto argument_list = std::vector<std::pair<os::ArgumentType, int>>(); + argument_list.push_back(std::make_pair( + os::ArgumentType::ACL_STATUS_CODE, + static_cast<int>(android::bluetooth::hci::StatusEnum::STATUS_NO_CONNECTION))); + + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_START, + argument_list); + + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_END, + argument_list); + // assert that these are equal + ASSERT_EQ(le_acl_state, LeAclConnectionState::LE_ACL_FAILED); + ASSERT_EQ(origin_type, LeConnectionOriginType::ORIGIN_NATIVE); + ASSERT_EQ(connection_type, LeConnectionType::CONNECTION_TYPE_LE_ACL); + ASSERT_EQ(remote_address, address1); + ASSERT_EQ(is_cancelled, false); +} + +TEST(LEConnectionMetricsRemoteDeviceTest, Cancellation) { + auto argument_list = std::vector<std::pair<os::ArgumentType, int>>(); + auto no_connection_argument_list = std::vector<std::pair<os::ArgumentType, int>>(); + no_connection_argument_list.push_back(std::make_pair( + os::ArgumentType::ACL_STATUS_CODE, + static_cast<int>(android::bluetooth::hci::StatusEnum::STATUS_NO_CONNECTION))); + + // Start of the LE-ACL Connection + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_START, + argument_list); + + // Cancellation of the LE-ACL Connection + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + empty_address, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_CANCEL, + argument_list); + + // Ending of the LE-ACL Connection + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_END, + no_connection_argument_list); + + ASSERT_EQ(le_acl_state, LeAclConnectionState::LE_ACL_FAILED); + ASSERT_EQ(origin_type, LeConnectionOriginType::ORIGIN_NATIVE); + ASSERT_EQ(connection_type, LeConnectionType::CONNECTION_TYPE_LE_ACL); + ASSERT_EQ(remote_address, address1); + ASSERT_EQ(is_cancelled, true); +} + +TEST(LEConnectionMetricsRemoteDeviceTest, Timeout) { + auto argument_list = std::vector<std::pair<os::ArgumentType, int>>(); + + // Start of the LE-ACL Connection + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_START, + argument_list); + + // Timeout of the LE-ACL Connection + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_TIMEOUT, + argument_list); + + ASSERT_EQ(le_acl_state, LeAclConnectionState::LE_ACL_FAILED); + ASSERT_EQ(origin_type, LeConnectionOriginType::ORIGIN_NATIVE); + ASSERT_EQ(connection_type, LeConnectionType::CONNECTION_TYPE_LE_ACL); + ASSERT_EQ(remote_address, address1); + ASSERT_EQ(is_cancelled, false); +} + +} // namespace +} // namespace metrics +} // namespace bluetooth diff --git a/system/gd/metrics/utils.cc b/system/gd/metrics/utils.cc index b059bb7133..40520e461b 100644 --- a/system/gd/metrics/utils.cc +++ b/system/gd/metrics/utils.cc @@ -35,5 +35,17 @@ bool GetBootId(std::string* boot_id) { return true; } +int GetArgumentTypeFromList( + std::vector<std::pair<os::ArgumentType, int>>& argument_list, os::ArgumentType argumentType) { + for (std::pair<os::ArgumentType, int> argumentPair : argument_list) { + if (argumentPair.first == argumentType) { + return argumentPair.second; + } + } + return -1; +} + + + } // namespace metrics } // namespace bluetooth diff --git a/system/gd/metrics/utils.h b/system/gd/metrics/utils.h index d6f25373dc..78ab5427b2 100644 --- a/system/gd/metrics/utils.h +++ b/system/gd/metrics/utils.h @@ -16,11 +16,17 @@ #pragma once #include <string> +#include <utility> +#include <vector> + +#include "os/metrics.h" namespace bluetooth { namespace metrics { bool GetBootId(std::string* boot_id); +int GetArgumentTypeFromList( + std::vector<std::pair<os::ArgumentType, int>>& argument_list, os::ArgumentType argumentType); } // namespace metrics -} // namespace bluetooth
\ No newline at end of file +} // namespace bluetooth diff --git a/system/gd/os/android/metrics.cc b/system/gd/os/android/metrics.cc index c9c66e50dd..f45d282817 100644 --- a/system/gd/os/android/metrics.cc +++ b/system/gd/os/android/metrics.cc @@ -23,6 +23,7 @@ #include <statslog_bt.h> #include "common/audit_log.h" +#include "metrics/metrics_state.h" #include "common/metric_id_manager.h" #include "common/strings.h" #include "hci/hci_packets.h" @@ -511,5 +512,44 @@ void LogMetricBluetoothCodePathCounterMetrics(int32_t key, int64_t count) { } } +void LogMetricBluetoothLEConnectionMetricEvent( + const Address& address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector<std::pair<os::ArgumentType, int>>& argument_list) { + bluetooth::metrics::MetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address, origin_type, connection_type, transaction_state, argument_list); +} + +void LogMetricBluetoothLEConnection(os::LEConnectionSessionOptions session_options) { + int metric_id = 0; + if (!session_options.remote_address.IsEmpty()) { + metric_id = MetricIdManager::GetInstance().AllocateId(session_options.remote_address); + } + int ret = stats_write( + BLUETOOTH_LE_SESSION_CONNECTED, + session_options.acl_connection_state, + session_options.origin_type, + session_options.transaction_type, + session_options.transaction_state, + session_options.latency, + metric_id, + session_options.app_uid, + session_options.acl_latency, + session_options.status, + session_options.is_cancelled); + + if (ret < 0) { + LOG_WARN( + "Failed BluetoothLeSessionConnected - Address: %s, ACL Connection State: %s, Origin Type: " + "%s", + ADDRESS_TO_LOGGABLE_CSTR(session_options.remote_address), + common::ToHexString(session_options.acl_connection_state).c_str(), + common::ToHexString(session_options.origin_type).c_str()); + } +} + } // namespace os } // namespace bluetooth + diff --git a/system/gd/os/host/metrics.cc b/system/gd/os/host/metrics.cc index a163b8c30a..3de27662e8 100644 --- a/system/gd/os/host/metrics.cc +++ b/system/gd/os/host/metrics.cc @@ -122,5 +122,15 @@ void LogMetricBluetoothRemoteSupportedFeatures( const Address& address, uint32_t page, uint64_t features, uint32_t connection_handle) {} void LogMetricBluetoothCodePathCounterMetrics(int32_t key, int64_t count) {} + +void LogMetricBluetoothLEConnectionMetricEvent( + const Address& address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector<std::pair<os::ArgumentType, int>>& argument_list) {} + +void LogMetricBluetoothLEConnection(os::LEConnectionSessionOptions session_options) {} + } // namespace os } // namespace bluetooth diff --git a/system/gd/os/linux/metrics.cc b/system/gd/os/linux/metrics.cc index d70cb3c027..fb0a26b42e 100644 --- a/system/gd/os/linux/metrics.cc +++ b/system/gd/os/linux/metrics.cc @@ -123,5 +123,12 @@ void LogMetricBluetoothRemoteSupportedFeatures( void LogMetricBluetoothCodePathCounterMetrics(int32_t key, int64_t count) {} +void LogMetricBluetoothLEConnectionMetricEvent( + const Address& address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector<std::pair<os::ArgumentType, int>>& argument_list) {} + } // namespace os } // namespace bluetooth diff --git a/system/gd/os/metrics.h b/system/gd/os/metrics.h index 27b6aefb87..e16919fa5a 100644 --- a/system/gd/os/metrics.h +++ b/system/gd/os/metrics.h @@ -20,6 +20,7 @@ #include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h> #include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h> +#include <frameworks/proto_logging/stats/enums/bluetooth/le/enums.pb.h> #include "hci/address.h" @@ -294,6 +295,47 @@ void LogMetricBluetoothRemoteSupportedFeatures( const hci::Address& address, uint32_t page, uint64_t features, uint32_t connection_handle); void LogMetricBluetoothCodePathCounterMetrics(int32_t key, int64_t count); -} // namespace os +using android::bluetooth::le::LeAclConnectionState; +using android::bluetooth::le::LeConnectionOriginType; +using android::bluetooth::le::LeConnectionType; +using android::bluetooth::le::LeConnectionState; +// Adding options +struct LEConnectionSessionOptions { + // Contains the state of the LE-ACL Connection + LeAclConnectionState acl_connection_state = LeAclConnectionState::LE_ACL_UNSPECIFIED; + // Origin of the transaction + LeConnectionOriginType origin_type = LeConnectionOriginType::ORIGIN_UNSPECIFIED; + // Connection Type + LeConnectionType transaction_type = LeConnectionType::CONNECTION_TYPE_UNSPECIFIED; + // Transaction State + LeConnectionState transaction_state = LeConnectionState::STATE_UNSPECIFIED; + // Latency of the entire transaction + int64_t latency = 0; + // Address of the remote device + hci::Address remote_address = hci::Address::kEmpty; + // UID associated with the device + int app_uid = 0; + // Latency of the ACL Transaction + int64_t acl_latency = 0; + // Contains the error code associated with the ACL Connection if failed + android::bluetooth::hci::StatusEnum status = android::bluetooth::hci::StatusEnum::STATUS_UNKNOWN; + // Cancelled connection + bool is_cancelled = false; +}; + +// Argument Type +enum ArgumentType { GATT_IF, L2CAP_PSM, L2CAP_CID, APP_UID, ACL_STATUS_CODE }; +void LogMetricBluetoothLEConnectionMetricEvent( + const hci::Address& address, + LeConnectionOriginType origin_type, + LeConnectionType connection_type, + LeConnectionState transaction_state, + std::vector<std::pair<os::ArgumentType, int>>& argument_list); + +// Upload LE Session +void LogMetricBluetoothLEConnection(os::LEConnectionSessionOptions session_options); + +} // namespace os + // } // namespace bluetooth diff --git a/system/main/shim/metrics_api.cc b/system/main/shim/metrics_api.cc index 9637ff4929..5ef1bd16a4 100644 --- a/system/main/shim/metrics_api.cc +++ b/system/main/shim/metrics_api.cc @@ -155,5 +155,17 @@ bool CountCounterMetrics(int32_t key, int64_t count) { } return counter_metrics->Count(key, count); } + +void LogMetricBluetoothLEConnectionMetricEvent( + const RawAddress& raw_address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector<std::pair<os::ArgumentType, int>> argument_list) { + + Address address = bluetooth::ToGdAddress(raw_address); + bluetooth::os::LogMetricBluetoothLEConnectionMetricEvent(address, origin_type, connection_type, transaction_state, argument_list); +} + } // namespace shim } // namespace bluetooth diff --git a/system/main/shim/metrics_api.h b/system/main/shim/metrics_api.h index 6661d6a916..2540fbdc12 100644 --- a/system/main/shim/metrics_api.h +++ b/system/main/shim/metrics_api.h @@ -18,9 +18,11 @@ #include <frameworks/proto_logging/stats/enums/bluetooth/enums.pb.h> #include <frameworks/proto_logging/stats/enums/bluetooth/hci/enums.pb.h> +#include <frameworks/proto_logging/stats/enums/bluetooth/le/enums.pb.h> #include <unordered_map> #include "types/raw_address.h" +#include "metrics/metrics_state.h" namespace bluetooth { namespace shim { @@ -220,5 +222,12 @@ void LogMetricManufacturerInfo( const std::string& software_version); bool CountCounterMetrics(int32_t key, int64_t count); + +void LogMetricBluetoothLEConnectionMetricEvent( + const RawAddress& raw_address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector<std::pair<os::ArgumentType, int>> argument_list); } // namespace shim } // namespace bluetooth diff --git a/system/stack/acl/btm_acl.cc b/system/stack/acl/btm_acl.cc index 9241b613f9..c8ab5238ee 100644 --- a/system/stack/acl/btm_acl.cc +++ b/system/stack/acl/btm_acl.cc @@ -44,12 +44,14 @@ #include "device/include/controller.h" #include "device/include/device_iot_config.h" #include "device/include/interop.h" +#include "gd/metrics/metrics_state.h" #include "include/l2cap_hci_link_interface.h" #include "main/shim/acl_api.h" #include "main/shim/btm_api.h" #include "main/shim/controller.h" #include "main/shim/dumpsys.h" #include "main/shim/l2c_api.h" +#include "main/shim/metrics_api.h" #include "main/shim/shim.h" #include "osi/include/allocator.h" #include "osi/include/log.h" @@ -73,6 +75,7 @@ #include "stack/include/sco_hci_link_interface.h" #include "types/hci_role.h" #include "types/raw_address.h" +#include "os/metrics.h" #ifndef PROPERTY_LINK_SUPERVISION_TIMEOUT #define PROPERTY_LINK_SUPERVISION_TIMEOUT \ @@ -2831,6 +2834,15 @@ bool acl_create_le_connection_with_id(uint8_t id, const RawAddress& bd_addr, return false; } + // argument list + auto argument_list = std::vector<std::pair<bluetooth::os::ArgumentType, int>>(); + + bluetooth::shim::LogMetricBluetoothLEConnectionMetricEvent( + bd_addr, android::bluetooth::le::LeConnectionOriginType::ORIGIN_NATIVE, + android::bluetooth::le::LeConnectionType::CONNECTION_TYPE_LE_ACL, + android::bluetooth::le::LeConnectionState::STATE_LE_ACL_START, + argument_list); + bluetooth::shim::ACL_AcceptLeConnectionFrom(address_with_type, /* is_direct */ true); return true; diff --git a/system/test/mock/mock_main_shim_metrics_api.cc b/system/test/mock/mock_main_shim_metrics_api.cc index ae8e3feef2..4be7bd0e29 100644 --- a/system/test/mock/mock_main_shim_metrics_api.cc +++ b/system/test/mock/mock_main_shim_metrics_api.cc @@ -184,6 +184,16 @@ void bluetooth::shim::LogMetricManufacturerInfo( bool bluetooth::shim::CountCounterMetrics(int32_t key, int64_t count) { inc_func_call_count(__func__); return false; + +} +void bluetooth::shim::LogMetricBluetoothLEConnectionMetricEvent( + const RawAddress& raw_address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector<std::pair<bluetooth::os::ArgumentType, int>> argument_list) { + inc_func_call_count(__func__); + // test::mock::main_shim_metrics_api::LogMetricBluetoothLEConnectionMetricEvent(raw_address, origin_type, connection_type, transaction_state, argument_list); } // END mockcify generation diff --git a/system/test/mock/mock_main_shim_metrics_api.h b/system/test/mock/mock_main_shim_metrics_api.h index 646e463ba5..c8b850eced 100644 --- a/system/test/mock/mock_main_shim_metrics_api.h +++ b/system/test/mock/mock_main_shim_metrics_api.h @@ -39,6 +39,8 @@ #include "main/shim/helpers.h" #include "main/shim/metrics_api.h" #include "types/raw_address.h" +#include <frameworks/proto_logging/stats/enums/bluetooth/le/enums.pb.h> + // Mocked compile conditionals, if any #ifndef UNUSED_ATTR @@ -297,6 +299,40 @@ struct LogMetricManufacturerInfo { }; extern struct LogMetricManufacturerInfo LogMetricManufacturerInfo; +// Name: LogMetricBluetoothLEConnectionMetricEvent +// Params: const RawAddress& raw_address, +// android::bluetooth::le::LeConnectionOriginType origin_type, +// android::bluetooth::le::LeConnectionType connection_type, +// android::bluetooth::le::LeConnectionState transaction_state, +// std::vector<std::pair<bluetooth::metrics::ArgumentType, int>> +// argument_list +struct LogMetricBluetoothLEConnectionMetricEvent { + std::function<void( + const RawAddress& raw_address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector<std::pair<bluetooth::os::ArgumentType, int>> + argument_list)> + body{[](const RawAddress& raw_address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState + transaction_state, + std::vector<std::pair<bluetooth::os::ArgumentType, int>> + argument_list) {}}; + void operator()( + const RawAddress& raw_address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector<std::pair<bluetooth::os::ArgumentType, int>> + argument_list) { + body(raw_address, origin_type, connection_type, transaction_state, + argument_list); + }; +}; + } // namespace main_shim_metrics_api } // namespace mock } // namespace test |