MediaMetrics: Update service transaction security

Expand trusted uids.
Note calling pid is 0 for one-way transactions.
Move time rounding to WestWorld proto generation so service has better
internal time accuracy.

Test: mediametrics dumpsys, atest mediametrics_tests
Bug: 138583596
Change-Id: I9909e79de34c398bdcfa536c43bb7ea6d43e680b
diff --git a/services/mediaanalytics/MediaAnalyticsService.cpp b/services/mediaanalytics/MediaAnalyticsService.cpp
index f1f4761..091ddc5 100644
--- a/services/mediaanalytics/MediaAnalyticsService.cpp
+++ b/services/mediaanalytics/MediaAnalyticsService.cpp
@@ -22,8 +22,8 @@
 
 #include <pwd.h> //getpwuid
 
-#include <audio_utils/clock.h>                 // clock conversions
 #include <android/content/pm/IPackageManagerNative.h>  // package info
+#include <audio_utils/clock.h>                 // clock conversions
 #include <binder/IPCThreadState.h>             // get calling uid
 #include <cutils/properties.h>                 // for property_get
 #include <private/android_filesystem_config.h> // UID
@@ -51,6 +51,12 @@
 
 // TODO: need to look at tuning kMaxRecords and friends for low-memory devices
 
+/* static */
+nsecs_t MediaAnalyticsService::roundTime(nsecs_t timeNs)
+{
+    return (timeNs + NANOS_PER_SECOND / 2) / NANOS_PER_SECOND * NANOS_PER_SECOND;
+}
+
 MediaAnalyticsService::MediaAnalyticsService()
         : mMaxRecords(kMaxRecords),
           mMaxRecordAgeNs(kMaxRecordAgeNs),
