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