MediaMetrics: Add AnalyticsActions and AnalyticsState
Factor out common analytics code from audio specifics.
Allow for saving and clearing analytics state if audioserver crashes.
Test: atest mediametrics_tests
Test: instrumented check on audioserver restart
Bug: 138583596
Change-Id: I1073f3ef95f44a383a7f14b0c2ea6f978a84ee24
diff --git a/media/libmediametrics/include/MediaMetricsItem.h b/media/libmediametrics/include/MediaMetricsItem.h
index dbbcaf9..536c0e1 100644
--- a/media/libmediametrics/include/MediaMetricsItem.h
+++ b/media/libmediametrics/include/MediaMetricsItem.h
@@ -1004,7 +1004,81 @@
const char *toCString();
const char *toCString(int version);
+ /**
+ * Returns true if the item has a property with a target value.
+ *
+ * If propName is nullptr, hasPropElem() returns false.
+ *
+ * \param propName is the property name.
+ * \param elem is the value to match. std::monostate matches any.
+ */
+ bool hasPropElem(const char *propName, const Prop::Elem& elem) const {
+ if (propName == nullptr) return false;
+ const Prop::Elem *e = get(propName);
+ return e != nullptr && (std::holds_alternative<std::monostate>(elem) || elem == *e);
+ }
+
+ /**
+ * Returns -2, -1, 0 (success) if the item has a property (wildcard matched) with a
+ * target value.
+ *
+ * The enum RecursiveWildcardCheck designates the meaning of the returned value.
+ *
+ * RECURSIVE_WILDCARD_CHECK_NO_MATCH_NO_WILDCARD = -2,
+ * RECURSIVE_WILDCARD_CHECK_NO_MATCH_WILDCARD_FOUND = -1,
+ * RECURSIVE_WILDCARD_CHECK_MATCH_FOUND = 0.
+ *
+ * If url is nullptr, RECURSIVE_WILDCARD_CHECK_NO_MATCH_NO_WILDCARD is returned.
+ *
+ * \param url is the full item + property name, which may have wildcards '*'
+ * denoting an arbitrary sequence of 0 or more characters.
+ * \param elem is the target property value to match. std::monostate matches any.
+ * \return 0 if the property was matched,
+ * -1 if the property was not matched and a wildcard char was encountered,
+ * -2 if the property was not matched with no wildcard char encountered.
+ */
+ enum RecursiveWildcardCheck {
+ RECURSIVE_WILDCARD_CHECK_NO_MATCH_NO_WILDCARD = -2,
+ RECURSIVE_WILDCARD_CHECK_NO_MATCH_WILDCARD_FOUND = -1,
+ RECURSIVE_WILDCARD_CHECK_MATCH_FOUND = 0,
+ };
+
+ enum RecursiveWildcardCheck recursiveWildcardCheckElem(
+ const char *url, const Prop::Elem& elem) const {
+ if (url == nullptr) return RECURSIVE_WILDCARD_CHECK_NO_MATCH_NO_WILDCARD;
+ return recursiveWildcardCheckElem(getKey().c_str(), url, elem);
+ }
+
private:
+
+ enum RecursiveWildcardCheck recursiveWildcardCheckElem(
+ const char *itemKeyPtr, const char *url, const Prop::Elem& elem) const {
+ for (; *url && *itemKeyPtr; ++url, ++itemKeyPtr) {
+ if (*url != *itemKeyPtr) {
+ if (*url == '*') { // wildcard
+ ++url;
+ while (true) {
+ if (recursiveWildcardCheckElem(itemKeyPtr, url, elem)
+ == RECURSIVE_WILDCARD_CHECK_MATCH_FOUND) {
+ return RECURSIVE_WILDCARD_CHECK_MATCH_FOUND;
+ }
+ if (*itemKeyPtr == 0) break;
+ ++itemKeyPtr;
+ }
+ return RECURSIVE_WILDCARD_CHECK_NO_MATCH_WILDCARD_FOUND;
+ }
+ return RECURSIVE_WILDCARD_CHECK_NO_MATCH_NO_WILDCARD;
+ }
+ }
+ if (itemKeyPtr[0] != 0 || url[0] != '.') {
+ return RECURSIVE_WILDCARD_CHECK_NO_MATCH_NO_WILDCARD;
+ }
+ const char *propName = url + 1; // skip the '.'
+ return hasPropElem(propName, elem)
+ ? RECURSIVE_WILDCARD_CHECK_MATCH_FOUND
+ : RECURSIVE_WILDCARD_CHECK_NO_MATCH_NO_WILDCARD;
+ }
+
// handle Parcel version 0
int32_t writeToParcel0(Parcel *) const;
int32_t readFromParcel0(const Parcel&);