• 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 "types/raw_address.h"
27 
28 using testing::_;
29 using testing::AnyNumber;
30 using testing::AtLeast;
31 using testing::AtMost;
32 using testing::DoAll;
33 using testing::Invoke;
34 using testing::Mock;
35 using testing::MockFunction;
36 using testing::NotNull;
37 using testing::Return;
38 using testing::SaveArg;
39 using testing::SetArgPointee;
40 using testing::Test;
41 using testing::WithArg;
42 
43 int log_count = 0;
44 int32_t last_group_size;
45 int32_t last_group_metric_id;
46 int64_t last_connection_duration_nanos;
47 int64_t last_broadcast_duration_nanos;
48 std::vector<int64_t> last_device_connecting_offset_nanos;
49 std::vector<int64_t> last_device_connected_offset_nanos;
50 std::vector<int64_t> last_device_connection_duration_nanos;
51 std::vector<int32_t> last_device_connection_status;
52 std::vector<int32_t> last_device_disconnection_status;
53 std::vector<RawAddress> last_device_address;
54 std::vector<int64_t> last_streaming_offset_nanos;
55 std::vector<int64_t> last_streaming_duration_nanos;
56 std::vector<int32_t> last_streaming_context_type;
57 
58 namespace bluetooth {
59 namespace common {
60 
LogLeAudioConnectionSessionReported(int32_t group_size,int32_t group_metric_id,int64_t connection_duration_nanos,std::vector<int64_t> & device_connecting_offset_nanos,std::vector<int64_t> & device_connected_offset_nanos,std::vector<int64_t> & device_connection_duration_nanos,std::vector<int32_t> & device_connection_status,std::vector<int32_t> & device_disconnection_status,std::vector<RawAddress> & device_address,std::vector<int64_t> & streaming_offset_nanos,std::vector<int64_t> & streaming_duration_nanos,std::vector<int32_t> & streaming_context_type)61 void LogLeAudioConnectionSessionReported(
62     int32_t group_size, int32_t group_metric_id,
63     int64_t connection_duration_nanos,
64     std::vector<int64_t>& device_connecting_offset_nanos,
65     std::vector<int64_t>& device_connected_offset_nanos,
66     std::vector<int64_t>& device_connection_duration_nanos,
67     std::vector<int32_t>& device_connection_status,
68     std::vector<int32_t>& device_disconnection_status,
69     std::vector<RawAddress>& device_address,
70     std::vector<int64_t>& streaming_offset_nanos,
71     std::vector<int64_t>& streaming_duration_nanos,
72     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 
LogLeAudioBroadcastSessionReported(int64_t duration_nanos)88 void LogLeAudioBroadcastSessionReported(int64_t duration_nanos) {
89   last_broadcast_duration_nanos = duration_nanos;
90 }
91 
92 }  // namespace common
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(
139       group_id1, device1, bluetooth::le_audio::ConnectionState::CONNECTING,
140       ConnectionStatus::UNKNOWN);
141   collector->OnConnectionStateChanged(
142       group_id1, device1, 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(
154       group_id1, device1, bluetooth::le_audio::ConnectionState::CONNECTING,
155       ConnectionStatus::UNKNOWN);
156   collector->OnConnectionStateChanged(
157       group_id1, device1, bluetooth::le_audio::ConnectionState::CONNECTED,
158       ConnectionStatus::SUCCESS);
159   collector->OnConnectionStateChanged(
160       group_id1, device1, 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(
177       group_id1, device1, bluetooth::le_audio::ConnectionState::CONNECTING,
178       ConnectionStatus::UNKNOWN);
179   collector->OnConnectionStateChanged(
180       group_id1, device1, bluetooth::le_audio::ConnectionState::CONNECTED,
181       ConnectionStatus::SUCCESS);
182   collector->OnConnectionStateChanged(
183       group_id1, device1, 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(
198       group_id1, device1, bluetooth::le_audio::ConnectionState::CONNECTING,
199       ConnectionStatus::UNKNOWN);
200   collector->OnConnectionStateChanged(
201       group_id1, device1, bluetooth::le_audio::ConnectionState::CONNECTED,
202       ConnectionStatus::SUCCESS);
203   collector->OnConnectionStateChanged(
204       group_id1, device1, 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(
221       group_id2, device2, bluetooth::le_audio::ConnectionState::CONNECTING,
222       ConnectionStatus::UNKNOWN);
223   collector->OnConnectionStateChanged(
224       group_id2, device2, bluetooth::le_audio::ConnectionState::CONNECTED,
225       ConnectionStatus::SUCCESS);
226   collector->OnConnectionStateChanged(
227       group_id2, device3, bluetooth::le_audio::ConnectionState::CONNECTED,
228       ConnectionStatus::SUCCESS);
229   collector->OnConnectionStateChanged(
230       group_id2, device3, bluetooth::le_audio::ConnectionState::DISCONNECTED,
231       ConnectionStatus::SUCCESS);
232   collector->OnConnectionStateChanged(
233       group_id2, device2, 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(
248       group_id2, device2, bluetooth::le_audio::ConnectionState::CONNECTING,
249       ConnectionStatus::UNKNOWN);
250   collector->OnConnectionStateChanged(
251       group_id2, device2, bluetooth::le_audio::ConnectionState::CONNECTED,
252       ConnectionStatus::SUCCESS);
253   collector->OnConnectionStateChanged(
254       group_id2, device3, bluetooth::le_audio::ConnectionState::CONNECTED,
255       ConnectionStatus::SUCCESS);
256   collector->OnConnectionStateChanged(
257       group_id2, device3, bluetooth::le_audio::ConnectionState::DISCONNECTED,
258       ConnectionStatus::SUCCESS);
259   collector->OnConnectionStateChanged(
260       group_id2, device3, bluetooth::le_audio::ConnectionState::CONNECTED,
261       ConnectionStatus::SUCCESS);
262   collector->OnConnectionStateChanged(
263       group_id2, device3, bluetooth::le_audio::ConnectionState::DISCONNECTED,
264       ConnectionStatus::SUCCESS);
265   collector->OnConnectionStateChanged(
266       group_id2, device2, 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(
281       group_id1, device1, bluetooth::le_audio::ConnectionState::CONNECTING,
282       ConnectionStatus::UNKNOWN);
283   collector->OnConnectionStateChanged(
284       group_id1, device1, bluetooth::le_audio::ConnectionState::CONNECTED,
285       ConnectionStatus::SUCCESS);
286   collector->OnConnectionStateChanged(
287       group_id2, device2, bluetooth::le_audio::ConnectionState::CONNECTING,
288       ConnectionStatus::UNKNOWN);
289   collector->OnConnectionStateChanged(
290       group_id2, device2, bluetooth::le_audio::ConnectionState::CONNECTED,
291       ConnectionStatus::SUCCESS);
292   collector->OnConnectionStateChanged(
293       group_id2, device3, bluetooth::le_audio::ConnectionState::CONNECTED,
294       ConnectionStatus::SUCCESS);
295   collector->OnConnectionStateChanged(
296       group_id2, device3, bluetooth::le_audio::ConnectionState::DISCONNECTED,
297       ConnectionStatus::SUCCESS);
298   collector->OnConnectionStateChanged(
299       group_id2, device2, 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(
312       group_id1, device1, 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(
329       group_id1, device1, bluetooth::le_audio::ConnectionState::CONNECTING,
330       ConnectionStatus::UNKNOWN);
331   collector->OnConnectionStateChanged(
332       group_id1, device1, bluetooth::le_audio::ConnectionState::CONNECTED,
333       ConnectionStatus::SUCCESS);
334   collector->OnConnectionStateChanged(
335       group_id1, device1, 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(
345       group_id1, device1, bluetooth::le_audio::ConnectionState::CONNECTING,
346       ConnectionStatus::UNKNOWN);
347   collector->OnConnectionStateChanged(
348       group_id1, device1, bluetooth::le_audio::ConnectionState::CONNECTED,
349       ConnectionStatus::SUCCESS);
350   collector->OnStreamStarted(
351       group_id1, bluetooth::le_audio::types::LeAudioContextType::MEDIA);
352   collector->OnStreamEnded(group_id1);
353   collector->OnStreamStarted(
354       group_id1,
355       bluetooth::le_audio::types::LeAudioContextType::CONVERSATIONAL);
356   collector->OnStreamEnded(group_id1);
357   collector->OnConnectionStateChanged(
358       group_id1, device1, bluetooth::le_audio::ConnectionState::DISCONNECTED,
359       ConnectionStatus::SUCCESS);
360 
361   ASSERT_EQ(log_count, 1);
362   ASSERT_EQ(last_group_metric_id, group_id1);
363   ASSERT_EQ(last_streaming_offset_nanos.size(), 2UL);
364   ASSERT_EQ(last_streaming_duration_nanos.size(), 2UL);
365   ASSERT_EQ(last_streaming_context_type.size(), 2UL);
366 
367   ASSERT_GT(last_streaming_offset_nanos[0], 0L);
368   ASSERT_GT(last_streaming_offset_nanos[1], 0L);
369   ASSERT_GT(last_streaming_duration_nanos[0], 0L);
370   ASSERT_GT(last_streaming_duration_nanos[1], 0L);
371   ASSERT_EQ(last_streaming_context_type[0],
372             static_cast<int32_t>(LeAudioMetricsContextType::MEDIA));
373   ASSERT_EQ(last_streaming_context_type[1],
374             static_cast<int32_t>(LeAudioMetricsContextType::COMMUNICATION));
375 }
376 
TEST_F(MetricsCollectorTest,BroadastSessions)377 TEST_F(MetricsCollectorTest, BroadastSessions) {
378   last_broadcast_duration_nanos = 0;
379   collector->OnBroadcastStateChanged(true);
380   collector->OnBroadcastStateChanged(false);
381   ASSERT_GT(last_broadcast_duration_nanos, 0);
382   last_broadcast_duration_nanos = 0;
383   collector->OnBroadcastStateChanged(true);
384   collector->OnBroadcastStateChanged(false);
385   ASSERT_GT(last_broadcast_duration_nanos, 0);
386 }
387 
388 }  // namespace bluetooth::le_audio