MediaMetrics: Add unit tests
Document some interface differences.
Test: mediametrics_tests
Change-Id: Idf19827e79136dcca6522e6df53e28e3ea4a2231
diff --git a/media/libmediametrics/include/IMediaAnalyticsService.h b/media/libmediametrics/include/IMediaAnalyticsService.h
index f635e94..f2e7710 100644
--- a/media/libmediametrics/include/IMediaAnalyticsService.h
+++ b/media/libmediametrics/include/IMediaAnalyticsService.h
@@ -39,19 +39,25 @@
public:
DECLARE_META_INTERFACE(MediaAnalyticsService);
- // generate a unique sessionID to use across multiple requests
- // 'unique' is within this device, since last reboot
+ /**
+ * Returns a unique sessionID to use across multiple requests;
+ * 'unique' is within this device, since last reboot.
+ */
virtual MediaAnalyticsItem::SessionID_t generateUniqueSessionID() = 0;
- // submit the indicated record to the mediaanalytics service, where
- // it will be merged (if appropriate) with incomplete records that
- // share the same key and sessionid.
- // 'forcenew' marks any matching incomplete record as complete before
- // inserting this new record.
- // returns the sessionID associated with that item.
- // caller continues to own the passed item
+ /**
+ * Submits the indicated record to the mediaanalytics service, where
+ * it will be merged (if appropriate) with incomplete records that
+ * share the same key and sessionID.
+ *
+ * \param item the item to submit.
+ * \param forcenew marks any matching incomplete record as complete before
+ * inserting this new record.
+ *
+ * \return the sessionID associated with that item or
+ * MediaAnalyticsItem::SessionIDInvalid on failure.
+ */
virtual MediaAnalyticsItem::SessionID_t submit(MediaAnalyticsItem *item, bool forcenew) = 0;
-
};
// ----------------------------------------------------------------------------
@@ -59,10 +65,10 @@
class BnMediaAnalyticsService: public BnInterface<IMediaAnalyticsService>
{
public:
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
+ status_t onTransact(uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0) override;
};
}; // namespace android
diff --git a/services/mediaanalytics/Android.bp b/services/mediaanalytics/Android.bp
index 80816d7..dc72064 100644
--- a/services/mediaanalytics/Android.bp
+++ b/services/mediaanalytics/Android.bp
@@ -5,8 +5,32 @@
name: "mediametrics",
srcs: [
- "iface_statsd.cpp",
"main_mediametrics.cpp",
+ ],
+
+ shared_libs: [
+ "libbinder",
+ "liblog",
+ "libmediaanalyticsservice",
+ "libutils",
+ ],
+
+ init_rc: [
+ "mediametrics.rc",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+}
+
+cc_library_shared {
+ name: "libmediaanalyticsservice",
+
+ srcs: [
+ "iface_statsd.cpp",
"MediaAnalyticsService.cpp",
"statsd_audiopolicy.cpp",
"statsd_audiorecord.cpp",
@@ -37,16 +61,12 @@
],
include_dirs: [
- "system/media/audio_utils/include"
+ "system/media/audio_utils/include",
],
- init_rc: ["mediametrics.rc"],
-
cflags: [
"-Wall",
"-Werror",
"-Wextra",
],
- clang: true,
-
}
diff --git a/services/mediaanalytics/MediaAnalyticsService.h b/services/mediaanalytics/MediaAnalyticsService.h
index 1101a8c..ed7b7b1 100644
--- a/services/mediaanalytics/MediaAnalyticsService.h
+++ b/services/mediaanalytics/MediaAnalyticsService.h
@@ -34,8 +34,24 @@
MediaAnalyticsService();
~MediaAnalyticsService() override;
- // caller surrenders ownership of item, MediaAnalyticsService will delete.
- int64_t submit(MediaAnalyticsItem *item, bool forcenew) override;
+ /**
+ * Submits the indicated record to the mediaanalytics service, where
+ * it will be merged (if appropriate) with incomplete records that
+ * share the same key and sessionid.
+ *
+ * \param item the item to submit.
+ * \param forcenew marks any matching incomplete record as complete before
+ * inserting this new record.
+ *
+ * \return the sessionID associated with that item or
+ * MediaAnalyticsItem::SessionIDInvalid on failure.
+ *
+ * BEWARE: When called directly on the service (not from the binder interface),
+ * the caller surrenders ownership of item, MediaAnalyticsService will delete
+ * even on error. The binder interface does not take ownership.
+ * TODO: fix this inconsistency with the binder RPC interface.
+ */
+ MediaAnalyticsItem::SessionID_t submit(MediaAnalyticsItem *item, bool forcenew) override;
status_t dump(int fd, const Vector<String16>& args) override;
diff --git a/services/mediaanalytics/tests/Android.bp b/services/mediaanalytics/tests/Android.bp
new file mode 100644
index 0000000..7bca1c4
--- /dev/null
+++ b/services/mediaanalytics/tests/Android.bp
@@ -0,0 +1,25 @@
+cc_test {
+ name: "mediametrics_tests",
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+
+ include_dirs: [
+ "frameworks/av/services/mediaanalytics",
+ ],
+
+ shared_libs: [
+ "libbinder",
+ "liblog",
+ "libmediaanalyticsservice",
+ "libmediametrics",
+ "libutils",
+ ],
+
+ srcs: [
+ "mediametrics_tests.cpp",
+ ],
+}
diff --git a/services/mediaanalytics/tests/build_and_run_all_unit_tests.sh b/services/mediaanalytics/tests/build_and_run_all_unit_tests.sh
new file mode 100755
index 0000000..2511c30
--- /dev/null
+++ b/services/mediaanalytics/tests/build_and_run_all_unit_tests.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+#
+# Run tests in this directory.
+#
+
+if [ -z "$ANDROID_BUILD_TOP" ]; then
+ echo "Android build environment not set"
+ exit -1
+fi
+
+# ensure we have mm
+. $ANDROID_BUILD_TOP/build/envsetup.sh
+
+mm
+
+echo "waiting for device"
+
+adb root && adb wait-for-device remount
+
+echo "========================================"
+
+echo "testing mediametrics"
+adb push $OUT/data/nativetest/mediametrics_tests/mediametrics_tests /system/bin
+adb shell /system/bin/mediametrics_tests
diff --git a/services/mediaanalytics/tests/mediametrics_tests.cpp b/services/mediaanalytics/tests/mediametrics_tests.cpp
new file mode 100644
index 0000000..794b2f0
--- /dev/null
+++ b/services/mediaanalytics/tests/mediametrics_tests.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "mediametrics_tests"
+#include <utils/Log.h>
+
+#include "MediaAnalyticsService.h"
+
+#include <stdio.h>
+
+#include <gtest/gtest.h>
+#include <media/MediaAnalyticsItem.h>
+
+using namespace android;
+
+TEST(mediametrics_tests, instantiate) {
+ sp mediaMetrics = new MediaAnalyticsService();
+ status_t status;
+
+ // NOTE: submission of items to MediaMetrics releases ownership, even on error.
+
+ // random keys ignored when empty
+ status = mediaMetrics->submit(MediaAnalyticsItem::create("random_key"), false);
+ ASSERT_EQ(MediaAnalyticsItem::SessionIDInvalid, status);
+
+ // random keys ignored with data
+ auto random_key = MediaAnalyticsItem::create("random_key");
+ random_key->setInt32("foo", 10);
+ status = mediaMetrics->submit(random_key, false);
+ ASSERT_EQ(MediaAnalyticsItem::SessionIDInvalid, status);
+
+ // known keys ignored if empty
+ status = mediaMetrics->submit(MediaAnalyticsItem::create("audiotrack"), false);
+ ASSERT_EQ(MediaAnalyticsItem::SessionIDInvalid, status);
+
+ auto audiotrack = MediaAnalyticsItem::create("audiotrack");
+ audiotrack->addInt32("foo", 10);
+ status = mediaMetrics->submit(audiotrack, false);
+ ASSERT_GT(status, MediaAnalyticsItem::SessionIDNone);
+
+ mediaMetrics->dump(fileno(stdout), {} /* args */);
+}