145d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski/****************************************************************************** 245d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski * 345d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski * Copyright (C) 2016 Google, Inc. 445d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski * 545d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski * Licensed under the Apache License, Version 2.0 (the "License"); 645d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski * you may not use this file except in compliance with the License. 745d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski * You may obtain a copy of the License at: 845d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski * 945d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski * http://www.apache.org/licenses/LICENSE-2.0 1045d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski * 1145d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski * Unless required by applicable law or agreed to in writing, software 1245d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski * distributed under the License is distributed on an "AS IS" BASIS, 1345d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1445d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski * See the License for the specific language governing permissions and 1545d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski * limitations under the License. 1645d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski * 1745d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski ******************************************************************************/ 1845d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski#define LOG_TAG "bt_osi_metrics" 1945d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski 20f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#include <unistd.h> 21f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#include <algorithm> 22f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#include <cerrno> 23f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#include <chrono> 24f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#include <cstdint> 25f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#include <cstring> 26f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#include <memory> 27f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#include <mutex> 28f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 29f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#include <base/base64.h> 30f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#include <base/logging.h> 31f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 32f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#include "osi/include/leaky_bonded_queue.h" 33f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#include "osi/include/log.h" 34f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#include "osi/include/osi.h" 35f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#include "osi/include/time.h" 36f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 3745d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski#include "osi/include/metrics.h" 3845d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski 39f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Henamespace system_bt_osi { 40f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 41f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He// Maximum number of log entries for each repeated field 42f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#define MAX_NUM_BLUETOOTH_SESSION 50 43f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#define MAX_NUM_PAIR_EVENT 50 44f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#define MAX_NUM_WAKE_EVENT 50 45f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He#define MAX_NUM_SCAN_EVENT 50 46f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 47f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hestatic float combine_averages(float avg_a, int64_t ct_a, float avg_b, 48f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He int64_t ct_b) { 49f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He if (ct_a > 0 && ct_b > 0) { 50f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He return (avg_a * ct_a + avg_b * ct_b) / (ct_a + ct_b); 51f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } else if (ct_b > 0) { 52f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He return avg_b; 53f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } else { 54f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He return avg_a; 55f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } 5645d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski} 5745d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski 58f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hestatic int32_t combine_averages(int32_t avg_a, int64_t ct_a, int32_t avg_b, 59f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He int64_t ct_b) { 60f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He if (ct_a > 0 && ct_b > 0) { 61f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He return (avg_a * ct_a + avg_b * ct_b) / (ct_a + ct_b); 62f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } else if (ct_b > 0) { 63f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He return avg_b; 64f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } else { 65f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He return avg_a; 66f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } 6745d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski} 6845d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski 69f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hevoid A2dpSessionMetrics::Update(const A2dpSessionMetrics& metrics) { 70f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He if (metrics.audio_duration_ms > 0) { 71f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He audio_duration_ms = std::max(static_cast<int64_t>(0), audio_duration_ms); 72f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He audio_duration_ms += metrics.audio_duration_ms; 73f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } 74f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He if (metrics.media_timer_min_ms > 0) { 75f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He if (media_timer_min_ms < 0) { 76f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He media_timer_min_ms = metrics.media_timer_min_ms; 77f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } else { 78f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He media_timer_min_ms = 79f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He std::min(media_timer_min_ms, metrics.media_timer_min_ms); 80f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } 81f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } 82f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He if (metrics.media_timer_max_ms > 0) { 83f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He media_timer_max_ms = 84f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He std::max(media_timer_max_ms, metrics.media_timer_max_ms); 85f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } 86f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He if (metrics.media_timer_avg_ms > 0 && metrics.total_scheduling_count > 0) { 87f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He if (media_timer_avg_ms < 0 || total_scheduling_count < 0) { 88f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He media_timer_avg_ms = metrics.media_timer_avg_ms; 89f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He total_scheduling_count = metrics.total_scheduling_count; 90f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } else { 91f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He media_timer_avg_ms = combine_averages( 92f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He media_timer_avg_ms, total_scheduling_count, 93f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He metrics.media_timer_avg_ms, metrics.total_scheduling_count); 94f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He total_scheduling_count += metrics.total_scheduling_count; 95f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } 96f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } 97f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He if (metrics.buffer_overruns_max_count > 0) { 98f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He buffer_overruns_max_count = 99f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He std::max(buffer_overruns_max_count, metrics.buffer_overruns_max_count); 100f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } 101f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He if (metrics.buffer_overruns_total > 0) { 102f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He buffer_overruns_total = 103f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He std::max(static_cast<int32_t>(0), buffer_overruns_total); 104f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He buffer_overruns_total += metrics.buffer_overruns_total; 105f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } 106f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He if (metrics.buffer_underruns_average > 0 && 107f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He metrics.buffer_underruns_count > 0) { 108f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He if (buffer_underruns_average < 0 || buffer_underruns_count < 0) { 109f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He buffer_underruns_average = metrics.buffer_underruns_average; 110f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He buffer_underruns_count = metrics.buffer_underruns_count; 111f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } else { 112f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He buffer_underruns_average = combine_averages( 113f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He metrics.buffer_underruns_average, metrics.buffer_underruns_count, 114f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He buffer_underruns_average, buffer_underruns_count); 115f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He buffer_underruns_count += metrics.buffer_underruns_count; 116f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } 117f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He } 11845d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski} 11945d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski 120f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hebool A2dpSessionMetrics::operator==(const A2dpSessionMetrics& rhs) const { 121f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He return audio_duration_ms == rhs.audio_duration_ms && 122f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He media_timer_min_ms == rhs.media_timer_min_ms && 123f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He media_timer_max_ms == rhs.media_timer_max_ms && 124f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He media_timer_avg_ms == rhs.media_timer_avg_ms && 125f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He total_scheduling_count == rhs.total_scheduling_count && 126f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He buffer_overruns_max_count == rhs.buffer_overruns_max_count && 127f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He buffer_overruns_total == rhs.buffer_overruns_total && 128f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He buffer_underruns_average == rhs.buffer_underruns_average && 129f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He buffer_underruns_count == rhs.buffer_underruns_count; 13045d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski} 13145d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski 132f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hestruct BluetoothMetricsLogger::impl { 133f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He // TODO(siyuanh): Implement for linux 134f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He}; 135f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 136f3175629208a64b190dde4dcf5f92cacef70d3e9Jack HeBluetoothMetricsLogger::BluetoothMetricsLogger() : pimpl_(new impl) {} 137f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 138f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hevoid BluetoothMetricsLogger::LogPairEvent(uint32_t disconnect_reason, 139f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He uint64_t timestamp_ms, 140f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He uint32_t device_class, 141f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He device_type_t device_type) { 142f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He // TODO(siyuanh): Implement for linux 14345d129394a71a112e28567f47faf89d365bca0a0Jakub Pawlowski} 144f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 145f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hevoid BluetoothMetricsLogger::LogWakeEvent(wake_event_type_t type, 146f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He const std::string& requestor, 147f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He const std::string& name, 148f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He uint64_t timestamp_ms) { 149f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He // TODO(siyuanh): Implement for linux 150f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He} 151f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 152f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hevoid BluetoothMetricsLogger::LogScanEvent(bool start, 153f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He const std::string& initator, 154f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He scan_tech_t type, uint32_t results, 155f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He uint64_t timestamp_ms) { 156f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He // TODO(siyuanh): Implement for linux 157f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He} 158f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 159f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hevoid BluetoothMetricsLogger::LogBluetoothSessionStart( 160f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He connection_tech_t connection_tech_type, uint64_t timestamp_ms) { 161f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He // TODO(siyuanh): Implement for linux 162f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He} 163f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 164f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hevoid BluetoothMetricsLogger::LogBluetoothSessionEnd( 165a386df9ac18ec8f54d2ad0dd0af0fd7cc5ecaefdJakub Pawlowski disconnect_reason_t disconnect_reason, uint64_t timestamp_ms) { 166f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He // TODO(siyuanh): Implement for linux 167f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He} 168f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 169f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hevoid BluetoothMetricsLogger::LogBluetoothSessionDeviceInfo( 170f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He uint32_t device_class, device_type_t device_type) { 171f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He // TODO(siyuanh): Implement for linux 172f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He} 173f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 174f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hevoid BluetoothMetricsLogger::LogA2dpSession( 175f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He const A2dpSessionMetrics& a2dp_session_metrics) { 176f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He // TODO(siyuanh): Implement for linux 177f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He} 178f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 179f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hevoid BluetoothMetricsLogger::WriteString(std::string* serialized, bool clear) { 180f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He // TODO(siyuanh): Implement for linux 181f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He} 182f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 183f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hevoid BluetoothMetricsLogger::WriteBase64String(std::string* serialized, 184f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He bool clear) { 185f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He // TODO(siyuanh): Implement for linux 186f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He} 187f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 188f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hevoid BluetoothMetricsLogger::WriteBase64(int fd, bool clear) { 189f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He // TODO(siyuanh): Implement for linux 190f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He} 191f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 192f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hevoid BluetoothMetricsLogger::CutoffSession() { 193f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He // TODO(siyuanh): Implement for linux 194f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He} 195f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 196f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hevoid BluetoothMetricsLogger::Build() { 197f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He // TODO(siyuanh): Implement for linux 198f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He} 199f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 200f3175629208a64b190dde4dcf5f92cacef70d3e9Jack Hevoid BluetoothMetricsLogger::Reset() { 201f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He // TODO(siyuanh): Implement for linux 202f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He} 203f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He 204f3175629208a64b190dde4dcf5f92cacef70d3e9Jack He} // namespace system_bt_osi 205