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