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());