@@ -70,38 +76,38 @@
 
 status_t MediaAnalyticsService::submitInternal(MediaAnalyticsItem *item, bool release)
 {
-    // we control these, generally not trusting user input
-    nsecs_t now = systemTime(SYSTEM_TIME_REALTIME);
-    // round nsecs to seconds
-    now = (now + NANOS_PER_SECOND / 2) / NANOS_PER_SECOND * NANOS_PER_SECOND;
-    // TODO: if we convert to boot time, do we need to round timestamp?
-    item->setTimestamp(now);
+    // calling PID is 0 for one-way calls.
+    const pid_t pid = IPCThreadState::self()->getCallingPid();
+    const pid_t pid_given = item->getPid();
+    const uid_t uid = IPCThreadState::self()->getCallingUid();
+    const uid_t uid_given = item->getUid();
 
-    const int pid = IPCThreadState::self()->getCallingPid();
-    const int uid = IPCThreadState::self()->getCallingUid();
-    const int uid_given = item->getUid();
-    const int pid_given = item->getPid();
+    //ALOGD("%s: caller pid=%d uid=%d,  item pid=%d uid=%d", __func__,
+    //        (int)pid, (int)uid, (int) pid_given, (int)uid_given);
 
-    ALOGV("%s: caller has uid=%d, embedded uid=%d", __func__, uid, uid_given);
     bool isTrusted;
     switch (uid) {
+    case AID_AUDIOSERVER:
+    case AID_BLUETOOTH:
+    case AID_CAMERA:
     case AID_DRM:
     case AID_MEDIA:
     case AID_MEDIA_CODEC:
     case AID_MEDIA_EX:
     case AID_MEDIA_DRM:
+    case AID_SYSTEM:
         // trusted source, only override default values
         isTrusted = true;
-        if (uid_given == -1) {
+        if (uid_given == (uid_t)-1) {
             item->setUid(uid);
         }
-        if (pid_given == -1) {
-            item->setPid(pid);
+        if (pid_given == (pid_t)-1) {
+            item->setPid(pid); // if one-way then this is 0.
         }
         break;
     default:
         isTrusted = false;
-        item->setPid(pid);
+        item->setPid(pid); // always use calling pid, if one-way then this is 0.
         item->setUid(uid);
         break;
     }
@@ -140,6 +146,16 @@
         return BAD_VALUE;
     }
 
+    if (!isTrusted || item->getTimestamp() == 0) {
+        // WestWorld logs two times for events: ElapsedRealTimeNs (BOOTTIME) and
+        // WallClockTimeNs (REALTIME).  The new audio keys use BOOTTIME.
+        //
+        // TODO: Reevaluate time base with other teams.
+        const bool useBootTime = startsWith(item->getKey(), "audio.");
+        const int64_t now = systemTime(useBootTime ? SYSTEM_TIME_BOOTTIME : SYSTEM_TIME_REALTIME);
+        item->setTimestamp(now);
+    }
+
     // now attach either the item or its dup to a const shared pointer
     std::shared_ptr<const MediaAnalyticsItem> sitem(release ? item : item->dup());
 
diff --git a/services/mediaanalytics/MediaAnalyticsService.h b/services/mediaanalytics/MediaAnalyticsService.h
index 4a8b971..ce7b9f4 100644
--- a/services/mediaanalytics/MediaAnalyticsService.h
+++ b/services/mediaanalytics/MediaAnalyticsService.h
@@ -55,6 +55,11 @@
 
     static constexpr const char * const kServiceName = "media.metrics";
 
+    /**
+     * Rounds time to the nearest second.
+     */
+    static nsecs_t roundTime(nsecs_t timeNs);
+
 protected:
 
     // Internal call where release is true if ownership of item is transferred
diff --git a/services/mediaanalytics/statsd_audiopolicy.cpp b/services/mediaanalytics/statsd_audiopolicy.cpp
index 2c11100..4e17040 100644
--- a/services/mediaanalytics/statsd_audiopolicy.cpp
+++ b/services/mediaanalytics/statsd_audiopolicy.cpp
@@ -42,7 +42,7 @@
     if (item == NULL) return false;
 
     // these go into the statsd wrapper
-    nsecs_t timestamp = item->getTimestamp();
+    const nsecs_t timestamp = MediaAnalyticsService::roundTime(item->getTimestamp());
     std::string pkgName = item->getPkgName();
     int64_t pkgVersionCode = item->getPkgVersionCode();
     int64_t mediaApexVersion = 0;
diff --git a/services/mediaanalytics/statsd_audiorecord.cpp b/services/mediaanalytics/statsd_audiorecord.cpp
index 6a80dd0..a102178 100644
--- a/services/mediaanalytics/statsd_audiorecord.cpp
+++ b/services/mediaanalytics/statsd_audiorecord.cpp
@@ -42,7 +42,7 @@
     if (item == NULL) return false;
 
     // these go into the statsd wrapper
-    nsecs_t timestamp = item->getTimestamp();
+    const nsecs_t timestamp = MediaAnalyticsService::roundTime(item->getTimestamp());
     std::string pkgName = item->getPkgName();
     int64_t pkgVersionCode = item->getPkgVersionCode();
     int64_t mediaApexVersion = 0;
diff --git a/services/mediaanalytics/statsd_audiothread.cpp b/services/mediaanalytics/statsd_audiothread.cpp
index e62899b..cf8cff2 100644
--- a/services/mediaanalytics/statsd_audiothread.cpp
+++ b/services/mediaanalytics/statsd_audiothread.cpp
@@ -42,7 +42,7 @@
     if (item == NULL) return false;
 
     // these go into the statsd wrapper
-    nsecs_t timestamp = item->getTimestamp();
+    const nsecs_t timestamp = MediaAnalyticsService::roundTime(item->getTimestamp());
     std::string pkgName = item->getPkgName();
     int64_t pkgVersionCode = item->getPkgVersionCode();
     int64_t mediaApexVersion = 0;
diff --git a/services/mediaanalytics/statsd_audiotrack.cpp b/services/mediaanalytics/statsd_audiotrack.cpp
index 10bf298..35f11d6 100644
--- a/services/mediaanalytics/statsd_audiotrack.cpp
+++ b/services/mediaanalytics/statsd_audiotrack.cpp
@@ -42,7 +42,7 @@
     if (item == NULL) return false;
 
     // these go into the statsd wrapper
-    nsecs_t timestamp = item->getTimestamp();
+    const nsecs_t timestamp = MediaAnalyticsService::roundTime(item->getTimestamp());
     std::string pkgName = item->getPkgName();
     int64_t pkgVersionCode = item->getPkgVersionCode();
     int64_t mediaApexVersion = 0;
diff --git a/services/mediaanalytics/statsd_codec.cpp b/services/mediaanalytics/statsd_codec.cpp
index 519091f..72e2c17 100644
--- a/services/mediaanalytics/statsd_codec.cpp
+++ b/services/mediaanalytics/statsd_codec.cpp
@@ -42,7 +42,7 @@
     if (item == NULL) return false;
 
     // these go into the statsd wrapper
-    nsecs_t timestamp = item->getTimestamp();
+    const nsecs_t timestamp = MediaAnalyticsService::roundTime(item->getTimestamp());
     std::string pkgName = item->getPkgName();
     int64_t pkgVersionCode = item->getPkgVersionCode();
     int64_t mediaApexVersion = 0;
diff --git a/services/mediaanalytics/statsd_drm.cpp b/services/mediaanalytics/statsd_drm.cpp
index 5c81ebf..6903e76 100644
--- a/services/mediaanalytics/statsd_drm.cpp
+++ b/services/mediaanalytics/statsd_drm.cpp
@@ -42,7 +42,7 @@
 {
     if (item == NULL) return false;
 
-    nsecs_t timestamp = item->getTimestamp();
+    const nsecs_t timestamp = MediaAnalyticsService::roundTime(item->getTimestamp());
     std::string pkgName = item->getPkgName();
     int64_t pkgVersionCode = item->getPkgVersionCode();
     int64_t mediaApexVersion = 0;
@@ -79,7 +79,7 @@
 {
     if (item == NULL) return false;
 
-    nsecs_t timestamp = item->getTimestamp();
+    const nsecs_t timestamp = MediaAnalyticsService::roundTime(item->getTimestamp());
     std::string pkgName = item->getPkgName();
     int64_t pkgVersionCode = item->getPkgVersionCode();
     int64_t mediaApexVersion = 0;
@@ -109,7 +109,7 @@
 {
     if (item == NULL) return false;
 
-    nsecs_t timestamp = item->getTimestamp();
+    const nsecs_t timestamp = MediaAnalyticsService::roundTime(item->getTimestamp());
     std::string pkgName = item->getPkgName();
     int64_t pkgVersionCode = item->getPkgVersionCode();
     int64_t mediaApexVersion = 0;
diff --git a/services/mediaanalytics/statsd_extractor.cpp b/services/mediaanalytics/statsd_extractor.cpp
index 55d5c29..b5c692e 100644
--- a/services/mediaanalytics/statsd_extractor.cpp
+++ b/services/mediaanalytics/statsd_extractor.cpp
@@ -42,7 +42,7 @@
     if (item == NULL) return false;
 
     // these go into the statsd wrapper
-    nsecs_t timestamp = item->getTimestamp();
+    const nsecs_t timestamp = MediaAnalyticsService::roundTime(item->getTimestamp());
     std::string pkgName = item->getPkgName();
     int64_t pkgVersionCode = item->getPkgVersionCode();
     int64_t mediaApexVersion = 0;
diff --git a/services/mediaanalytics/statsd_nuplayer.cpp b/services/mediaanalytics/statsd_nuplayer.cpp
index 791a125..3390233 100644
--- a/services/mediaanalytics/statsd_nuplayer.cpp
+++ b/services/mediaanalytics/statsd_nuplayer.cpp
@@ -46,7 +46,7 @@
     if (item == NULL) return false;
 
     // these go into the statsd wrapper
-    nsecs_t timestamp = item->getTimestamp();
+    const nsecs_t timestamp = MediaAnalyticsService::roundTime(item->getTimestamp());
     std::string pkgName = item->getPkgName();
     int64_t pkgVersionCode = item->getPkgVersionCode();
     int64_t mediaApexVersion = 0;
diff --git a/services/mediaanalytics/statsd_recorder.cpp b/services/mediaanalytics/statsd_recorder.cpp
index e6383e6..afb74da 100644
--- a/services/mediaanalytics/statsd_recorder.cpp
+++ b/services/mediaanalytics/statsd_recorder.cpp
@@ -42,7 +42,7 @@
     if (item == NULL) return false;
 
     // these go into the statsd wrapper
-    nsecs_t timestamp = item->getTimestamp();
+    const nsecs_t timestamp = MediaAnalyticsService::roundTime(item->getTimestamp());
     std::string pkgName = item->getPkgName();
     int64_t pkgVersionCode = item->getPkgVersionCode();
     int64_t mediaApexVersion = 0;