Add UID for graphicsstats

Bug: 368606283
Flag: EXEMPT log only update
Test: statsd_testdrive
Change-Id: I9fbbcaa6e8bb49b7456bd13b94321298694e576f
diff --git a/libs/hwui/jni/GraphicsStatsService.cpp b/libs/hwui/jni/GraphicsStatsService.cpp
index 54369b9..80a8ae1 100644
--- a/libs/hwui/jni/GraphicsStatsService.cpp
+++ b/libs/hwui/jni/GraphicsStatsService.cpp
@@ -42,8 +42,9 @@
     return reinterpret_cast<jlong>(dump);
 }
 
-static void addToDump(JNIEnv* env, jobject, jlong dumpPtr, jstring jpath, jstring jpackage,
-                      jlong versionCode, jlong startTime, jlong endTime, jbyteArray jdata) {
+static void addToDump(JNIEnv* env, jobject, jlong dumpPtr, jstring jpath, jint uid,
+                      jstring jpackage, jlong versionCode, jlong startTime, jlong endTime,
+                      jbyteArray jdata) {
     std::string path;
     const ProfileData* data = nullptr;
     LOG_ALWAYS_FATAL_IF(jdata == nullptr && jpath == nullptr, "Path and data can't both be null");
@@ -68,7 +69,8 @@
     LOG_ALWAYS_FATAL_IF(!dump, "null passed for dump pointer");
 
     const std::string package(packageChars.c_str(), packageChars.size());
-    GraphicsStatsService::addToDump(dump, path, package, versionCode, startTime, endTime, data);
+    GraphicsStatsService::addToDump(dump, path, static_cast<uid_t>(uid), package, versionCode,
+                                    startTime, endTime, data);
 }
 
 static void addFileToDump(JNIEnv* env, jobject, jlong dumpPtr, jstring jpath) {
@@ -91,7 +93,7 @@
     GraphicsStatsService::finishDumpInMemory(dump, data, lastFullDay == JNI_TRUE);
 }
 
-static void saveBuffer(JNIEnv* env, jobject clazz, jstring jpath, jstring jpackage,
+static void saveBuffer(JNIEnv* env, jobject clazz, jstring jpath, jint uid, jstring jpackage,
                        jlong versionCode, jlong startTime, jlong endTime, jbyteArray jdata) {
     ScopedByteArrayRO buffer(env, jdata);
     LOG_ALWAYS_FATAL_IF(buffer.size() != sizeof(ProfileData),
@@ -106,7 +108,8 @@
     const std::string path(pathChars.c_str(), pathChars.size());
     const std::string package(packageChars.c_str(), packageChars.size());
     const ProfileData* data = reinterpret_cast<const ProfileData*>(buffer.get());
-    GraphicsStatsService::saveBuffer(path, package, versionCode, startTime, endTime, data);
+    GraphicsStatsService::saveBuffer(path, static_cast<uid_t>(uid), package, versionCode, startTime,
+                                     endTime, data);
 }
 
 static jobject gGraphicsStatsServiceObject = nullptr;
@@ -173,16 +176,16 @@
 } // namespace android
 using namespace android;
 
-static const JNINativeMethod sMethods[] =
-        {{"nGetAshmemSize", "()I", (void*)getAshmemSize},
-         {"nCreateDump", "(IZ)J", (void*)createDump},
-         {"nAddToDump", "(JLjava/lang/String;Ljava/lang/String;JJJ[B)V", (void*)addToDump},
-         {"nAddToDump", "(JLjava/lang/String;)V", (void*)addFileToDump},
-         {"nFinishDump", "(J)V", (void*)finishDump},
-         {"nFinishDumpInMemory", "(JJZ)V", (void*)finishDumpInMemory},
-         {"nSaveBuffer", "(Ljava/lang/String;Ljava/lang/String;JJJ[B)V", (void*)saveBuffer},
-         {"nativeInit", "()V", (void*)nativeInit},
-         {"nativeDestructor", "()V", (void*)nativeDestructor}};
+static const JNINativeMethod sMethods[] = {
+        {"nGetAshmemSize", "()I", (void*)getAshmemSize},
+        {"nCreateDump", "(IZ)J", (void*)createDump},
+        {"nAddToDump", "(JLjava/lang/String;ILjava/lang/String;JJJ[B)V", (void*)addToDump},
+        {"nAddToDump", "(JLjava/lang/String;)V", (void*)addFileToDump},
+        {"nFinishDump", "(J)V", (void*)finishDump},
+        {"nFinishDumpInMemory", "(JJZ)V", (void*)finishDumpInMemory},
+        {"nSaveBuffer", "(Ljava/lang/String;ILjava/lang/String;JJJ[B)V", (void*)saveBuffer},
+        {"nativeInit", "()V", (void*)nativeInit},
+        {"nativeDestructor", "()V", (void*)nativeDestructor}};
 
 int register_android_graphics_GraphicsStatsService(JNIEnv* env) {
     jclass graphicsStatsService_class =
diff --git a/libs/hwui/protos/graphicsstats.proto b/libs/hwui/protos/graphicsstats.proto
index 745393c..a6e786c 100644
--- a/libs/hwui/protos/graphicsstats.proto
+++ b/libs/hwui/protos/graphicsstats.proto
@@ -58,6 +58,9 @@
 
     // HWUI renders pipeline type: GL or Vulkan
     optional PipelineType pipeline = 8;
+
+    // The UID of the app
+    optional int32 uid = 9;
 }
 
 message GraphicsStatsJankSummaryProto {
diff --git a/libs/hwui/service/GraphicsStatsService.cpp b/libs/hwui/service/GraphicsStatsService.cpp
index ece5905..702f2a5 100644
--- a/libs/hwui/service/GraphicsStatsService.cpp
+++ b/libs/hwui/service/GraphicsStatsService.cpp
@@ -22,6 +22,7 @@
 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 #include <inttypes.h>
 #include <log/log.h>
+#include <stats_annotations.h>
 #include <stats_event.h>
 #include <statslog_hwui.h>
 #include <sys/mman.h>
@@ -45,9 +46,9 @@
 constexpr int sHistogramSize = ProfileData::HistogramSize();
 constexpr int sGPUHistogramSize = ProfileData::GPUHistogramSize();
 
-static bool mergeProfileDataIntoProto(protos::GraphicsStatsProto* proto, const std::string& package,
-                                      int64_t versionCode, int64_t startTime, int64_t endTime,
-                                      const ProfileData* data);
+static bool mergeProfileDataIntoProto(protos::GraphicsStatsProto* proto, uid_t uid,
+                                      const std::string& package, int64_t versionCode,
+                                      int64_t startTime, int64_t endTime, const ProfileData* data);
 static void dumpAsTextToFd(protos::GraphicsStatsProto* proto, int outFd);
 
 class FileDescriptor {
@@ -159,15 +160,16 @@
     return success;
 }
 
-bool mergeProfileDataIntoProto(protos::GraphicsStatsProto* proto, const std::string& package,
-                               int64_t versionCode, int64_t startTime, int64_t endTime,
-                               const ProfileData* data) {
+bool mergeProfileDataIntoProto(protos::GraphicsStatsProto* proto, uid_t uid,
+                               const std::string& package, int64_t versionCode, int64_t startTime,
+                               int64_t endTime, const ProfileData* data) {
     if (proto->stats_start() == 0 || proto->stats_start() > startTime) {
         proto->set_stats_start(startTime);
     }
     if (proto->stats_end() == 0 || proto->stats_end() < endTime) {
         proto->set_stats_end(endTime);
     }
+    proto->set_uid(static_cast<int32_t>(uid));
     proto->set_package_name(package);
     proto->set_version_code(versionCode);
     proto->set_pipeline(data->pipelineType() == RenderPipelineType::SkiaGL ?
@@ -286,6 +288,7 @@
               proto->package_name().c_str(), proto->has_summary());
         return;
     }
+    dprintf(fd, "\nUID: %d", proto->uid());
     dprintf(fd, "\nPackage: %s", proto->package_name().c_str());
     dprintf(fd, "\nVersion: %" PRId64, proto->version_code());
     dprintf(fd, "\nStats since: %" PRId64 "ns", proto->stats_start());
@@ -319,14 +322,15 @@
     dprintf(fd, "\n");
 }
 
-void GraphicsStatsService::saveBuffer(const std::string& path, const std::string& package,
-                                      int64_t versionCode, int64_t startTime, int64_t endTime,
-                                      const ProfileData* data) {
+void GraphicsStatsService::saveBuffer(const std::string& path, uid_t uid,
+                                      const std::string& package, int64_t versionCode,
+                                      int64_t startTime, int64_t endTime, const ProfileData* data) {
     protos::GraphicsStatsProto statsProto;
     if (!parseFromFile(path, &statsProto)) {
         statsProto.Clear();
     }
-    if (!mergeProfileDataIntoProto(&statsProto, package, versionCode, startTime, endTime, data)) {
+    if (!mergeProfileDataIntoProto(&statsProto, uid, package, versionCode, startTime, endTime,
+                                   data)) {
         return;
     }
     // Although we might not have read any data from the file, merging the existing data
@@ -383,7 +387,7 @@
 
 private:
     // use package name and app version for a key
-    typedef std::pair<std::string, int64_t> DumpKey;
+    typedef std::tuple<uid_t, std::string, int64_t> DumpKey;
 
     std::map<DumpKey, protos::GraphicsStatsProto> mStats;
     int mFd;
@@ -392,7 +396,8 @@
 };
 
 void GraphicsStatsService::Dump::mergeStat(const protos::GraphicsStatsProto& stat) {
-    auto dumpKey = std::make_pair(stat.package_name(), stat.version_code());
+    auto dumpKey = std::make_tuple(static_cast<uid_t>(stat.uid()), stat.package_name(),
+                                   stat.version_code());
     auto findIt = mStats.find(dumpKey);
     if (findIt == mStats.end()) {
         mStats[dumpKey] = stat;
@@ -437,15 +442,15 @@
     return new Dump(outFd, type);
 }
 
-void GraphicsStatsService::addToDump(Dump* dump, const std::string& path,
+void GraphicsStatsService::addToDump(Dump* dump, const std::string& path, uid_t uid,
                                      const std::string& package, int64_t versionCode,
                                      int64_t startTime, int64_t endTime, const ProfileData* data) {
     protos::GraphicsStatsProto statsProto;
     if (!path.empty() && !parseFromFile(path, &statsProto)) {
         statsProto.Clear();
     }
-    if (data &&
-        !mergeProfileDataIntoProto(&statsProto, package, versionCode, startTime, endTime, data)) {
+    if (data && !mergeProfileDataIntoProto(&statsProto, uid, package, versionCode, startTime,
+                                           endTime, data)) {
         return;
     }
     if (!statsProto.IsInitialized()) {
@@ -556,6 +561,8 @@
         // TODO: fill in UI mainline module version, when the feature is available.
         AStatsEvent_writeInt64(event, (int64_t)0);
         AStatsEvent_writeBool(event, !lastFullDay);
+        AStatsEvent_writeInt32(event, stat.uid());
+        AStatsEvent_addBoolAnnotation(event, ASTATSLOG_ANNOTATION_ID_IS_UID, true);
         AStatsEvent_build(event);
     }
     delete dump;
diff --git a/libs/hwui/service/GraphicsStatsService.h b/libs/hwui/service/GraphicsStatsService.h
index 4063f74..68c7355 100644
--- a/libs/hwui/service/GraphicsStatsService.h
+++ b/libs/hwui/service/GraphicsStatsService.h
@@ -44,13 +44,14 @@
         ProtobufStatsd,
     };
 
-    static void saveBuffer(const std::string& path, const std::string& package, int64_t versionCode,
-                           int64_t startTime, int64_t endTime, const ProfileData* data);
+    static void saveBuffer(const std::string& path, uid_t uid, const std::string& package,
+                           int64_t versionCode, int64_t startTime, int64_t endTime,
+                           const ProfileData* data);
 
     static Dump* createDump(int outFd, DumpType type);
-    static void addToDump(Dump* dump, const std::string& path, const std::string& package,
-                          int64_t versionCode, int64_t startTime, int64_t endTime,
-                          const ProfileData* data);
+    static void addToDump(Dump* dump, const std::string& path, uid_t uid,
+                          const std::string& package, int64_t versionCode, int64_t startTime,
+                          int64_t endTime, const ProfileData* data);
     static void addToDump(Dump* dump, const std::string& path);
     static void finishDump(Dump* dump);
     static void finishDumpInMemory(Dump* dump, AStatsEventList* data, bool lastFullDay);
diff --git a/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp b/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp
index c2d23e6..eb164f9 100644
--- a/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp
+++ b/libs/hwui/tests/unit/GraphicsStatsServiceTests.cpp
@@ -62,6 +62,7 @@
 
 TEST(GraphicsStats, saveLoad) {
     std::string path = findRootPath() + "/test_saveLoad";
+    uid_t uid = 123;
     std::string packageName = "com.test.saveLoad";
     MockProfileData mockData;
     mockData.editJankFrameCount() = 20;
@@ -75,12 +76,13 @@
     for (size_t i = 0; i < mockData.editSlowFrameCounts().size(); i++) {
         mockData.editSlowFrameCounts()[i] = (i % 5) + 1;
     }
-    GraphicsStatsService::saveBuffer(path, packageName, 5, 3000, 7000, &mockData);
+    GraphicsStatsService::saveBuffer(path, uid, packageName, 5, 3000, 7000, &mockData);
     protos::GraphicsStatsProto loadedProto;
     EXPECT_TRUE(GraphicsStatsService::parseFromFile(path, &loadedProto));
     // Clean up the file
     unlink(path.c_str());
 
+    EXPECT_EQ(uid, loadedProto.uid());
     EXPECT_EQ(packageName, loadedProto.package_name());
     EXPECT_EQ(5, loadedProto.version_code());
     EXPECT_EQ(3000, loadedProto.stats_start());
@@ -109,6 +111,7 @@
 TEST(GraphicsStats, merge) {
     std::string path = findRootPath() + "/test_merge";
     std::string packageName = "com.test.merge";
+    uid_t uid = 123;
     MockProfileData mockData;
     mockData.editJankFrameCount() = 20;
     mockData.editTotalFrameCount() = 100;
@@ -121,7 +124,7 @@
     for (size_t i = 0; i < mockData.editSlowFrameCounts().size(); i++) {
         mockData.editSlowFrameCounts()[i] = (i % 5) + 1;
     }
-    GraphicsStatsService::saveBuffer(path, packageName, 5, 3000, 7000, &mockData);
+    GraphicsStatsService::saveBuffer(path, uid, packageName, 5, 3000, 7000, &mockData);
     mockData.editJankFrameCount() = 50;
     mockData.editTotalFrameCount() = 500;
     for (size_t i = 0; i < mockData.editFrameCounts().size(); i++) {
@@ -130,13 +133,15 @@
     for (size_t i = 0; i < mockData.editSlowFrameCounts().size(); i++) {
         mockData.editSlowFrameCounts()[i] = ((i % 10) + 1) * 2;
     }
-    GraphicsStatsService::saveBuffer(path, packageName, 5, 7050, 10000, &mockData);
+
+    GraphicsStatsService::saveBuffer(path, uid, packageName, 5, 7050, 10000, &mockData);
 
     protos::GraphicsStatsProto loadedProto;
     EXPECT_TRUE(GraphicsStatsService::parseFromFile(path, &loadedProto));
     // Clean up the file
     unlink(path.c_str());
 
+    EXPECT_EQ(uid, loadedProto.uid());
     EXPECT_EQ(packageName, loadedProto.package_name());
     EXPECT_EQ(5, loadedProto.version_code());
     EXPECT_EQ(3000, loadedProto.stats_start());