• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "metrics_collector.h"
18 
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 #include <unistd.h>
22 
23 #include <cstdint>
24 #include <vector>
25 
26 #include "os/metrics.h"
27 #include "types/raw_address.h"
28 
29 using testing::_;
30 using testing::AnyNumber;
31 using testing::AtLeast;
32 using testing::AtMost;
33 using testing::DoAll;
34 using testing::Invoke;
35 using testing::Mock;
36 using testing::MockFunction;
37 using testing::NotNull;
38 using testing::Return;
39 using testing::SaveArg;
40 using testing::SetArgPointee;
41 using testing::Test;
42 using testing::WithArg;
43 
44 int log_count = 0;
45 int32_t last_group_size;
46 int32_t last_group_metric_id;
47 int64_t last_connection_duration_nanos;
48 int64_t last_broadcast_duration_nanos;
49 std::vector<int64_t> last_device_connecting_offset_nanos;
50 std::vector<int64_t> last_device_connected_offset_nanos;
51 std::vector<int64_t> last_device_connection_duration_nanos;
52 std::vector<int32_t> last_device_connection_status;
53 std::vector<int32_t> last_device_disconnection_status;
54 std::vector<RawAddress> last_device_address;
55 std::vector<int64_t> last_streaming_offset_nanos;
56 std::vector<int64_t> last_streaming_duration_nanos;
57 std::vector<int32_t> last_streaming_context_type;
58 
59 namespace bluetooth {
60 namespace os {
61 
LogMetricLeAudioConnectionSessionReported(int32_t group_size,int32_t group_metric_id,int64_t connection_duration_nanos,const std::vector<int64_t> & device_connecting_offset_nanos,const std::vector<int64_t> & device_connected_offset_nanos,const std::vector<int64_t> & device_connection_duration_nanos,const std::vector<int32_t> & device_connection_status,const std::vector<int32_t> & device_disconnection_status,const std::vector<RawAddress> & device_address,const std::vector<int64_t> & streaming_offset_nanos,const std::vector<int64_t> & streaming_duration_nanos,const std::vector<int32_t> & streaming_context_type)62 void LogMetricLeAudioConnectionSessionReported(
63         int32_t group_size, int32_t group_metric_id, int64_t connection_duration_nanos,
64         const std::vector<int64_t>& device_connecting_offset_nanos,
65         const std::vector<int64_t>& device_connected_offset_nanos,
66         const std::vector<int64_t>& device_connection_duration_nanos,
67         const std::vector<int32_t>& device_connection_status,
68         const std::vector<int32_t>& device_disconnection_status,
69         const std::vector<RawAddress>& device_address,
70         const std::vector<int64_t>& streaming_offset_nanos,
71         const std::vector<int64_t>& streaming_duration_nanos,
72         const std::vector<int32_t>& streaming_context_type) {
73   log_count++;
74   last_group_size = group_size;
75   last_group_metric_id = group_metric_id;
76   last_connection_duration_nanos = connection_duration_nanos;
77   last_device_connecting_offset_nanos = device_connecting_offset_nanos;
78   last_device_connected_offset_nanos = device_connected_offset_nanos;
79   last_device_connection_duration_nanos = device_connection_duration_nanos;
80   last_device_connection_status = device_connection_status;
81   last_device_disconnection_status = device_disconnection_status;
82   last_device_address = device_address;
83   last_streaming_offset_nanos = streaming_offset_nanos;
84   last_streaming_duration_nanos = streaming_duration_nanos;
85   last_streaming_context_type = streaming_context_type;
86 }
87 
LogMetricLeAudioBroadcastSessionReported(int64_t duration_nanos)88 void LogMetricLeAudioBroadcastSessionReported(int64_t duration_nanos) {
89   last_broadcast_duration_nanos = duration_nanos;
90 }
91 
92 }  // namespace os
93 }  // namespace bluetooth
94 
95 namespace bluetooth::le_audio {
96 
97 const int32_t group_id1 = 1;
98 const RawAddress device1 = RawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x66});
99 
100 const int32_t group_id2 = 2;
101 const RawAddress device2 = RawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x67});
102 const RawAddress device3 = RawAddress({0x11, 0x22, 0x33, 0x44, 0x55, 0x68});
103 
104 class MockMetricsCollector : public MetricsCollector {
105 public:
MockMetricsCollector()106   MockMetricsCollector() {}
107 };
108 
109 class MetricsCollectorTest : public Test {
110 protected:
111   std::unique_ptr<MetricsCollector> collector;
112 
SetUp()113   void SetUp() override {
114     collector = std::make_unique<MockMetricsCollector>();
115 
116     log_count = 0;
117     last_group_size = 0;
118     last_group_metric_id = 0;
119     last_broadcast_duration_nanos = 0;
120     last_connection_duration_nanos = 0;
121     last_device_connecting_offset_nanos = {};
122     last_device_connected_offset_nanos = {};
123     last_device_connection_duration_nanos = {};
124     last_device_connection_status = {};
125     last_device_disconnection_status = {};
126     last_device_address = {};
127     last_streaming_offset_nanos = {};
128     last_streaming_duration_nanos = {};
129     last_streaming_context_type = {};
130   }
131 
TearDown()132   void TearDown() override { collector = nullptr; }
133 };
134 
TEST_F(MetricsCollectorTest,Initialize)135 TEST_F(MetricsCollectorTest, Initialize) { ASSERT_EQ(log_count, 0); }
136 
TEST_F(MetricsCollectorTest,ConnectionFailed)137 TEST_F(MetricsCollectorTest, ConnectionFailed) {
138   collector->OnConnectionStateChanged(group_id1, device1,
139                                       bluetooth::le_audio::ConnectionState::CONNECTING,
140                                       ConnectionStatus::UNKNOWN);
141   collector->OnConnectionStateChanged(group_id1, device1,
142                                       bluetooth::le_audio::ConnectionState::CONNECTED,
143                                       ConnectionStatus::FAILED);
144 
145   ASSERT_EQ(log_count, 1);
146   ASSERT_EQ(last_group_metric_id, group_id1);
147   ASSERT_EQ(last_device_connecting_offset_nanos.size(), 1UL);
148   ASSERT_EQ(last_device_connection_status.size(), 1UL);
149   ASSERT_EQ(last_device_connection_status.back(), ConnectionStatus::FAILED);
150 }
151 
TEST_F(MetricsCollectorTest,ConnectingConnectedDisconnected)152 TEST_F(MetricsCollectorTest, ConnectingConnectedDisconnected) {
153   collector->OnConnectionStateChanged(group_id1, device1,
154                                       bluetooth::le_audio::ConnectionState::CONNECTING,
155                                       ConnectionStatus::UNKNOWN);
156   collector->OnConnectionStateChanged(group_id1, device1,
157                                       bluetooth::le_audio::ConnectionState::CONNECTED,
158                                       ConnectionStatus::SUCCESS);
159   collector->OnConnectionStateChanged(group_id1, device1,
160                                       bluetooth::le_audio::ConnectionState::DISCONNECTED,
161                                       ConnectionStatus::SUCCESS);
162 
163   ASSERT_EQ(log_count, 1);
164   ASSERT_EQ(last_group_metric_id, group_id1);
165   ASSERT_EQ(last_device_connecting_offset_nanos.size(), 1UL);
166   ASSERT_EQ(last_device_connection_status.size(), 1UL);
167   ASSERT_EQ(last_device_disconnection_status.size(), 1UL);
168   ASSERT_EQ(last_device_connecting_offset_nanos.size(), 1UL);
169   ASSERT_EQ(last_device_connected_offset_nanos.size(), 1UL);
170   ASSERT_EQ(last_device_connection_duration_nanos.size(), 1UL);
171   ASSERT_EQ(last_device_connection_status.back(), ConnectionStatus::SUCCESS);
172   ASSERT_EQ(last_device_disconnection_status.back(), ConnectionStatus::SUCCESS);
173 }
174 
TEST_F(MetricsCollectorTest,SingleDeviceTwoConnections)175 TEST_F(MetricsCollectorTest, SingleDeviceTwoConnections) {
176   collector->OnConnectionStateChanged(group_id1, device1,
177                                       bluetooth::le_audio::ConnectionState::CONNECTING,
178                                       ConnectionStatus::UNKNOWN);
179   collector->OnConnectionStateChanged(group_id1, device1,
180                                       bluetooth::le_audio::ConnectionState::CONNECTED,
181                                       ConnectionStatus::SUCCESS);
182   collector->OnConnectionStateChanged(group_id1, device1,
183                                       bluetooth::le_audio::ConnectionState::DISCONNECTED,
184                                       ConnectionStatus::SUCCESS);
185 
186   ASSERT_EQ(log_count, 1);
187   ASSERT_EQ(last_group_metric_id, group_id1);
188   ASSERT_EQ(last_device_connecting_offset_nanos.size(), 1UL);
189   ASSERT_EQ(last_device_connection_status.size(), 1UL);
190   ASSERT_EQ(last_device_disconnection_status.size(), 1UL);
191   ASSERT_EQ(last_device_connecting_offset_nanos.size(), 1UL);
192   ASSERT_EQ(last_device_connected_offset_nanos.size(), 1UL);
193   ASSERT_EQ(last_device_connection_duration_nanos.size(), 1UL);
194   ASSERT_EQ(last_device_connection_status.back(), ConnectionStatus::SUCCESS);
195   ASSERT_EQ(last_device_disconnection_status.back(), ConnectionStatus::SUCCESS);
196 
197   collector->OnConnectionStateChanged(group_id1, device1,
198                                       bluetooth::le_audio::ConnectionState::CONNECTING,
199                                       ConnectionStatus::UNKNOWN);
200   collector->OnConnectionStateChanged(group_id1, device1,
201                                       bluetooth::le_audio::ConnectionState::CONNECTED,
202                                       ConnectionStatus::SUCCESS);
203   collector->OnConnectionStateChanged(group_id1, device1,
204                                       bluetooth::le_audio::ConnectionState::DISCONNECTED,
205                                       ConnectionStatus::SUCCESS);
206 
207   ASSERT_EQ(log_count, 2);
208   ASSERT_EQ(last_group_metric_id, group_id1);
209   ASSERT_EQ(last_device_connecting_offset_nanos.size(), 1UL);
210   ASSERT_EQ(last_device_connection_status.size(), 1UL);
211   ASSERT_EQ(last_device_disconnection_status.size(), 1UL);
212   ASSERT_EQ(last_device_connecting_offset_nanos.size(), 1UL);
213   ASSERT_EQ(last_device_connected_offset_nanos.size(), 1UL);
214   ASSERT_EQ(last_device_connection_duration_nanos.size(), 1UL);
215   ASSERT_EQ(last_device_connection_status.back(), ConnectionStatus::SUCCESS);
216   ASSERT_EQ(last_device_disconnection_status.back(), ConnectionStatus::SUCCESS);
217 }
218 
TEST_F(MetricsCollectorTest,StereoGroupBasicTest)219 TEST_F(MetricsCollectorTest, StereoGroupBasicTest) {
220   collector->OnConnectionStateChanged(group_id2, device2,
221                                       bluetooth::le_audio::ConnectionState::CONNECTING,
222                                       ConnectionStatus::UNKNOWN);
223   collector->OnConnectionStateChanged(group_id2, device2,
224                                       bluetooth::le_audio::ConnectionState::CONNECTED,
225                                       ConnectionStatus::SUCCESS);
226   collector->OnConnectionStateChanged(group_id2, device3,
227                                       bluetooth::le_audio::ConnectionState::CONNECTED,
228                                       ConnectionStatus::SUCCESS);
229   collector->OnConnectionStateChanged(group_id2, device3,
230                                       bluetooth::le_audio::ConnectionState::DISCONNECTED,
231                                       ConnectionStatus::SUCCESS);
232   collector->OnConnectionStateChanged(group_id2, device2,
233                                       bluetooth::le_audio::ConnectionState::DISCONNECTED,
234                                       ConnectionStatus::SUCCESS);
235 
236   ASSERT_EQ(log_count, 1);
237   ASSERT_EQ(last_group_metric_id, group_id2);
238   ASSERT_EQ(last_device_connecting_offset_nanos.size(), 2UL);
239   ASSERT_EQ(last_device_connection_status.size(), 2UL);
240   ASSERT_EQ(last_device_disconnection_status.size(), 2UL);
241   ASSERT_EQ(last_device_connecting_offset_nanos.size(), 2UL);
242   ASSERT_EQ(last_device_connected_offset_nanos.size(), 2UL);
243   ASSERT_EQ(last_device_connection_duration_nanos.size(), 2UL);
244 }
245 
TEST_F(MetricsCollectorTest,StereoGroupMultiReconnections)246 TEST_F(MetricsCollectorTest, StereoGroupMultiReconnections) {
247   collector->OnConnectionStateChanged(group_id2, device2,
248                                       bluetooth::le_audio::ConnectionState::CONNECTING,
249                                       ConnectionStatus::UNKNOWN);
250   collector->OnConnectionStateChanged(group_id2, device2,
251                                       bluetooth::le_audio::ConnectionState::CONNECTED,
252                                       ConnectionStatus::SUCCESS);
253   collector->OnConnectionStateChanged(group_id2, device3,
254                                       bluetooth::le_audio::ConnectionState::CONNECTED,
255                                       ConnectionStatus::SUCCESS);
256   collector->OnConnectionStateChanged(group_id2, device3,
257                                       bluetooth::le_audio::ConnectionState::DISCONNECTED,
258                                       ConnectionStatus::SUCCESS);
259   collector->OnConnectionStateChanged(group_id2, device3,
260                                       bluetooth::le_audio::ConnectionState::CONNECTED,
261                                       ConnectionStatus::SUCCESS);
262   collector->OnConnectionStateChanged(group_id2, device3,
263                                       bluetooth::le_audio::ConnectionState::DISCONNECTED,
264                                       ConnectionStatus::SUCCESS);
265   collector->OnConnectionStateChanged(group_id2, device2,
266                                       bluetooth::le_audio::ConnectionState::DISCONNECTED,
267                                       ConnectionStatus::SUCCESS);
268 
269   ASSERT_EQ(log_count, 1);
270   ASSERT_EQ(last_group_metric_id, group_id2);
271   ASSERT_EQ(last_device_connecting_offset_nanos.size(), 3UL);
272   ASSERT_EQ(last_device_connection_status.size(), 3UL);
273   ASSERT_EQ(last_device_disconnection_status.size(), 3UL);
274   ASSERT_EQ(last_device_connecting_offset_nanos.size(), 3UL);
275   ASSERT_EQ(last_device_connected_offset_nanos.size(), 3UL);
276   ASSERT_EQ(last_device_connection_duration_nanos.size(), 3UL);
277 }
278 
TEST_F(MetricsCollectorTest,MixGroups)279 TEST_F(MetricsCollectorTest, MixGroups) {
280   collector->OnConnectionStateChanged(group_id1, device1,
281                                       bluetooth::le_audio::ConnectionState::CONNECTING,
282                                       ConnectionStatus::UNKNOWN);
283   collector->OnConnectionStateChanged(group_id1, device1,
284                                       bluetooth::le_audio::ConnectionState::CONNECTED,
285                                       ConnectionStatus::SUCCESS);
286   collector->OnConnectionStateChanged(group_id2, device2,
287                                       bluetooth::le_audio::ConnectionState::CONNECTING,
288                                       ConnectionStatus::UNKNOWN);
289   collector->OnConnectionStateChanged(group_id2, device2,
290                                       bluetooth::le_audio::ConnectionState::CONNECTED,
291                                       ConnectionStatus::SUCCESS);
292   collector->OnConnectionStateChanged(group_id2, device3,
293                                       bluetooth::le_audio::ConnectionState::CONNECTED,
294                                       ConnectionStatus::SUCCESS);
295   collector->OnConnectionStateChanged(group_id2, device3,
296                                       bluetooth::le_audio::ConnectionState::DISCONNECTED,
297                                       ConnectionStatus::SUCCESS);
298   collector->OnConnectionStateChanged(group_id2, device2,
299                                       bluetooth::le_audio::ConnectionState::DISCONNECTED,
300                                       ConnectionStatus::SUCCESS);
301 
302   ASSERT_EQ(log_count, 1);
303   ASSERT_EQ(last_group_metric_id, group_id2);
304   ASSERT_EQ(last_device_connecting_offset_nanos.size(), 2UL);
305   ASSERT_EQ(last_device_connection_status.size(), 2UL);
306   ASSERT_EQ(last_device_disconnection_status.size(), 2UL);
307   ASSERT_EQ(last_device_connecting_offset_nanos.size(), 2UL);
308   ASSERT_EQ(last_device_connected_offset_nanos.size(), 2UL);
309   ASSERT_EQ(last_device_connection_duration_nanos.size(), 2UL);
310 
311   collector->OnConnectionStateChanged(group_id1, device1,
312                                       bluetooth::le_audio::ConnectionState::DISCONNECTED,
313                                       ConnectionStatus::SUCCESS);
314 
315   ASSERT_EQ(log_count, 2);
316   ASSERT_EQ(last_group_metric_id, group_id1);
317   ASSERT_EQ(last_device_connecting_offset_nanos.size(), 1UL);
318   ASSERT_EQ(last_device_connection_status.size(), 1UL);
319   ASSERT_EQ(last_device_disconnection_status.size(), 1UL);
320   ASSERT_EQ(last_device_connecting_offset_nanos.size(), 1UL);
321   ASSERT_EQ(last_device_connected_offset_nanos.size(), 1UL);
322   ASSERT_EQ(last_device_connection_duration_nanos.size(), 1UL);
323 }
324 
TEST_F(MetricsCollectorTest,GroupSizeUpdated)325 TEST_F(MetricsCollectorTest, GroupSizeUpdated) {
326   collector->OnGroupSizeUpdate(group_id2, 1);
327   collector->OnGroupSizeUpdate(group_id1, 2);
328   collector->OnConnectionStateChanged(group_id1, device1,
329                                       bluetooth::le_audio::ConnectionState::CONNECTING,
330                                       ConnectionStatus::UNKNOWN);
331   collector->OnConnectionStateChanged(group_id1, device1,
332                                       bluetooth::le_audio::ConnectionState::CONNECTED,
333                                       ConnectionStatus::SUCCESS);
334   collector->OnConnectionStateChanged(group_id1, device1,
335                                       bluetooth::le_audio::ConnectionState::DISCONNECTED,
336                                       ConnectionStatus::SUCCESS);
337 
338   ASSERT_EQ(log_count, 1);
339   ASSERT_EQ(last_group_metric_id, group_id1);
340   ASSERT_EQ(last_group_size, 2);
341 }
342 
TEST_F(MetricsCollectorTest,StreamingSessions)343 TEST_F(MetricsCollectorTest, StreamingSessions) {
344   collector->OnConnectionStateChanged(group_id1, device1,
345                                       bluetooth::le_audio::ConnectionState::CONNECTING,
346                                       ConnectionStatus::UNKNOWN);
347   collector->OnConnectionStateChanged(group_id1, device1,
348                                       bluetooth::le_audio::ConnectionState::CONNECTED,
349                                       ConnectionStatus::SUCCESS);
350   collector->OnStreamStarted(group_id1, bluetooth::le_audio::types::LeAudioContextType::MEDIA);
351   collector->OnStreamEnded(group_id1);
352   collector->OnStreamStarted(group_id1,
353                              bluetooth::le_audio::types::LeAudioContextType::CONVERSATIONAL);
354   collector->OnStreamEnded(group_id1);
355   collector->OnConnectionStateChanged(group_id1, device1,
356                                       bluetooth::le_audio::ConnectionState::DISCONNECTED,
357                                       ConnectionStatus::SUCCESS);
358 
359   ASSERT_EQ(log_count, 1);
360   ASSERT_EQ(last_group_metric_id, group_id1);
361   ASSERT_EQ(last_streaming_offset_nanos.size(), 2UL);
362   ASSERT_EQ(last_streaming_duration_nanos.size(), 2UL);
363   ASSERT_EQ(last_streaming_context_type.size(), 2UL);
364 
365   ASSERT_GT(last_streaming_offset_nanos[0], 0L);
366   ASSERT_GT(last_streaming_offset_nanos[1], 0L);
367   ASSERT_GT(last_streaming_duration_nanos[0], 0L);
368   ASSERT_GT(last_streaming_duration_nanos[1], 0L);
369   ASSERT_EQ(last_streaming_context_type[0], static_cast<int32_t>(LeAudioMetricsContextType::MEDIA));
370   ASSERT_EQ(last_streaming_context_type[1],
371             static_cast<int32_t>(LeAudioMetricsContextType::COMMUNICATION));
372 }
373 
TEST_F(MetricsCollectorTest,BroadastSessions)374 TEST_F(MetricsCollectorTest, BroadastSessions) {
375   last_broadcast_duration_nanos = 0;
376   collector->OnBroadcastStateChanged(true);
377   collector->OnBroadcastStateChanged(false);
378   ASSERT_GT(last_broadcast_duration_nanos, 0);
379   last_broadcast_duration_nanos = 0;
380   collector->OnBroadcastStateChanged(true);
381   collector->OnBroadcastStateChanged(false);
382   ASSERT_GT(last_broadcast_duration_nanos, 0);
383 }
384 
385 }  // namespace bluetooth::le_audio
386