From 4d6b54d2bfc27747974cd93b6d7f7d0a0ddcb91d Mon Sep 17 00:00:00 2001 From: Chris Wren Date: Thu, 27 Apr 2017 16:56:54 -0400 Subject: [PATCH] expose the UID in the EventLog API Bug: 32806111 Test: runtest --path frameworks/base/core/tests/coretests/src/android/metrics Change-Id: I16800a33bc6d4d37b3addd71b675fd760bd5d7b8 --- api/system-current.txt | 2 ++ core/java/android/metrics/LogMaker.java | 31 +++++++++++++++++++ core/java/android/metrics/MetricsReader.java | 10 +++++- core/java/android/util/EventLog.java | 15 +++++++++ .../src/android/metrics/LogMakerTest.java | 8 +++++ .../android/metrics/MetricsReaderTest.java | 12 ++++++- proto/src/metrics_constants.proto | 6 +++- 7 files changed, 81 insertions(+), 3 deletions(-) diff --git a/api/system-current.txt b/api/system-current.txt index 1fe7288066079..8f16d0e523b66 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -27271,6 +27271,7 @@ package android.metrics { method public java.lang.Object getTaggedData(int); method public long getTimestamp(); method public int getType(); + method public int getUid(); method public boolean isLongCounterBucket(); method public boolean isSubsetOf(android.metrics.LogMaker); method public boolean isValidValue(java.lang.Object); @@ -46743,6 +46744,7 @@ package android.util { method public int getTag(); method public int getThreadId(); method public long getTimeNanos(); + method public int getUid(); } public deprecated class EventLogTags { diff --git a/core/java/android/metrics/LogMaker.java b/core/java/android/metrics/LogMaker.java index 3c6baa76558af..2bb43bd36be3b 100644 --- a/core/java/android/metrics/LogMaker.java +++ b/core/java/android/metrics/LogMaker.java @@ -169,6 +169,27 @@ public class LogMaker { return this; } + /** + * This will be set by the system when the log is persisted. + * Client-supplied values will be ignored. + * + * @param uid to replace the existing setting. + * @hide + */ + public LogMaker setUid(int uid) { + entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_UID, uid); + return this; + } + + /** + * Remove the UID property. + * @hide + */ + public LogMaker clearUid() { + entries.remove(MetricsEvent.RESERVED_FOR_LOGBUILDER_UID); + return this; + } + /** * The name of the counter or histogram. * Only useful for counter or histogram category objects. @@ -319,6 +340,16 @@ public class LogMaker { } } + /** @return the UID of the log, or -1. */ + public int getUid() { + Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_UID); + if (obj instanceof Integer) { + return (Integer) obj; + } else { + return -1; + } + } + /** @return the name of the counter, or null. */ public String getCounterName() { Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_NAME); diff --git a/core/java/android/metrics/MetricsReader.java b/core/java/android/metrics/MetricsReader.java index 5be977ae183d9..5f356ca00d88f 100644 --- a/core/java/android/metrics/MetricsReader.java +++ b/core/java/android/metrics/MetricsReader.java @@ -93,6 +93,7 @@ public class MetricsReader { } final LogMaker log = new LogMaker(objects) .setTimestamp(eventTimestampMs) + .setUid(event.getUid()) .setProcessId(event.getProcessId()); if (log.getCategory() == MetricsEvent.METRICS_CHECKPOINT) { if (log.getSubtype() == mCheckpointTag) { @@ -155,11 +156,13 @@ public class MetricsReader { public static class Event { long mTimeMillis; int mPid; + int mUid; Object mData; - public Event(long timeMillis, int pid, Object data) { + public Event(long timeMillis, int pid, int uid, Object data) { mTimeMillis = timeMillis; mPid = pid; + mUid = uid; mData = data; } @@ -167,6 +170,7 @@ public class MetricsReader { mTimeMillis = TimeUnit.MILLISECONDS.convert( nativeEvent.getTimeNanos(), TimeUnit.NANOSECONDS); mPid = nativeEvent.getProcessId(); + mUid = nativeEvent.getUid(); mData = nativeEvent.getData(); } @@ -178,6 +182,10 @@ public class MetricsReader { return mPid; } + public int getUid() { + return mUid; + } + public Object getData() { return mData; } diff --git a/core/java/android/util/EventLog.java b/core/java/android/util/EventLog.java index 6d4281b9e0f71..92f218b4155aa 100644 --- a/core/java/android/util/EventLog.java +++ b/core/java/android/util/EventLog.java @@ -68,6 +68,7 @@ public class EventLog { private static final int THREAD_OFFSET = 8; private static final int SECONDS_OFFSET = 12; private static final int NANOSECONDS_OFFSET = 16; + private static final int UID_OFFSET = 24; // Layout for event log v1 format, v2 and v3 use HEADER_SIZE_OFFSET private static final int V1_PAYLOAD_START = 20; @@ -91,6 +92,20 @@ public class EventLog { return mBuffer.getInt(PROCESS_OFFSET); } + /** + * @return the UID which wrote the log entry + * @hide + */ + @SystemApi + public int getUid() { + try { + return mBuffer.getInt(UID_OFFSET); + } catch (IndexOutOfBoundsException e) { + // buffer won't contain the UID if the caller doesn't have permission. + return -1; + } + } + /** @return the thread ID which wrote the log entry */ public int getThreadId() { return mBuffer.getInt(THREAD_OFFSET); diff --git a/core/tests/coretests/src/android/metrics/LogMakerTest.java b/core/tests/coretests/src/android/metrics/LogMakerTest.java index 63c1f87178aa5..ada59cd849313 100644 --- a/core/tests/coretests/src/android/metrics/LogMakerTest.java +++ b/core/tests/coretests/src/android/metrics/LogMakerTest.java @@ -179,6 +179,14 @@ public class LogMakerTest extends TestCase { assertEquals(-1, builder.getProcessId()); } + public void testSetAndClearUid() { + LogMaker builder = new LogMaker(0); + builder.setUid(1); + assertEquals(1, builder.getUid()); + builder.clearUid(); + assertEquals(-1, builder.getUid()); + } + public void testGiantLogOmitted() { LogMaker badBuilder = new LogMaker(0); StringBuilder b = new StringBuilder(); diff --git a/core/tests/coretests/src/android/metrics/MetricsReaderTest.java b/core/tests/coretests/src/android/metrics/MetricsReaderTest.java index d06f522433dbe..d10b3519bccf6 100644 --- a/core/tests/coretests/src/android/metrics/MetricsReaderTest.java +++ b/core/tests/coretests/src/android/metrics/MetricsReaderTest.java @@ -26,6 +26,8 @@ import java.util.Collection; public class MetricsReaderTest extends TestCase { private static final int FULL_N = 10; private static final int CHECKPOINTED_N = 4; + private static final int PID = 1; + private static final int UID = 2; class FakeLogReader extends MetricsReader.LogReader { MetricsReader.Event[] mEvents; @@ -36,7 +38,8 @@ public class MetricsReaderTest extends TestCase { for (int i = 0; i < FULL_N; i++) { mEvents[i] = new MetricsReader.Event( 1000L + i, - 1, + PID, + UID, new LogMaker(i).serialize()); } } @@ -88,6 +91,13 @@ public class MetricsReaderTest extends TestCase { } } + public void testPidUid() { + mReader.read(0); + LogMaker log = mReader.next(); + assertEquals(PID, log.getProcessId()); + assertEquals(UID, log.getUid()); + } + public void testBlockingRead_readResetsHorizon() { mReader.read(1000); assertEquals(1000, mLogReader.mHorizonMs); diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index dc082e137da86..cc6e435507102 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -3636,7 +3636,7 @@ message MetricsEvent { // OS: N ACTION_GET_CONTACT = 864; - // This values should never appear in log outputs - it is reserved for + // This value should never appear in log outputs - it is reserved for // internal platform metrics use. RESERVED_FOR_LOGBUILDER_PID = 865; @@ -3948,6 +3948,10 @@ message MetricsEvent { // OS: O NOTIFICATION_CHANNEL_LOCK_SCREEN_VIS = 942; + // This value should never appear in log outputs - it is reserved for + // internal platform metrics use. + RESERVED_FOR_LOGBUILDER_UID = 943; + // ---- End O Constants, all O constants go above this line ---- // Add new aosp constants above this line.