From 803054dccb2f2201c6b11f5ab4e61ef8dff984e1 Mon Sep 17 00:00:00 2001 From: Alison Cichowlas Date: Tue, 13 Dec 2016 14:38:01 -0500 Subject: [PATCH] Log wrapper for multi-metrics in tron. Test: Added new LogBuilderTest; runtest --path frameworks/base/core/tests/coretests/src/com/android/internal/logging/LogBuilderTest.java new file: core/java/com/android/internal/logging/LogWrapper.java Change-Id: I8c64a07b95ab9a70f39663d4ec54f9ec1bf49063 --- .../internal/logging/EventLogTags.logtags | 1 + .../android/internal/logging/LogBuilder.java | 67 +++++++++++++++++++ .../internal/logging/MetricsLogger.java | 10 +++ .../internal/logging/LogBuilderTest.java | 43 ++++++++++++ proto/src/metrics_constants.proto | 7 ++ .../server/am/ActivityMetricsLogger.java | 8 +++ 6 files changed, 136 insertions(+) create mode 100644 core/java/com/android/internal/logging/LogBuilder.java create mode 100644 core/tests/coretests/src/com/android/internal/logging/LogBuilderTest.java diff --git a/core/java/com/android/internal/logging/EventLogTags.logtags b/core/java/com/android/internal/logging/EventLogTags.logtags index 4364cc39af3fa..93d5a0373d2d7 100644 --- a/core/java/com/android/internal/logging/EventLogTags.logtags +++ b/core/java/com/android/internal/logging/EventLogTags.logtags @@ -5,5 +5,6 @@ option java_package com.android.internal.logging; # interaction logs 524287 sysui_view_visibility (category|1|5),(visible|1|6) 524288 sysui_action (category|1|5),(pkg|3) +524292 sysui_multi_action (content|4) 524290 sysui_count (name|3),(increment|1) 524291 sysui_histogram (name|3),(bucket|1) diff --git a/core/java/com/android/internal/logging/LogBuilder.java b/core/java/com/android/internal/logging/LogBuilder.java new file mode 100644 index 0000000000000..634d061e79d1e --- /dev/null +++ b/core/java/com/android/internal/logging/LogBuilder.java @@ -0,0 +1,67 @@ +package com.android.internal.logging; + +import android.util.EventLog; +import android.util.SparseArray; +import android.view.View; + +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; + + +/** + * Helper class to assemble more complex logs. + * + * @hide + */ + +public class LogBuilder { + + private SparseArray entries = new SparseArray(); + + public LogBuilder() {} + + + public LogBuilder setView(View view) { + entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_VIEW, view.getId()); + return this; + } + + public LogBuilder setCategory(int category) { + entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_CATEGORY, category); + return this; + } + + public LogBuilder setType(int type) { + entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_TYPE, type); + return this; + } + + /** + * @param tag From your MetricsEvent enum. + * @param value One of Integer, Long, Float, String + * @return + */ + public LogBuilder addTaggedData(int tag, Object value) { + if (!(value instanceof Integer || + value instanceof String || + value instanceof Long || + value instanceof Float)) { + throw new IllegalArgumentException( + "Value must be loggable type - int, long, float, String"); + } + entries.put(tag, value); + return this; + } + + /** + * Assemble logs into structure suitable for EventLog. + */ + public Object[] serialize() { + Object[] out = new Object[entries.size() * 2]; + for (int i = 0; i < entries.size(); i++) { + out[i * 2] = entries.keyAt(i); + out[i * 2 + 1] = entries.valueAt(i); + } + return out; + } +} + diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java index a94f30867e400..5eb39aed2c7b9 100644 --- a/core/java/com/android/internal/logging/MetricsLogger.java +++ b/core/java/com/android/internal/logging/MetricsLogger.java @@ -17,10 +17,12 @@ package com.android.internal.logging; import android.content.Context; import android.os.Build; +import android.util.EventLog; import android.view.View; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; + /** * Log all the things. * @@ -71,6 +73,14 @@ public class MetricsLogger { action(context, category, Boolean.toString(value)); } + public static void action(LogBuilder content) { + //EventLog.writeEvent(524292, content.serialize()); + // Below would be the *right* way to do this, using the generated + // EventLogTags method, but that doesn't work. + EventLogTags.writeSysuiMultiAction(content.serialize()); + } + + public static void action(Context context, int category, String pkg) { if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) { throw new IllegalArgumentException("Must define metric category"); diff --git a/core/tests/coretests/src/com/android/internal/logging/LogBuilderTest.java b/core/tests/coretests/src/com/android/internal/logging/LogBuilderTest.java new file mode 100644 index 0000000000000..e7d23a8edb9ce --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/logging/LogBuilderTest.java @@ -0,0 +1,43 @@ +package com.android.internal.logging; + +import junit.framework.TestCase; + +public class LogBuilderTest extends TestCase { + + public void testSerialize() { + LogBuilder builder = new LogBuilder(); + builder.addTaggedData(1, "one"); + builder.addTaggedData(2, "two"); + Object[] out = builder.serialize(); + assertEquals(1, out[0]); + assertEquals("one", out[1]); + assertEquals(2, out[2]); + assertEquals("two", out[3]); + } + + public void testInvalidInputThrows() { + LogBuilder builder = new LogBuilder(); + boolean threw = false; + try { + builder.addTaggedData(0, new Object()); + } catch (IllegalArgumentException e) { + threw = true; + } + assertTrue(threw); + assertEquals(0, builder.serialize().length); + } + + public void testValidInputTypes() { + LogBuilder builder = new LogBuilder(); + builder.addTaggedData(1, "onetwothree"); + builder.addTaggedData(2, 123); + builder.addTaggedData(3, 123L); + builder.addTaggedData(4, 123.0F); + Object[] out = builder.serialize(); + assertEquals("onetwothree", out[1]); + assertEquals(123, out[3]); + assertEquals(123L, out[5]); + assertEquals(123.0F, out[7]); + } + +} diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index eed7e70866d39..2048cc8e5b027 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -3165,6 +3165,13 @@ message MetricsEvent { // CATEGORY: Settings DIALOG_SUPPORT_SYSTEM_INFORMATION = 756; + // These values should never appear in log outputs - they are reserved for + // internal Tron use. + RESERVED_FOR_LOGBUILDER_VIEW = 757; + RESERVED_FOR_LOGBUILDER_CATEGORY = 758; + RESERVED_FOR_LOGBUILDER_TYPE = 759; + + // ---- End O Constants, all O constants go above this line ---- // Add new aosp constants above this line. diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java index 32dec96c027ee..3f166fe4ddfb3 100644 --- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java @@ -17,6 +17,7 @@ import android.content.Context; import android.os.SystemClock; import android.util.Slog; +import com.android.internal.logging.LogBuilder; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -170,6 +171,13 @@ class ActivityMetricsLogger { processRunning); MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_DEVICE_UPTIME_SECONDS, (int) (SystemClock.uptimeMillis() / 1000)); + + LogBuilder builder = new LogBuilder(); + builder.addTaggedData(MetricsEvent.APP_TRANSITION_COMPONENT_NAME, componentName); + builder.addTaggedData(MetricsEvent.APP_TRANSITION_PROCESS_RUNNING, processRunning ? 1 : 0); + builder.addTaggedData(MetricsEvent.APP_TRANSITION_DEVICE_UPTIME_SECONDS, + SystemClock.uptimeMillis() / 1000); + MetricsLogger.action(builder); } /**