blob: 478355bfa27b5ae97f775e32016e25bc47a12d48 [file] [log] [blame]
Andy Hungc89c8dc2019-10-16 17:48:21 -07001/*
2 * Copyright (C) 2019 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#define LOG_TAG "mediametrics_tests"
18#include <utils/Log.h>
19
Ray Essick40e8e5e2019-12-05 20:19:40 -080020#include "MediaMetricsService.h"
Andy Hungc89c8dc2019-10-16 17:48:21 -070021
22#include <stdio.h>
Andy Hunga629bd12020-06-05 16:03:53 -070023#include <unordered_set>
Andy Hungc89c8dc2019-10-16 17:48:21 -070024
25#include <gtest/gtest.h>
Ray Essickf27e9872019-12-07 06:28:46 -080026#include <media/MediaMetricsItem.h>
Andy Hunga629bd12020-06-05 16:03:53 -070027#include <system/audio.h>
28
29#include "AudioTypes.h"
30#include "StringUtils.h"
Andy Hungc89c8dc2019-10-16 17:48:21 -070031
32using namespace android;
33
Andy Hung06f3aba2019-12-03 16:36:42 -080034static size_t countNewlines(const char *s) {
35 size_t count = 0;
36 while ((s = strchr(s, '\n')) != nullptr) {
37 ++s;
38 ++count;
39 }
40 return count;
41}
42
Andy Hunga629bd12020-06-05 16:03:53 -070043template <typename M>
44ssize_t countDuplicates(const M& map) {
45 std::unordered_set<typename M::mapped_type> s;
46 for (const auto &m : map) {
47 s.emplace(m.second);
48 }
49 return map.size() - s.size();
50}
51
Andy Hung37de9b72020-01-02 13:54:05 -080052TEST(mediametrics_tests, startsWith) {
53 std::string s("test");
54 ASSERT_EQ(true, android::mediametrics::startsWith(s, "te"));
55 ASSERT_EQ(true, android::mediametrics::startsWith(s, std::string("tes")));
56 ASSERT_EQ(false, android::mediametrics::startsWith(s, "ts"));
57 ASSERT_EQ(false, android::mediametrics::startsWith(s, std::string("est")));
58}
59
60TEST(mediametrics_tests, defer) {
61 bool check = false;
62 {
63 android::mediametrics::Defer defer([&] { check = true; });
64 ASSERT_EQ(false, check);
65 }
66 ASSERT_EQ(true, check);
67}
68
Andy Hung0f7ad8c2020-01-03 13:24:34 -080069TEST(mediametrics_tests, shared_ptr_wrap) {
70 // Test shared pointer wrap with simple access
71 android::mediametrics::SharedPtrWrap<std::string> s("123");
72 ASSERT_EQ('1', s->at(0));
73 ASSERT_EQ('2', s->at(1));
74 s->push_back('4');
75 ASSERT_EQ('4', s->at(3));
76
77 const android::mediametrics::SharedPtrWrap<std::string> s2("345");
78 ASSERT_EQ('3', s2->operator[](0)); // s2[0] == '3'
79 // we allow modification through a const shared pointer wrap
80 // for compatibility with shared_ptr.
81 s2->push_back('6');
82 ASSERT_EQ('6', s2->operator[](3)); // s2[3] == '6'
83
84 android::mediametrics::SharedPtrWrap<std::string> s3("");
85 s3.set(std::make_shared<std::string>("abc"));
86 ASSERT_EQ('b', s3->operator[](1)); // s2[1] = 'b';
87
88 // Use Thunk to check whether the destructor was called prematurely
89 // when setting the shared ptr wrap in the middle of a method.
90
91 class Thunk {
92 std::function<void(int)> mF;
93 const int mFinal;
94
95 public:
Andy Hungb744faf2020-04-09 13:09:26 -070096 explicit Thunk(decltype(mF) f, int final) : mF(std::move(f)), mFinal(final) {}
Andy Hung0f7ad8c2020-01-03 13:24:34 -080097 ~Thunk() { mF(mFinal); }
98 void thunk(int value) { mF(value); }
99 };
100
101 int counter = 0;
102 android::mediametrics::SharedPtrWrap<Thunk> s4(
103 [&](int value) {
104 s4.set(std::make_shared<Thunk>([](int){}, 0)); // recursively set s4 while in s4.
105 ++counter;
106 ASSERT_EQ(value, counter); // on thunk() value is 1, on destructor this is 2.
107 }, 2);
108
109 // This will fail if the shared ptr wrap doesn't hold a ref count during method access.
110 s4->thunk(1);
111}
112
113TEST(mediametrics_tests, lock_wrap) {
114 // Test lock wrap with simple access
115 android::mediametrics::LockWrap<std::string> s("123");
116 ASSERT_EQ('1', s->at(0));
117 ASSERT_EQ('2', s->at(1));
118 s->push_back('4');
119 ASSERT_EQ('4', s->at(3));
120
121 const android::mediametrics::LockWrap<std::string> s2("345");
122 ASSERT_EQ('3', s2->operator[](0)); // s2[0] == '3'
123 // note: we can't modify s2 due to const, s2->push_back('6');
124
125 android::mediametrics::LockWrap<std::string> s3("");
126 s3->operator=("abc");
127 ASSERT_EQ('b', s3->operator[](1)); // s2[1] = 'b';
128
Andy Hung42b99302020-01-10 12:01:18 -0800129 // Check that we can recursively hold lock.
130 android::mediametrics::LockWrap<std::vector<int>> v{std::initializer_list<int>{1, 2}};
131 v->push_back(3);
132 v->push_back(4);
133 ASSERT_EQ(1, v->operator[](0));
134 ASSERT_EQ(2, v->operator[](1));
135 ASSERT_EQ(3, v->operator[](2));
136 ASSERT_EQ(4, v->operator[](3));
137 // The end of the full expression here requires recursive depth of 4.
138 ASSERT_EQ(10, v->operator[](0) + v->operator[](1) + v->operator[](2) + v->operator[](3));
139
140 // Mikhail's note: a non-recursive lock implementation could be used if one obtains
141 // the LockedPointer helper object like this and directly hold the lock through RAII,
142 // though it is trickier in use.
143 //
144 // We include an example here for completeness.
145 {
146 auto l = v.operator->();
147 ASSERT_EQ(10, l->operator[](0) + l->operator[](1) + l->operator[](2) + l->operator[](3));
148 }
149
Andy Hung0f7ad8c2020-01-03 13:24:34 -0800150 // Use Thunk to check whether we have the lock when calling a method through LockWrap.
151
152 class Thunk {
153 std::function<void()> mF;
154
155 public:
Andy Hungb744faf2020-04-09 13:09:26 -0700156 explicit Thunk(decltype(mF) f) : mF(std::move(f)) {}
Andy Hung0f7ad8c2020-01-03 13:24:34 -0800157 void thunk() { mF(); }
158 };
159
160 android::mediametrics::LockWrap<Thunk> s4([&]{
Andy Hung42b99302020-01-10 12:01:18 -0800161 ASSERT_EQ((size_t)1, s4.getRecursionDepth()); // we must be locked when thunk() is called.
Andy Hung0f7ad8c2020-01-03 13:24:34 -0800162 });
163
Andy Hung42b99302020-01-10 12:01:18 -0800164 ASSERT_EQ((size_t)0, s4.getRecursionDepth());
Andy Hung0f7ad8c2020-01-03 13:24:34 -0800165 // This will fail if we are not locked during method access.
166 s4->thunk();
Andy Hung42b99302020-01-10 12:01:18 -0800167 ASSERT_EQ((size_t)0, s4.getRecursionDepth());
Andy Hung0f7ad8c2020-01-03 13:24:34 -0800168}
169
170TEST(mediametrics_tests, lock_wrap_multithread) {
171 class Accumulator {
172 int32_t value_ = 0;
173 public:
174 void add(int32_t incr) {
175 const int32_t temp = value_;
176 sleep(0); // yield
177 value_ = temp + incr;
178 }
179 int32_t get() { return value_; }
180 };
181
182 android::mediametrics::LockWrap<Accumulator> a{}; // locked accumulator succeeds
183 // auto a = std::make_shared<Accumulator>(); // this fails, only 50% adds atomic.
184
185 constexpr size_t THREADS = 100;
186 constexpr size_t ITERATIONS = 10;
187 constexpr int32_t INCREMENT = 1;
188
189 std::vector<std::future<void>> threads(THREADS);
190 for (size_t i = 0; i < THREADS; ++i) {
191 threads.push_back(std::async(std::launch::async, [&] {
192 for (size_t j = 0; j < ITERATIONS; ++j) {
193 a->add(INCREMENT);
194 }
195 }));
196 }
197 threads.clear();
198
199 // If the add operations are not atomic, value will be smaller than expected.
200 ASSERT_EQ(INCREMENT * THREADS * ITERATIONS, (size_t)a->get());
201}
202
Andy Hungc89c8dc2019-10-16 17:48:21 -0700203TEST(mediametrics_tests, instantiate) {
Ray Essickf27e9872019-12-07 06:28:46 -0800204 sp mediaMetrics = new MediaMetricsService();
Andy Hungc89c8dc2019-10-16 17:48:21 -0700205 status_t status;
206
Andy Hungc89c8dc2019-10-16 17:48:21 -0700207 // random keys ignored when empty
Ray Essickf27e9872019-12-07 06:28:46 -0800208 std::unique_ptr<mediametrics::Item> random_key(mediametrics::Item::create("random_key"));
Andy Hunga87e69c2019-10-18 10:07:40 -0700209 status = mediaMetrics->submit(random_key.get());
210 ASSERT_EQ(PERMISSION_DENIED, status);
Andy Hungc89c8dc2019-10-16 17:48:21 -0700211
212 // random keys ignored with data
Andy Hungc89c8dc2019-10-16 17:48:21 -0700213 random_key->setInt32("foo", 10);
Andy Hunga87e69c2019-10-18 10:07:40 -0700214 status = mediaMetrics->submit(random_key.get());
215 ASSERT_EQ(PERMISSION_DENIED, status);
Andy Hungc89c8dc2019-10-16 17:48:21 -0700216
217 // known keys ignored if empty
Ray Essickf27e9872019-12-07 06:28:46 -0800218 std::unique_ptr<mediametrics::Item> audiotrack_key(mediametrics::Item::create("audiotrack"));
Andy Hunga87e69c2019-10-18 10:07:40 -0700219 status = mediaMetrics->submit(audiotrack_key.get());
220 ASSERT_EQ(BAD_VALUE, status);
Andy Hungc89c8dc2019-10-16 17:48:21 -0700221
Andy Hunga87e69c2019-10-18 10:07:40 -0700222 // known keys not ignored if not empty
223 audiotrack_key->addInt32("foo", 10);
224 status = mediaMetrics->submit(audiotrack_key.get());
225 ASSERT_EQ(NO_ERROR, status);
Andy Hungc89c8dc2019-10-16 17:48:21 -0700226
Andy Hungaeef7882019-10-18 15:18:14 -0700227
228 /*
229 // fluent style that goes directly to mediametrics
Ray Essickf27e9872019-12-07 06:28:46 -0800230 ASSERT_EQ(true, mediametrics::Item("audiorecord")
Andy Hungaeef7882019-10-18 15:18:14 -0700231 .setInt32("value", 2)
232 .addInt32("bar", 1)
233 .addInt32("value", 3)
234 .selfrecord());
235 */
236
Andy Hungc89c8dc2019-10-16 17:48:21 -0700237 mediaMetrics->dump(fileno(stdout), {} /* args */);
238}
Andy Hungaeef7882019-10-18 15:18:14 -0700239
Andy Hunga85efab2019-12-23 11:41:29 -0800240TEST(mediametrics_tests, package_installer_check) {
241 ASSERT_EQ(false, MediaMetricsService::useUidForPackage(
242 "abcd", "installer")); // ok, package name has no dot.
243 ASSERT_EQ(false, MediaMetricsService::useUidForPackage(
244 "android.com", "installer")); // ok, package name starts with android
245
246 ASSERT_EQ(false, MediaMetricsService::useUidForPackage(
247 "abc.def", "com.android.foo")); // ok, installer name starts with com.android
248 ASSERT_EQ(false, MediaMetricsService::useUidForPackage(
249 "123.456", "com.google.bar")); // ok, installer name starts with com.google
250 ASSERT_EQ(false, MediaMetricsService::useUidForPackage(
251 "r2.d2", "preload")); // ok, installer name is preload
252
253 ASSERT_EQ(true, MediaMetricsService::useUidForPackage(
254 "abc.def", "installer")); // unknown installer
255 ASSERT_EQ(true, MediaMetricsService::useUidForPackage(
256 "123.456", "installer")); // unknown installer
257 ASSERT_EQ(true, MediaMetricsService::useUidForPackage(
258 "r2.d2", "preload23")); // unknown installer
259
260 ASSERT_EQ(true, MediaMetricsService::useUidForPackage(
261 "com.android.foo", "abc.def")); // unknown installer
262 ASSERT_EQ(true, MediaMetricsService::useUidForPackage(
263 "com.google.bar", "123.456")); // unknown installer
264}
265
Andy Hungaeef7882019-10-18 15:18:14 -0700266TEST(mediametrics_tests, item_manipulation) {
Ray Essickf27e9872019-12-07 06:28:46 -0800267 mediametrics::Item item("audiorecord");
Andy Hungaeef7882019-10-18 15:18:14 -0700268
269 item.setInt32("value", 2).addInt32("bar", 3).addInt32("value", 4);
270
271 int32_t i32;
272 ASSERT_TRUE(item.getInt32("value", &i32));
273 ASSERT_EQ(6, i32);
274
275 ASSERT_TRUE(item.getInt32("bar", &i32));
276 ASSERT_EQ(3, i32);
277
278 item.setInt64("big", INT64_MAX).setInt64("smaller", INT64_MAX - 1).addInt64("smaller", -2);
279
280 int64_t i64;
281 ASSERT_TRUE(item.getInt64("big", &i64));
282 ASSERT_EQ(INT64_MAX, i64);
283
284 ASSERT_TRUE(item.getInt64("smaller", &i64));
285 ASSERT_EQ(INT64_MAX - 3, i64);
286
287 item.setDouble("precise", 10.5).setDouble("small", 0.125).addDouble("precise", 0.25);
288
289 double d;
290 ASSERT_TRUE(item.getDouble("precise", &d));
291 ASSERT_EQ(10.75, d);
292
293 ASSERT_TRUE(item.getDouble("small", &d));
294 ASSERT_EQ(0.125, d);
295
296 char *s;
297 item.setCString("name", "Frank").setCString("mother", "June").setCString("mother", "July");
298 ASSERT_TRUE(item.getCString("name", &s));
299 ASSERT_EQ(0, strcmp(s, "Frank"));
300 free(s);
301
302 ASSERT_TRUE(item.getCString("mother", &s));
303 ASSERT_EQ(0, strcmp(s, "July")); // "July" overwrites "June"
304 free(s);
305
306 item.setRate("burgersPerHour", 5, 2);
307 int64_t b, h;
308 ASSERT_TRUE(item.getRate("burgersPerHour", &b, &h, &d));
309 ASSERT_EQ(5, b);
310 ASSERT_EQ(2, h);
311 ASSERT_EQ(2.5, d);
312
313 item.addRate("burgersPerHour", 4, 2);
314 ASSERT_TRUE(item.getRate("burgersPerHour", &b, &h, &d));
315 ASSERT_EQ(9, b);
316 ASSERT_EQ(4, h);
317 ASSERT_EQ(2.25, d);
318
319 printf("item: %s\n", item.toString().c_str());
320 fflush(stdout);
321
Ray Essickf27e9872019-12-07 06:28:46 -0800322 sp mediaMetrics = new MediaMetricsService();
Andy Hungaeef7882019-10-18 15:18:14 -0700323 status_t status = mediaMetrics->submit(&item);
324 ASSERT_EQ(NO_ERROR, status);
325 mediaMetrics->dump(fileno(stdout), {} /* args */);
326}
327
328TEST(mediametrics_tests, superbig_item) {
Ray Essickf27e9872019-12-07 06:28:46 -0800329 mediametrics::Item item("TheBigOne");
Andy Hungaeef7882019-10-18 15:18:14 -0700330 constexpr size_t count = 10000;
331
332 for (size_t i = 0; i < count; ++i) {
333 item.setInt32(std::to_string(i).c_str(), i);
334 }
335 for (size_t i = 0; i < count; ++i) {
336 int32_t i32;
337 ASSERT_TRUE(item.getInt32(std::to_string(i).c_str(), &i32));
338 ASSERT_EQ((int32_t)i, i32);
339 }
340}
341
342TEST(mediametrics_tests, superbig_item_removal) {
Ray Essickf27e9872019-12-07 06:28:46 -0800343 mediametrics::Item item("TheOddBigOne");
Andy Hungaeef7882019-10-18 15:18:14 -0700344 constexpr size_t count = 10000;
345
346 for (size_t i = 0; i < count; ++i) {
347 item.setInt32(std::to_string(i).c_str(), i);
348 }
349 for (size_t i = 0; i < count; i += 2) {
350 item.filter(std::to_string(i).c_str()); // filter out all the evens.
351 }
352 for (size_t i = 0; i < count; ++i) {
353 int32_t i32;
354 if (i & 1) { // check to see that only the odds are left.
355 ASSERT_TRUE(item.getInt32(std::to_string(i).c_str(), &i32));
356 ASSERT_EQ((int32_t)i, i32);
357 } else {
358 ASSERT_FALSE(item.getInt32(std::to_string(i).c_str(), &i32));
359 }
360 }
361}
362
Andy Hung3253f2d2019-10-21 14:50:07 -0700363TEST(mediametrics_tests, superbig_item_removal2) {
Ray Essickf27e9872019-12-07 06:28:46 -0800364 mediametrics::Item item("TheOne");
Andy Hung3253f2d2019-10-21 14:50:07 -0700365 constexpr size_t count = 10000;
366
367 for (size_t i = 0; i < count; ++i) {
368 item.setInt32(std::to_string(i).c_str(), i);
369 }
370 static const char *attrs[] = { "1", };
371 item.filterNot(1, attrs);
372
373 for (size_t i = 0; i < count; ++i) {
374 int32_t i32;
375 if (i == 1) { // check to see that there is only one
376 ASSERT_TRUE(item.getInt32(std::to_string(i).c_str(), &i32));
377 ASSERT_EQ((int32_t)i, i32);
378 } else {
379 ASSERT_FALSE(item.getInt32(std::to_string(i).c_str(), &i32));
380 }
381 }
382}
383
Andy Hungaeef7882019-10-18 15:18:14 -0700384TEST(mediametrics_tests, item_transmutation) {
Ray Essickf27e9872019-12-07 06:28:46 -0800385 mediametrics::Item item("Alchemist's Stone");
Andy Hungaeef7882019-10-18 15:18:14 -0700386
387 item.setInt64("convert", 123);
388 int64_t i64;
389 ASSERT_TRUE(item.getInt64("convert", &i64));
390 ASSERT_EQ(123, i64);
391
392 item.addInt32("convert", 2); // changes type of 'convert' from i64 to i32 (and re-init).
393 ASSERT_FALSE(item.getInt64("convert", &i64)); // should be false, no value in i64.
394
395 int32_t i32;
396 ASSERT_TRUE(item.getInt32("convert", &i32)); // check it is i32 and 2 (123 is discarded).
397 ASSERT_EQ(2, i32);
398}
Andy Hung3253f2d2019-10-21 14:50:07 -0700399
400TEST(mediametrics_tests, item_binderization) {
Ray Essickf27e9872019-12-07 06:28:46 -0800401 mediametrics::Item item;
Andy Hung3253f2d2019-10-21 14:50:07 -0700402 item.setInt32("i32", 1)
403 .setInt64("i64", 2)
404 .setDouble("double", 3.1)
405 .setCString("string", "abc")
406 .setRate("rate", 11, 12);
407
408 Parcel p;
409 item.writeToParcel(&p);
410
411 p.setDataPosition(0); // rewind for reading
Ray Essickf27e9872019-12-07 06:28:46 -0800412 mediametrics::Item item2;
Andy Hung3253f2d2019-10-21 14:50:07 -0700413 item2.readFromParcel(p);
414
415 ASSERT_EQ(item, item2);
416}
417
418TEST(mediametrics_tests, item_byteserialization) {
Ray Essickf27e9872019-12-07 06:28:46 -0800419 mediametrics::Item item;
Andy Hung3253f2d2019-10-21 14:50:07 -0700420 item.setInt32("i32", 1)
421 .setInt64("i64", 2)
422 .setDouble("double", 3.1)
423 .setCString("string", "abc")
424 .setRate("rate", 11, 12);
425
426 char *data;
427 size_t length;
428 ASSERT_EQ(0, item.writeToByteString(&data, &length));
429 ASSERT_GT(length, (size_t)0);
430
Ray Essickf27e9872019-12-07 06:28:46 -0800431 mediametrics::Item item2;
Andy Hung3253f2d2019-10-21 14:50:07 -0700432 item2.readFromByteString(data, length);
433
434 printf("item: %s\n", item.toString().c_str());
435 printf("item2: %s\n", item2.toString().c_str());
436 ASSERT_EQ(item, item2);
437
438 free(data);
439}
440
441TEST(mediametrics_tests, item_iteration) {
Ray Essickf27e9872019-12-07 06:28:46 -0800442 mediametrics::Item item;
Andy Hung3253f2d2019-10-21 14:50:07 -0700443 item.setInt32("i32", 1)
444 .setInt64("i64", 2)
445 .setDouble("double", 3.125)
446 .setCString("string", "abc")
447 .setRate("rate", 11, 12);
448
449 int mask = 0;
450 for (auto &prop : item) {
451 const char *name = prop.getName();
452 if (!strcmp(name, "i32")) {
453 int32_t i32;
454 ASSERT_TRUE(prop.get(&i32));
455 ASSERT_EQ(1, i32);
Andy Hung692870b2020-01-02 13:46:06 -0800456 ASSERT_EQ(1, std::get<int32_t>(prop.get()));
Andy Hung3253f2d2019-10-21 14:50:07 -0700457 mask |= 1;
458 } else if (!strcmp(name, "i64")) {
459 int64_t i64;
460 ASSERT_TRUE(prop.get(&i64));
461 ASSERT_EQ(2, i64);
Andy Hung692870b2020-01-02 13:46:06 -0800462 ASSERT_EQ(2, std::get<int64_t>(prop.get()));
Andy Hung3253f2d2019-10-21 14:50:07 -0700463 mask |= 2;
464 } else if (!strcmp(name, "double")) {
465 double d;
466 ASSERT_TRUE(prop.get(&d));
467 ASSERT_EQ(3.125, d);
Andy Hung692870b2020-01-02 13:46:06 -0800468 ASSERT_EQ(3.125, std::get<double>(prop.get()));
Andy Hung3253f2d2019-10-21 14:50:07 -0700469 mask |= 4;
470 } else if (!strcmp(name, "string")) {
Andy Hungb7aadb32019-12-09 19:40:42 -0800471 std::string s;
Andy Hung3253f2d2019-10-21 14:50:07 -0700472 ASSERT_TRUE(prop.get(&s));
Andy Hungb7aadb32019-12-09 19:40:42 -0800473 ASSERT_EQ("abc", s);
Andy Hung692870b2020-01-02 13:46:06 -0800474 ASSERT_EQ(s, std::get<std::string>(prop.get()));
Andy Hung3253f2d2019-10-21 14:50:07 -0700475 mask |= 8;
476 } else if (!strcmp(name, "rate")) {
477 std::pair<int64_t, int64_t> r;
478 ASSERT_TRUE(prop.get(&r));
479 ASSERT_EQ(11, r.first);
480 ASSERT_EQ(12, r.second);
Andy Hung692870b2020-01-02 13:46:06 -0800481 ASSERT_EQ(r, std::get<decltype(r)>(prop.get()));
Andy Hung3253f2d2019-10-21 14:50:07 -0700482 mask |= 16;
483 } else {
484 FAIL();
485 }
486 }
487 ASSERT_EQ(31, mask);
488}
Andy Hung1efc9c62019-12-03 13:43:33 -0800489
490TEST(mediametrics_tests, item_expansion) {
Ray Essickf27e9872019-12-07 06:28:46 -0800491 mediametrics::LogItem<1> item("I");
Andy Hung1efc9c62019-12-03 13:43:33 -0800492 item.set("i32", (int32_t)1)
493 .set("i64", (int64_t)2)
494 .set("double", (double)3.125)
495 .set("string", "abcdefghijklmnopqrstuvwxyz")
496 .set("rate", std::pair<int64_t, int64_t>(11, 12));
497 ASSERT_TRUE(item.updateHeader());
498
Ray Essickf27e9872019-12-07 06:28:46 -0800499 mediametrics::Item item2;
Andy Hung1efc9c62019-12-03 13:43:33 -0800500 item2.readFromByteString(item.getBuffer(), item.getLength());
501 ASSERT_EQ((pid_t)-1, item2.getPid());
502 ASSERT_EQ((uid_t)-1, item2.getUid());
503 int mask = 0;
504 for (auto &prop : item2) {
505 const char *name = prop.getName();
506 if (!strcmp(name, "i32")) {
507 int32_t i32;
508 ASSERT_TRUE(prop.get(&i32));
509 ASSERT_EQ(1, i32);
510 mask |= 1;
511 } else if (!strcmp(name, "i64")) {
512 int64_t i64;
513 ASSERT_TRUE(prop.get(&i64));
514 ASSERT_EQ(2, i64);
515 mask |= 2;
516 } else if (!strcmp(name, "double")) {
517 double d;
518 ASSERT_TRUE(prop.get(&d));
519 ASSERT_EQ(3.125, d);
520 mask |= 4;
521 } else if (!strcmp(name, "string")) {
Andy Hungb7aadb32019-12-09 19:40:42 -0800522 std::string s;
Andy Hung1efc9c62019-12-03 13:43:33 -0800523 ASSERT_TRUE(prop.get(&s));
Andy Hungb7aadb32019-12-09 19:40:42 -0800524 ASSERT_EQ("abcdefghijklmnopqrstuvwxyz", s);
Andy Hung1efc9c62019-12-03 13:43:33 -0800525 mask |= 8;
526 } else if (!strcmp(name, "rate")) {
527 std::pair<int64_t, int64_t> r;
528 ASSERT_TRUE(prop.get(&r));
529 ASSERT_EQ(11, r.first);
530 ASSERT_EQ(12, r.second);
531 mask |= 16;
532 } else {
533 FAIL();
534 }
535 }
536 ASSERT_EQ(31, mask);
537}
538
539TEST(mediametrics_tests, item_expansion2) {
Ray Essickf27e9872019-12-07 06:28:46 -0800540 mediametrics::LogItem<1> item("Bigly");
Andy Hung1efc9c62019-12-03 13:43:33 -0800541 item.setPid(123)
542 .setUid(456);
543 constexpr size_t count = 10000;
544
545 for (size_t i = 0; i < count; ++i) {
546 // printf("recording %zu, %p, len:%zu of %zu remaining:%zu \n", i, item.getBuffer(), item.getLength(), item.getCapacity(), item.getRemaining());
547 item.set(std::to_string(i).c_str(), (int32_t)i);
548 }
549 ASSERT_TRUE(item.updateHeader());
550
Ray Essickf27e9872019-12-07 06:28:46 -0800551 mediametrics::Item item2;
Andy Hung1efc9c62019-12-03 13:43:33 -0800552 printf("begin buffer:%p length:%zu\n", item.getBuffer(), item.getLength());
553 fflush(stdout);
554 item2.readFromByteString(item.getBuffer(), item.getLength());
555
556 ASSERT_EQ((pid_t)123, item2.getPid());
557 ASSERT_EQ((uid_t)456, item2.getUid());
558 for (size_t i = 0; i < count; ++i) {
559 int32_t i32;
560 ASSERT_TRUE(item2.getInt32(std::to_string(i).c_str(), &i32));
561 ASSERT_EQ((int32_t)i, i32);
562 }
563}
Andy Hung06f3aba2019-12-03 16:36:42 -0800564
565TEST(mediametrics_tests, time_machine_storage) {
Ray Essickf27e9872019-12-07 06:28:46 -0800566 auto item = std::make_shared<mediametrics::Item>("Key");
Andy Hung06f3aba2019-12-03 16:36:42 -0800567 (*item).set("i32", (int32_t)1)
568 .set("i64", (int64_t)2)
569 .set("double", (double)3.125)
570 .set("string", "abcdefghijklmnopqrstuvwxyz")
571 .set("rate", std::pair<int64_t, int64_t>(11, 12));
572
573 // Let's put the item in
574 android::mediametrics::TimeMachine timeMachine;
575 ASSERT_EQ(NO_ERROR, timeMachine.put(item, true));
576
577 // Can we read the values?
578 int32_t i32;
579 ASSERT_EQ(NO_ERROR, timeMachine.get("Key", "i32", &i32, -1));
580 ASSERT_EQ(1, i32);
581
582 int64_t i64;
583 ASSERT_EQ(NO_ERROR, timeMachine.get("Key", "i64", &i64, -1));
584 ASSERT_EQ(2, i64);
585
586 double d;
587 ASSERT_EQ(NO_ERROR, timeMachine.get("Key", "double", &d, -1));
588 ASSERT_EQ(3.125, d);
589
590 std::string s;
591 ASSERT_EQ(NO_ERROR, timeMachine.get("Key", "string", &s, -1));
592 ASSERT_EQ("abcdefghijklmnopqrstuvwxyz", s);
593
594 // Using fully qualified name?
595 i32 = 0;
596 ASSERT_EQ(NO_ERROR, timeMachine.get("Key.i32", &i32, -1));
597 ASSERT_EQ(1, i32);
598
599 i64 = 0;
600 ASSERT_EQ(NO_ERROR, timeMachine.get("Key.i64", &i64, -1));
601 ASSERT_EQ(2, i64);
602
603 d = 0.;
604 ASSERT_EQ(NO_ERROR, timeMachine.get("Key.double", &d, -1));
605 ASSERT_EQ(3.125, d);
606
607 s.clear();
608 ASSERT_EQ(NO_ERROR, timeMachine.get("Key.string", &s, -1));
609 ASSERT_EQ("abcdefghijklmnopqrstuvwxyz", s);
610}
611
612TEST(mediametrics_tests, time_machine_remote_key) {
Ray Essickf27e9872019-12-07 06:28:46 -0800613 auto item = std::make_shared<mediametrics::Item>("Key1");
Andy Hung06f3aba2019-12-03 16:36:42 -0800614 (*item).set("one", (int32_t)1)
615 .set("two", (int32_t)2);
616
617 android::mediametrics::TimeMachine timeMachine;
618 ASSERT_EQ(NO_ERROR, timeMachine.put(item, true));
619
Ray Essickf27e9872019-12-07 06:28:46 -0800620 auto item2 = std::make_shared<mediametrics::Item>("Key2");
Andy Hung06f3aba2019-12-03 16:36:42 -0800621 (*item2).set("three", (int32_t)3)
622 .set("[Key1]four", (int32_t)4) // affects Key1
623 .set("[Key1]five", (int32_t)5); // affects key1
624
625 ASSERT_EQ(NO_ERROR, timeMachine.put(item2, true));
626
Ray Essickf27e9872019-12-07 06:28:46 -0800627 auto item3 = std::make_shared<mediametrics::Item>("Key2");
Andy Hung06f3aba2019-12-03 16:36:42 -0800628 (*item3).set("six", (int32_t)6)
629 .set("[Key1]seven", (int32_t)7); // affects Key1
630
631 ASSERT_EQ(NO_ERROR, timeMachine.put(item3, false)); // remote keys not allowed.
632
633 // Can we read the values?
634 int32_t i32;
635 ASSERT_EQ(NO_ERROR, timeMachine.get("Key1.one", &i32, -1));
636 ASSERT_EQ(1, i32);
637
638 ASSERT_EQ(NO_ERROR, timeMachine.get("Key1.two", &i32, -1));
639 ASSERT_EQ(2, i32);
640
641 ASSERT_EQ(BAD_VALUE, timeMachine.get("Key1.three", &i32, -1));
642
643 ASSERT_EQ(NO_ERROR, timeMachine.get("Key2.three", &i32, -1));
644 ASSERT_EQ(3, i32);
645
646 ASSERT_EQ(NO_ERROR, timeMachine.get("Key1.four", &i32, -1));
647 ASSERT_EQ(4, i32);
648
649 ASSERT_EQ(BAD_VALUE, timeMachine.get("Key2.four", &i32, -1));
650
651 ASSERT_EQ(NO_ERROR, timeMachine.get("Key1.five", &i32, -1));
652 ASSERT_EQ(5, i32);
653
654 ASSERT_EQ(BAD_VALUE, timeMachine.get("Key2.five", &i32, -1));
655
656 ASSERT_EQ(NO_ERROR, timeMachine.get("Key2.six", &i32, -1));
657 ASSERT_EQ(6, i32);
658
659 ASSERT_EQ(BAD_VALUE, timeMachine.get("Key2.seven", &i32, -1));
660}
661
662TEST(mediametrics_tests, time_machine_gc) {
Ray Essickf27e9872019-12-07 06:28:46 -0800663 auto item = std::make_shared<mediametrics::Item>("Key1");
Andy Hung06f3aba2019-12-03 16:36:42 -0800664 (*item).set("one", (int32_t)1)
665 .set("two", (int32_t)2)
666 .setTimestamp(10);
667
668 android::mediametrics::TimeMachine timeMachine(1, 2); // keep at most 2 keys.
669
670 ASSERT_EQ((size_t)0, timeMachine.size());
671
672 ASSERT_EQ(NO_ERROR, timeMachine.put(item, true));
673
674 ASSERT_EQ((size_t)1, timeMachine.size());
675
Ray Essickf27e9872019-12-07 06:28:46 -0800676 auto item2 = std::make_shared<mediametrics::Item>("Key2");
Andy Hung06f3aba2019-12-03 16:36:42 -0800677 (*item2).set("three", (int32_t)3)
678 .set("[Key1]three", (int32_t)3)
679 .setTimestamp(11);
680
681 ASSERT_EQ(NO_ERROR, timeMachine.put(item2, true));
682 ASSERT_EQ((size_t)2, timeMachine.size());
683
684 //printf("Before\n%s\n\n", timeMachine.dump().c_str());
685
Ray Essickf27e9872019-12-07 06:28:46 -0800686 auto item3 = std::make_shared<mediametrics::Item>("Key3");
Andy Hung06f3aba2019-12-03 16:36:42 -0800687 (*item3).set("six", (int32_t)6)
688 .set("[Key1]four", (int32_t)4) // affects Key1
689 .set("[Key1]five", (int32_t)5) // affects key1
690 .setTimestamp(12);
691
692 ASSERT_EQ(NO_ERROR, timeMachine.put(item3, true));
693
694 ASSERT_EQ((size_t)2, timeMachine.size());
695
696 // Can we read the values?
697 int32_t i32;
698 ASSERT_EQ(BAD_VALUE, timeMachine.get("Key1.one", &i32, -1));
699 ASSERT_EQ(BAD_VALUE, timeMachine.get("Key1.two", &i32, -1));
700 ASSERT_EQ(BAD_VALUE, timeMachine.get("Key1.three", &i32, -1));
701 ASSERT_EQ(BAD_VALUE, timeMachine.get("Key1.four", &i32, -1));
702 ASSERT_EQ(BAD_VALUE, timeMachine.get("Key1.five", &i32, -1));
703
704 ASSERT_EQ(NO_ERROR, timeMachine.get("Key2.three", &i32, -1));
705 ASSERT_EQ(3, i32);
706
707 ASSERT_EQ(NO_ERROR, timeMachine.get("Key3.six", &i32, -1));
708 ASSERT_EQ(6, i32);
709
710 printf("After\n%s\n", timeMachine.dump().first.c_str());
711}
712
713TEST(mediametrics_tests, transaction_log_gc) {
Ray Essickf27e9872019-12-07 06:28:46 -0800714 auto item = std::make_shared<mediametrics::Item>("Key1");
Andy Hung06f3aba2019-12-03 16:36:42 -0800715 (*item).set("one", (int32_t)1)
716 .set("two", (int32_t)2)
717 .setTimestamp(10);
718
719 android::mediametrics::TransactionLog transactionLog(1, 2); // keep at most 2 items
720 ASSERT_EQ((size_t)0, transactionLog.size());
721
722 ASSERT_EQ(NO_ERROR, transactionLog.put(item));
723 ASSERT_EQ((size_t)1, transactionLog.size());
724
Ray Essickf27e9872019-12-07 06:28:46 -0800725 auto item2 = std::make_shared<mediametrics::Item>("Key2");
Andy Hung06f3aba2019-12-03 16:36:42 -0800726 (*item2).set("three", (int32_t)3)
727 .set("[Key1]three", (int32_t)3)
728 .setTimestamp(11);
729
730 ASSERT_EQ(NO_ERROR, transactionLog.put(item2));
731 ASSERT_EQ((size_t)2, transactionLog.size());
732
Ray Essickf27e9872019-12-07 06:28:46 -0800733 auto item3 = std::make_shared<mediametrics::Item>("Key3");
Andy Hung06f3aba2019-12-03 16:36:42 -0800734 (*item3).set("six", (int32_t)6)
735 .set("[Key1]four", (int32_t)4) // affects Key1
736 .set("[Key1]five", (int32_t)5) // affects key1
737 .setTimestamp(12);
738
739 ASSERT_EQ(NO_ERROR, transactionLog.put(item3));
740 ASSERT_EQ((size_t)2, transactionLog.size());
741}
742
Andy Hung0f7ad8c2020-01-03 13:24:34 -0800743TEST(mediametrics_tests, analytics_actions) {
744 mediametrics::AnalyticsActions analyticsActions;
745 bool action1 = false;
746 bool action2 = false;
747 bool action3 = false;
748 bool action4 = false;
749
750 // check to see whether various actions have been matched.
751 analyticsActions.addAction(
752 "audio.flinger.event",
753 std::string("AudioFlinger"),
754 std::make_shared<mediametrics::AnalyticsActions::Function>(
755 [&](const std::shared_ptr<const android::mediametrics::Item> &) {
756 action1 = true;
757 }));
758
759 analyticsActions.addAction(
760 "audio.*.event",
761 std::string("AudioFlinger"),
762 std::make_shared<mediametrics::AnalyticsActions::Function>(
763 [&](const std::shared_ptr<const android::mediametrics::Item> &) {
764 action2 = true;
765 }));
766
767 analyticsActions.addAction("audio.fl*n*g*r.event",
768 std::string("AudioFlinger"),
769 std::make_shared<mediametrics::AnalyticsActions::Function>(
770 [&](const std::shared_ptr<const android::mediametrics::Item> &) {
771 action3 = true;
772 }));
773
774 analyticsActions.addAction("audio.fl*gn*r.event",
775 std::string("AudioFlinger"),
776 std::make_shared<mediametrics::AnalyticsActions::Function>(
777 [&](const std::shared_ptr<const android::mediametrics::Item> &) {
778 action4 = true;
779 }));
780
781 // make a test item
782 auto item = std::make_shared<mediametrics::Item>("audio.flinger");
783 (*item).set("event", "AudioFlinger");
784
785 // get the actions and execute them
786 auto actions = analyticsActions.getActionsForItem(item);
787 for (const auto& action : actions) {
788 action->operator()(item);
789 }
790
791 // The following should match.
792 ASSERT_EQ(true, action1);
793 ASSERT_EQ(true, action2);
794 ASSERT_EQ(true, action3);
795 ASSERT_EQ(false, action4); // audio.fl*gn*r != audio.flinger
796}
797
Andy Hung06f3aba2019-12-03 16:36:42 -0800798TEST(mediametrics_tests, audio_analytics_permission) {
Ray Essickf27e9872019-12-07 06:28:46 -0800799 auto item = std::make_shared<mediametrics::Item>("audio.1");
Andy Hung06f3aba2019-12-03 16:36:42 -0800800 (*item).set("one", (int32_t)1)
801 .set("two", (int32_t)2)
802 .setTimestamp(10);
803
Ray Essickf27e9872019-12-07 06:28:46 -0800804 auto item2 = std::make_shared<mediametrics::Item>("audio.1");
Andy Hung06f3aba2019-12-03 16:36:42 -0800805 (*item2).set("three", (int32_t)3)
806 .setTimestamp(11);
807
Ray Essickf27e9872019-12-07 06:28:46 -0800808 auto item3 = std::make_shared<mediametrics::Item>("audio.2");
Andy Hung06f3aba2019-12-03 16:36:42 -0800809 (*item3).set("four", (int32_t)4)
810 .setTimestamp(12);
811
812 android::mediametrics::AudioAnalytics audioAnalytics;
813
814 // untrusted entities cannot create a new key.
815 ASSERT_EQ(PERMISSION_DENIED, audioAnalytics.submit(item, false /* isTrusted */));
816 ASSERT_EQ(PERMISSION_DENIED, audioAnalytics.submit(item2, false /* isTrusted */));
817
818 // TODO: Verify contents of AudioAnalytics.
819 // Currently there is no getter API in AudioAnalytics besides dump.
Andy Hunga629bd12020-06-05 16:03:53 -0700820 ASSERT_EQ(11, audioAnalytics.dump(1000).second /* lines */);
Andy Hung06f3aba2019-12-03 16:36:42 -0800821
822 ASSERT_EQ(NO_ERROR, audioAnalytics.submit(item, true /* isTrusted */));
823 // untrusted entities can add to an existing key
824 ASSERT_EQ(NO_ERROR, audioAnalytics.submit(item2, false /* isTrusted */));
825
826 // Check that we have some info in the dump.
Andy Hung0f7ad8c2020-01-03 13:24:34 -0800827 ASSERT_LT(9, audioAnalytics.dump(1000).second /* lines */);
Andy Hung06f3aba2019-12-03 16:36:42 -0800828}
829
Andy Hungd203eb62020-04-27 09:12:46 -0700830TEST(mediametrics_tests, audio_analytics_permission2) {
831 constexpr int32_t transactionUid = 1010; // arbitrary
832 auto item = std::make_shared<mediametrics::Item>("audio.1");
833 (*item).set("one", (int32_t)1)
834 .set("two", (int32_t)2)
835 .set(AMEDIAMETRICS_PROP_ALLOWUID, transactionUid)
836 .setTimestamp(10);
837
838 // item2 submitted untrusted
839 auto item2 = std::make_shared<mediametrics::Item>("audio.1");
840 (*item2).set("three", (int32_t)3)
841 .setUid(transactionUid)
842 .setTimestamp(11);
843
844 auto item3 = std::make_shared<mediametrics::Item>("audio.2");
845 (*item3).set("four", (int32_t)4)
846 .setTimestamp(12);
847
848 android::mediametrics::AudioAnalytics audioAnalytics;
849
850 // untrusted entities cannot create a new key.
851 ASSERT_EQ(PERMISSION_DENIED, audioAnalytics.submit(item, false /* isTrusted */));
852 ASSERT_EQ(PERMISSION_DENIED, audioAnalytics.submit(item2, false /* isTrusted */));
853
854 // TODO: Verify contents of AudioAnalytics.
855 // Currently there is no getter API in AudioAnalytics besides dump.
Andy Hunga629bd12020-06-05 16:03:53 -0700856 ASSERT_EQ(11, audioAnalytics.dump(1000).second /* lines */);
Andy Hungd203eb62020-04-27 09:12:46 -0700857
858 ASSERT_EQ(NO_ERROR, audioAnalytics.submit(item, true /* isTrusted */));
859 // untrusted entities can add to an existing key
860 ASSERT_EQ(NO_ERROR, audioAnalytics.submit(item2, false /* isTrusted */));
861
862 // Check that we have some info in the dump.
863 ASSERT_LT(9, audioAnalytics.dump(1000).second /* lines */);
864}
865
Andy Hung06f3aba2019-12-03 16:36:42 -0800866TEST(mediametrics_tests, audio_analytics_dump) {
Ray Essickf27e9872019-12-07 06:28:46 -0800867 auto item = std::make_shared<mediametrics::Item>("audio.1");
Andy Hung06f3aba2019-12-03 16:36:42 -0800868 (*item).set("one", (int32_t)1)
869 .set("two", (int32_t)2)
870 .setTimestamp(10);
871
Ray Essickf27e9872019-12-07 06:28:46 -0800872 auto item2 = std::make_shared<mediametrics::Item>("audio.1");
Andy Hung06f3aba2019-12-03 16:36:42 -0800873 (*item2).set("three", (int32_t)3)
874 .setTimestamp(11);
875
Ray Essickf27e9872019-12-07 06:28:46 -0800876 auto item3 = std::make_shared<mediametrics::Item>("audio.2");
Andy Hung06f3aba2019-12-03 16:36:42 -0800877 (*item3).set("four", (int32_t)4)
878 .setTimestamp(12);
879
880 android::mediametrics::AudioAnalytics audioAnalytics;
881
882 ASSERT_EQ(NO_ERROR, audioAnalytics.submit(item, true /* isTrusted */));
883 // untrusted entities can add to an existing key
884 ASSERT_EQ(NO_ERROR, audioAnalytics.submit(item2, false /* isTrusted */));
885 ASSERT_EQ(NO_ERROR, audioAnalytics.submit(item3, true /* isTrusted */));
886
887 // find out how many lines we have.
888 auto [string, lines] = audioAnalytics.dump(1000);
889 ASSERT_EQ(lines, (int32_t) countNewlines(string.c_str()));
890
891 printf("AudioAnalytics: %s", string.c_str());
892 // ensure that dump operates over those lines.
893 for (int32_t ll = 0; ll < lines; ++ll) {
894 auto [s, l] = audioAnalytics.dump(ll);
895 ASSERT_EQ(ll, l);
896 ASSERT_EQ(ll, (int32_t) countNewlines(s.c_str()));
897 }
898}
Andy Hung5d3f2d12020-03-04 19:55:03 -0800899
Andy Hungce9b6632020-04-28 20:15:17 -0700900TEST(mediametrics_tests, device_parsing) {
Andy Hung1ea842e2020-05-18 10:47:31 -0700901 auto devaddr = android::mediametrics::stringutils::getDeviceAddressPairs("(DEVICE, )");
Andy Hungce9b6632020-04-28 20:15:17 -0700902 ASSERT_EQ((size_t)1, devaddr.size());
903 ASSERT_EQ("DEVICE", devaddr[0].first);
904 ASSERT_EQ("", devaddr[0].second);
905
Andy Hung1ea842e2020-05-18 10:47:31 -0700906 devaddr = android::mediametrics::stringutils::getDeviceAddressPairs(
Andy Hungce9b6632020-04-28 20:15:17 -0700907 "(DEVICE1, A)|(D, ADDRB)");
908 ASSERT_EQ((size_t)2, devaddr.size());
909 ASSERT_EQ("DEVICE1", devaddr[0].first);
910 ASSERT_EQ("A", devaddr[0].second);
911 ASSERT_EQ("D", devaddr[1].first);
912 ASSERT_EQ("ADDRB", devaddr[1].second);
913
Andy Hung1ea842e2020-05-18 10:47:31 -0700914 devaddr = android::mediametrics::stringutils::getDeviceAddressPairs(
Andy Hungce9b6632020-04-28 20:15:17 -0700915 "(A,B)|(C,D)");
916 ASSERT_EQ((size_t)2, devaddr.size());
917 ASSERT_EQ("A", devaddr[0].first);
918 ASSERT_EQ("B", devaddr[0].second);
919 ASSERT_EQ("C", devaddr[1].first);
920 ASSERT_EQ("D", devaddr[1].second);
921
Andy Hung1ea842e2020-05-18 10:47:31 -0700922 devaddr = android::mediametrics::stringutils::getDeviceAddressPairs(
Andy Hungce9b6632020-04-28 20:15:17 -0700923 " ( A1 , B ) | ( C , D2 ) ");
924 ASSERT_EQ((size_t)2, devaddr.size());
925 ASSERT_EQ("A1", devaddr[0].first);
926 ASSERT_EQ("B", devaddr[0].second);
927 ASSERT_EQ("C", devaddr[1].first);
928 ASSERT_EQ("D2", devaddr[1].second);
929}
930
931TEST(mediametrics_tests, timed_action) {
932 android::mediametrics::TimedAction timedAction;
933 std::atomic_int value1 = 0;
934
935 timedAction.postIn(std::chrono::seconds(0), [&value1] { ++value1; });
936 timedAction.postIn(std::chrono::seconds(1000), [&value1] { ++value1; });
937 usleep(100000);
938 ASSERT_EQ(1, value1);
939 ASSERT_EQ((size_t)1, timedAction.size());
940}
941
Andy Hunga629bd12020-06-05 16:03:53 -0700942// Ensure we don't introduce unexpected duplicates into our maps.
943TEST(mediametrics_tests, audio_types_tables) {
944 using namespace android::mediametrics::types;
945
946 ASSERT_EQ(0, countDuplicates(getAudioCallerNameMap()));
947 ASSERT_EQ(2, countDuplicates(getAudioDeviceInMap())); // has dups
948 ASSERT_EQ(1, countDuplicates(getAudioDeviceOutMap())); // has dups
949 ASSERT_EQ(0, countDuplicates(getAudioThreadTypeMap()));
950 ASSERT_EQ(0, countDuplicates(getAudioTrackTraitsMap()));
951}
952
953// Check our string validation (before logging to statsd).
954// This variant checks the logged, possibly shortened string.
955TEST(mediametrics_tests, audio_types_string) {
956 using namespace android::mediametrics::types;
957
958 ASSERT_EQ("java", (lookup<CALLER_NAME, std::string>)("java"));
959 ASSERT_EQ("", (lookup<CALLER_NAME, std::string>)("random"));
960
961 ASSERT_EQ("SPEECH", (lookup<CONTENT_TYPE, std::string>)("AUDIO_CONTENT_TYPE_SPEECH"));
962 ASSERT_EQ("", (lookup<CONTENT_TYPE, std::string>)("random"));
963
964 ASSERT_EQ("FLAC", (lookup<ENCODING, std::string>)("AUDIO_FORMAT_FLAC"));
965 ASSERT_EQ("", (lookup<ENCODING, std::string>)("random"));
966
967 ASSERT_EQ("USB_DEVICE", (lookup<INPUT_DEVICE, std::string>)("AUDIO_DEVICE_IN_USB_DEVICE"));
968 ASSERT_EQ("BUILTIN_MIC|WIRED_HEADSET", (lookup<INPUT_DEVICE, std::string>)(
969 "AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET"));
970 ASSERT_EQ("", (lookup<INPUT_DEVICE, std::string>)("random"));
971
972 ASSERT_EQ("RAW", (lookup<INPUT_FLAG, std::string>)("AUDIO_INPUT_FLAG_RAW"));
973 ASSERT_EQ("HW_AV_SYNC|VOIP_TX", (lookup<INPUT_FLAG, std::string>)(
974 "AUDIO_INPUT_FLAG_HW_AV_SYNC|AUDIO_INPUT_FLAG_VOIP_TX"));
975 ASSERT_EQ("", (lookup<INPUT_FLAG, std::string>)("random"));
976
977 ASSERT_EQ("BLUETOOTH_SCO_CARKIT",
978 (lookup<OUTPUT_DEVICE, std::string>)("AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT"));
979 ASSERT_EQ("SPEAKER|HDMI", (lookup<OUTPUT_DEVICE, std::string>)(
980 "AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_HDMI"));
981 ASSERT_EQ("", (lookup<OUTPUT_DEVICE, std::string>)("random"));
982
983 ASSERT_EQ("PRIMARY", (lookup<OUTPUT_FLAG, std::string>)("AUDIO_OUTPUT_FLAG_PRIMARY"));
984 ASSERT_EQ("DEEP_BUFFER|NON_BLOCKING", (lookup<OUTPUT_FLAG, std::string>)(
985 "AUDIO_OUTPUT_FLAG_DEEP_BUFFER|AUDIO_OUTPUT_FLAG_NON_BLOCKING"));
986 ASSERT_EQ("", (lookup<OUTPUT_FLAG, std::string>)("random"));
987
988 ASSERT_EQ("MIC", (lookup<SOURCE_TYPE, std::string>)("AUDIO_SOURCE_MIC"));
989 ASSERT_EQ("", (lookup<SOURCE_TYPE, std::string>)("random"));
990
991 ASSERT_EQ("TTS", (lookup<STREAM_TYPE, std::string>)("AUDIO_STREAM_TTS"));
992 ASSERT_EQ("", (lookup<STREAM_TYPE, std::string>)("random"));
993
994 ASSERT_EQ("DIRECT", (lookup<THREAD_TYPE, std::string>)("DIRECT"));
995 ASSERT_EQ("", (lookup<THREAD_TYPE, std::string>)("random"));
996
997 ASSERT_EQ("static", (lookup<TRACK_TRAITS, std::string>)("static"));
998 ASSERT_EQ("", (lookup<TRACK_TRAITS, std::string>)("random"));
999
1000 ASSERT_EQ("VOICE_COMMUNICATION",
1001 (lookup<USAGE, std::string>)("AUDIO_USAGE_VOICE_COMMUNICATION"));
1002 ASSERT_EQ("", (lookup<USAGE, std::string>)("random"));
1003}
1004
1005// Check our string validation (before logging to statsd).
1006// This variant checks integral value logging.
1007TEST(mediametrics_tests, audio_types_integer) {
1008 using namespace android::mediametrics::types;
1009
1010 ASSERT_EQ(2, (lookup<CALLER_NAME, int32_t>)("java"));
1011 ASSERT_EQ(0, (lookup<CALLER_NAME, int32_t>)("random")); // 0 == unknown
1012
1013 ASSERT_EQ((int32_t)AUDIO_CONTENT_TYPE_SPEECH,
1014 (lookup<CONTENT_TYPE, int32_t>)("AUDIO_CONTENT_TYPE_SPEECH"));
1015 ASSERT_EQ((int32_t)AUDIO_CONTENT_TYPE_UNKNOWN, (lookup<CONTENT_TYPE, int32_t>)("random"));
1016
1017 ASSERT_EQ((int32_t)AUDIO_FORMAT_FLAC, (lookup<ENCODING, int32_t>)("AUDIO_FORMAT_FLAC"));
1018 ASSERT_EQ((int32_t)AUDIO_FORMAT_INVALID, (lookup<ENCODING, int32_t>)("random"));
1019
1020 ASSERT_EQ(getAudioDeviceInMap().at("AUDIO_DEVICE_IN_USB_DEVICE"),
1021 (lookup<INPUT_DEVICE, int64_t>)("AUDIO_DEVICE_IN_USB_DEVICE"));
1022 ASSERT_EQ(getAudioDeviceInMap().at("AUDIO_DEVICE_IN_BUILTIN_MIC")
1023 | getAudioDeviceInMap().at("AUDIO_DEVICE_IN_WIRED_HEADSET"),
1024 (lookup<INPUT_DEVICE, int64_t>)(
1025 "AUDIO_DEVICE_IN_BUILTIN_MIC|AUDIO_DEVICE_IN_WIRED_HEADSET"));
1026 ASSERT_EQ(0, (lookup<INPUT_DEVICE, int64_t>)("random"));
1027
1028 ASSERT_EQ((int32_t)AUDIO_INPUT_FLAG_RAW,
1029 (lookup<INPUT_FLAG, int32_t>)("AUDIO_INPUT_FLAG_RAW"));
1030 ASSERT_EQ((int32_t)AUDIO_INPUT_FLAG_HW_AV_SYNC
1031 | (int32_t)AUDIO_INPUT_FLAG_VOIP_TX,
1032 (lookup<INPUT_FLAG, int32_t>)(
1033 "AUDIO_INPUT_FLAG_HW_AV_SYNC|AUDIO_INPUT_FLAG_VOIP_TX"));
1034 ASSERT_EQ(0, (lookup<INPUT_FLAG, int32_t>)("random"));
1035
1036 ASSERT_EQ(getAudioDeviceOutMap().at("AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT"),
1037 (lookup<OUTPUT_DEVICE, int64_t>)("AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT"));
1038 ASSERT_EQ(getAudioDeviceOutMap().at("AUDIO_DEVICE_OUT_SPEAKER")
1039 | getAudioDeviceOutMap().at("AUDIO_DEVICE_OUT_HDMI"),
1040 (lookup<OUTPUT_DEVICE, int64_t>)(
1041 "AUDIO_DEVICE_OUT_SPEAKER|AUDIO_DEVICE_OUT_HDMI"));
1042 ASSERT_EQ(0, (lookup<OUTPUT_DEVICE, int64_t>)("random"));
1043
1044 ASSERT_EQ((int32_t)AUDIO_OUTPUT_FLAG_PRIMARY,
1045 (lookup<OUTPUT_FLAG, int32_t>)("AUDIO_OUTPUT_FLAG_PRIMARY"));
1046 ASSERT_EQ((int32_t)AUDIO_OUTPUT_FLAG_DEEP_BUFFER | (int32_t)AUDIO_OUTPUT_FLAG_NON_BLOCKING,
1047 (lookup<OUTPUT_FLAG, int32_t>)(
1048 "AUDIO_OUTPUT_FLAG_DEEP_BUFFER|AUDIO_OUTPUT_FLAG_NON_BLOCKING"));
1049 ASSERT_EQ(0, (lookup<OUTPUT_FLAG, int32_t>)("random"));
1050
1051 ASSERT_EQ((int32_t)AUDIO_SOURCE_MIC, (lookup<SOURCE_TYPE, int32_t>)("AUDIO_SOURCE_MIC"));
1052 ASSERT_EQ((int32_t)AUDIO_SOURCE_DEFAULT, (lookup<SOURCE_TYPE, int32_t>)("random"));
1053
1054 ASSERT_EQ((int32_t)AUDIO_STREAM_TTS, (lookup<STREAM_TYPE, int32_t>)("AUDIO_STREAM_TTS"));
1055 ASSERT_EQ((int32_t)AUDIO_STREAM_DEFAULT, (lookup<STREAM_TYPE, int32_t>)("random"));
1056
1057 ASSERT_EQ(1, (lookup<THREAD_TYPE, int32_t>)("DIRECT"));
1058 ASSERT_EQ(-1, (lookup<THREAD_TYPE, int32_t>)("random"));
1059
1060 ASSERT_EQ(getAudioTrackTraitsMap().at("static"), (lookup<TRACK_TRAITS, int32_t>)("static"));
1061 ASSERT_EQ(0, (lookup<TRACK_TRAITS, int32_t>)("random"));
1062
1063 ASSERT_EQ((int32_t)AUDIO_USAGE_VOICE_COMMUNICATION,
1064 (lookup<USAGE, int32_t>)("AUDIO_USAGE_VOICE_COMMUNICATION"));
1065 ASSERT_EQ((int32_t)AUDIO_USAGE_UNKNOWN, (lookup<USAGE, int32_t>)("random"));
1066}
1067
Andy Hung5d3f2d12020-03-04 19:55:03 -08001068#if 0
1069// Stress test code for garbage collection, you need to enable AID_SHELL as trusted to run
1070// in MediaMetricsService.cpp.
1071//
1072// TODO: Make a dedicated stress test.
1073//
1074TEST(mediametrics_tests, gc_same_key) {
1075 // random keys ignored when empty
1076 for (int i = 0; i < 10000000; ++i) {
1077 std::unique_ptr<mediametrics::Item> test_key(mediametrics::Item::create("audio.zzz.123"));
1078 test_key->set("event#", "hello");
1079 test_key->set("value", (int)10);
1080 test_key->selfrecord();
1081 }
1082 //mediaMetrics->dump(fileno(stdout), {} /* args */);
1083}
1084#endif