create a metrics log reader for tests
Add parallel logs using the new format for the old MetricsLogger calls. Deduplicate these after the new reader implementation is complete. Test: ./vendor/google/tools/systemui/systemui_test_cookbook.sh Change-Id: If12e1b66b0ec5ac23bd65e44df4f3c6d6931e722
This commit is contained in:
@@ -1,6 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging;
|
||||
|
||||
import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.view.View;
|
||||
|
||||
@@ -14,16 +30,16 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
*/
|
||||
|
||||
public class LogBuilder {
|
||||
|
||||
private static final String TAG = "LogBuilder";
|
||||
private SparseArray<Object> entries = new SparseArray();
|
||||
|
||||
public LogBuilder(int mainCategory) {
|
||||
setCategory(mainCategory);
|
||||
}
|
||||
|
||||
public LogBuilder setView(View view) {
|
||||
entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_VIEW, view.getId());
|
||||
return this;
|
||||
/* Deserialize from the eventlog */
|
||||
public LogBuilder(Object[] items) {
|
||||
deserialize(items);
|
||||
}
|
||||
|
||||
public LogBuilder setCategory(int category) {
|
||||
@@ -36,16 +52,48 @@ public class LogBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogBuilder setSubtype(int subtype) {
|
||||
entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_SUBTYPE, subtype);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogBuilder setTimestamp(long timestamp) {
|
||||
entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_TIMESTAMP, timestamp);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogBuilder setPackageName(String packageName) {
|
||||
entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_PACKAGENAME, packageName);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogBuilder setCounterName(String name) {
|
||||
entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_NAME, name);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogBuilder setCounterBucket(int bucket) {
|
||||
entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_BUCKET, bucket);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogBuilder setCounterBucket(long bucket) {
|
||||
entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_BUCKET, bucket);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogBuilder setCounterValue(int value) {
|
||||
entries.put(MetricsEvent.RESERVED_FOR_LOGBUILDER_VALUE, value);
|
||||
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)) {
|
||||
if (isValidValue(value)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Value must be loggable type - int, long, float, String");
|
||||
}
|
||||
@@ -53,6 +101,94 @@ public class LogBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isValidValue(Object value) {
|
||||
return !(value instanceof Integer ||
|
||||
value instanceof String ||
|
||||
value instanceof Long ||
|
||||
value instanceof Float);
|
||||
}
|
||||
|
||||
public Object getTaggedData(int tag) {
|
||||
return entries.get(tag);
|
||||
}
|
||||
|
||||
public int getCategory() {
|
||||
Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_CATEGORY);
|
||||
if (obj instanceof Integer) {
|
||||
return (Integer) obj;
|
||||
} else {
|
||||
return MetricsEvent.VIEW_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_TYPE);
|
||||
if (obj instanceof Integer) {
|
||||
return (Integer) obj;
|
||||
} else {
|
||||
return MetricsEvent.TYPE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public int getSubtype() {
|
||||
Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_SUBTYPE);
|
||||
if (obj instanceof Integer) {
|
||||
return (Integer) obj;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_TIMESTAMP);
|
||||
if (obj instanceof Long) {
|
||||
return (Long) obj;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_PACKAGENAME);
|
||||
if (obj instanceof String) {
|
||||
return (String) obj;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getCounterName() {
|
||||
Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_NAME);
|
||||
if (obj instanceof String) {
|
||||
return (String) obj;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public long getCounterBucket() {
|
||||
Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_BUCKET);
|
||||
if (obj instanceof Number) {
|
||||
return ((Number) obj).longValue();
|
||||
} else {
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isLongCounterBucket() {
|
||||
Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_BUCKET);
|
||||
return obj instanceof Long;
|
||||
}
|
||||
|
||||
public int getCounterValue() {
|
||||
Object obj = entries.get(MetricsEvent.RESERVED_FOR_LOGBUILDER_VALUE);
|
||||
if (obj instanceof Integer) {
|
||||
return (Integer) obj;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assemble logs into structure suitable for EventLog.
|
||||
*/
|
||||
@@ -64,5 +200,17 @@ public class LogBuilder {
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
public void deserialize(Object[] items) {
|
||||
int i = 0;
|
||||
while(i < items.length) {
|
||||
Object key = items[i++];
|
||||
Object value = i < items.length ? items[i++] : null;
|
||||
if (key instanceof Integer) {
|
||||
entries.put((Integer) key, value);
|
||||
} else {
|
||||
Log.i(TAG, "Invalid key " + key.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,10 @@ 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.
|
||||
*
|
||||
@@ -38,6 +36,10 @@ public class MetricsLogger {
|
||||
throw new IllegalArgumentException("Must define metric category");
|
||||
}
|
||||
EventLogTags.writeSysuiViewVisibility(category, 100);
|
||||
EventLogTags.writeSysuiMultiAction(
|
||||
new LogBuilder(category)
|
||||
.setType(MetricsEvent.TYPE_OPEN)
|
||||
.serialize());
|
||||
}
|
||||
|
||||
public static void hidden(Context context, int category) throws IllegalArgumentException {
|
||||
@@ -45,6 +47,10 @@ public class MetricsLogger {
|
||||
throw new IllegalArgumentException("Must define metric category");
|
||||
}
|
||||
EventLogTags.writeSysuiViewVisibility(category, 0);
|
||||
EventLogTags.writeSysuiMultiAction(
|
||||
new LogBuilder(category)
|
||||
.setType(MetricsEvent.TYPE_CLOSE)
|
||||
.serialize());
|
||||
}
|
||||
|
||||
public static void visibility(Context context, int category, boolean visibile)
|
||||
@@ -62,21 +68,38 @@ public class MetricsLogger {
|
||||
}
|
||||
|
||||
public static void action(Context context, int category) {
|
||||
action(context, category, "");
|
||||
EventLogTags.writeSysuiAction(category, "");
|
||||
EventLogTags.writeSysuiMultiAction(
|
||||
new LogBuilder(category)
|
||||
.setType(MetricsEvent.TYPE_ACTION)
|
||||
.serialize());
|
||||
}
|
||||
|
||||
public static void action(Context context, int category, int value) {
|
||||
action(context, category, Integer.toString(value));
|
||||
EventLogTags.writeSysuiAction(category, Integer.toString(value));
|
||||
EventLogTags.writeSysuiMultiAction(
|
||||
new LogBuilder(category)
|
||||
.setType(MetricsEvent.TYPE_ACTION)
|
||||
.setSubtype(value)
|
||||
.serialize());
|
||||
}
|
||||
|
||||
public static void action(Context context, int category, boolean value) {
|
||||
action(context, category, Boolean.toString(value));
|
||||
EventLogTags.writeSysuiAction(category, Boolean.toString(value));
|
||||
EventLogTags.writeSysuiMultiAction(
|
||||
new LogBuilder(category)
|
||||
.setType(MetricsEvent.TYPE_ACTION)
|
||||
.setSubtype(value ? 1 : 0)
|
||||
.serialize());
|
||||
}
|
||||
|
||||
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.
|
||||
if (content.getType() == MetricsEvent.TYPE_UNKNOWN) {
|
||||
content.setType(MetricsEvent.TYPE_ACTION);
|
||||
}
|
||||
EventLogTags.writeSysuiMultiAction(content.serialize());
|
||||
}
|
||||
|
||||
@@ -86,15 +109,30 @@ public class MetricsLogger {
|
||||
throw new IllegalArgumentException("Must define metric category");
|
||||
}
|
||||
EventLogTags.writeSysuiAction(category, pkg);
|
||||
EventLogTags.writeSysuiMultiAction(new LogBuilder(category)
|
||||
.setType(MetricsEvent.TYPE_ACTION)
|
||||
.setPackageName(pkg)
|
||||
.serialize());
|
||||
}
|
||||
|
||||
/** Add an integer value to the monotonically increasing counter with the given name. */
|
||||
public static void count(Context context, String name, int value) {
|
||||
EventLogTags.writeSysuiCount(name, value);
|
||||
EventLogTags.writeSysuiMultiAction(
|
||||
new LogBuilder(MetricsEvent.RESERVED_FOR_LOGBUILDER_COUNTER)
|
||||
.setCounterName(name)
|
||||
.setCounterValue(value)
|
||||
.serialize());
|
||||
}
|
||||
|
||||
/** Increment the bucket with the integer label on the histogram with the given name. */
|
||||
public static void histogram(Context context, String name, int bucket) {
|
||||
EventLogTags.writeSysuiHistogram(name, bucket);
|
||||
EventLogTags.writeSysuiMultiAction(
|
||||
new LogBuilder(MetricsEvent.RESERVED_FOR_LOGBUILDER_HISTOGRAM)
|
||||
.setCounterName(name)
|
||||
.setCounterBucket(bucket)
|
||||
.setCounterValue(1)
|
||||
.serialize());
|
||||
}
|
||||
}
|
||||
|
||||
64
core/java/com/android/internal/logging/MetricsReader.java
Normal file
64
core/java/com/android/internal/logging/MetricsReader.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging;
|
||||
|
||||
import com.android.internal.logging.legacy.LegacyConversionLogger;
|
||||
import com.android.internal.logging.legacy.EventLogCollector;
|
||||
|
||||
import java.util.Queue;
|
||||
|
||||
/**
|
||||
* Read platform logs.
|
||||
*/
|
||||
public class MetricsReader {
|
||||
private EventLogCollector mReader;
|
||||
private Queue<LogBuilder> mEventQueue;
|
||||
private long mLastEventMs;
|
||||
private long mCheckpointMs;
|
||||
|
||||
/** Open a new session and start reading logs.
|
||||
*
|
||||
* Starts reading from the oldest log not already read by this reader object.
|
||||
* On first invocation starts from the oldest available log ion the system.
|
||||
*/
|
||||
public void read(long startMs) {
|
||||
EventLogCollector reader = EventLogCollector.getInstance();
|
||||
LegacyConversionLogger logger = new LegacyConversionLogger();
|
||||
mLastEventMs = reader.collect(logger, startMs);
|
||||
mEventQueue = logger.getEvents();
|
||||
}
|
||||
|
||||
public void checkpoint() {
|
||||
read(0L);
|
||||
mCheckpointMs = mLastEventMs;
|
||||
mEventQueue = null;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
read(mCheckpointMs);
|
||||
}
|
||||
|
||||
/* Does the current log session have another entry? */
|
||||
public boolean hasNext() {
|
||||
return mEventQueue == null ? false : !mEventQueue.isEmpty();
|
||||
}
|
||||
|
||||
/* Next entry in the current log session. */
|
||||
public LogBuilder next() {
|
||||
return mEventQueue == null ? null : mEventQueue.remove();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Parse the Android counter event logs.
|
||||
* @hide
|
||||
*/
|
||||
public class CounterParser extends TagParser {
|
||||
private static final String TAG = "CounterParser";
|
||||
private static final int EVENTLOG_TAG = 524290;
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
|
||||
final boolean debug = Util.debug();
|
||||
if (operands.length >= 2) {
|
||||
try {
|
||||
String name = ((String) operands[0]);
|
||||
int value = (Integer) operands[1];
|
||||
logCount(logger, name, value);
|
||||
} catch (ClassCastException e) {
|
||||
if (debug) {
|
||||
Log.d(TAG, "unexpected operand type", e);
|
||||
}
|
||||
}
|
||||
} else if (debug) {
|
||||
Log.d(TAG, "wrong number of operands: " + operands.length);
|
||||
}
|
||||
}
|
||||
|
||||
protected void logCount(TronLogger logger, String name, int value) {
|
||||
logger.incrementBy(TronCounters.TRON_AOSP_PREFIX + name, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.ArrayMap;
|
||||
import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Scan the event log for interaction metrics events.
|
||||
* @hide
|
||||
*/
|
||||
public class EventLogCollector {
|
||||
private static final String TAG = "EventLogCollector";
|
||||
|
||||
// TODO replace this with GoogleLogTags.TRON_HEARTBEAT
|
||||
@VisibleForTesting
|
||||
static final int TRON_HEARTBEAT = 208000;
|
||||
|
||||
private static EventLogCollector sInstance;
|
||||
|
||||
private final ArrayMap<Integer, TagParser> mTagParsers;
|
||||
private int[] mInterestingTags;
|
||||
|
||||
private LogReader mLogReader;
|
||||
|
||||
private EventLogCollector() {
|
||||
mTagParsers = new ArrayMap<>();
|
||||
addParser(new SysuiViewVisibilityParser());
|
||||
addParser(new SysuiActionParser());
|
||||
addParser(new SysuiQueryParser());
|
||||
addParser(new NotificationPanelRevealedParser());
|
||||
addParser(new NotificationPanelHiddenParser());
|
||||
addParser(new NotificationClickedParser());
|
||||
addParser(new NotificationActionClickedParser());
|
||||
addParser(new NotificationCanceledParser());
|
||||
addParser(new NotificationVisibilityParser());
|
||||
addParser(new NotificationAlertParser());
|
||||
addParser(new NotificationExpansionParser());
|
||||
addParser(new CounterParser());
|
||||
addParser(new HistogramParser());
|
||||
addParser(new LockscreenGestureParser());
|
||||
addParser(new StatusBarStateParser());
|
||||
addParser(new PowerScreenStateParser());
|
||||
addParser(new SysuiMultiActionParser());
|
||||
|
||||
mLogReader = new LogReader();
|
||||
}
|
||||
|
||||
public static EventLogCollector getInstance() {
|
||||
if (sInstance == null) {
|
||||
sInstance = new EventLogCollector();
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setLogReader(LogReader logReader) {
|
||||
mLogReader = logReader;
|
||||
}
|
||||
|
||||
private int[] getInterestingTags() {
|
||||
if (mInterestingTags == null) {
|
||||
mInterestingTags = new int[mTagParsers.size()];
|
||||
for (int i = 0; i < mTagParsers.size(); i++) {
|
||||
mInterestingTags[i] = mTagParsers.valueAt(i).getTag();
|
||||
}
|
||||
}
|
||||
return mInterestingTags;
|
||||
}
|
||||
|
||||
// I would customize ArrayMap to add put(TagParser), but ArrayMap is final.
|
||||
@VisibleForTesting
|
||||
void addParser(TagParser parser) {
|
||||
mTagParsers.put(parser.getTag(), parser);
|
||||
mInterestingTags = null;
|
||||
}
|
||||
|
||||
public void collect(LegacyConversionLogger logger) {
|
||||
collect(logger, 0L);
|
||||
}
|
||||
|
||||
public long collect(TronLogger logger, long lastSeenEventMs) {
|
||||
long lastEventMs = 0L;
|
||||
final boolean debug = Util.debug();
|
||||
|
||||
if (debug) {
|
||||
Log.d(TAG, "Eventlog Collection");
|
||||
}
|
||||
ArrayList<Event> events = new ArrayList<>();
|
||||
try {
|
||||
mLogReader.readEvents(getInterestingTags(), events);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (debug) {
|
||||
Log.d(TAG, "read this many events: " + events.size());
|
||||
}
|
||||
|
||||
for (Event event : events) {
|
||||
final long millis = event.getTimeNanos() / 1000000;
|
||||
if (millis > lastSeenEventMs) {
|
||||
final int tag = event.getTag();
|
||||
TagParser parser = mTagParsers.get(tag);
|
||||
if (parser == null) {
|
||||
if (debug) {
|
||||
Log.d(TAG, "unknown tag: " + tag);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (debug) {
|
||||
Log.d(TAG, "parsing tag: " + tag);
|
||||
}
|
||||
parser.parseEvent(logger, event);
|
||||
lastEventMs = Math.max(lastEventMs, millis);
|
||||
} else {
|
||||
if (debug) {
|
||||
Log.d(TAG, "old event: " + millis + " < " + lastSeenEventMs);
|
||||
}
|
||||
}
|
||||
}
|
||||
return lastEventMs;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class Event {
|
||||
long mTimeNanos;
|
||||
int mTag;
|
||||
Object mData;
|
||||
|
||||
Event(long timeNanos, int tag, Object data) {
|
||||
super();
|
||||
mTimeNanos = timeNanos;
|
||||
mTag = tag;
|
||||
mData = data;
|
||||
}
|
||||
|
||||
Event(EventLog.Event event) {
|
||||
mTimeNanos = event.getTimeNanos();
|
||||
mTag = event.getTag();
|
||||
mData = event.getData();
|
||||
}
|
||||
|
||||
public long getTimeNanos() {
|
||||
return mTimeNanos;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return mTag;
|
||||
}
|
||||
|
||||
public Object getData() {
|
||||
return mData;
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class LogReader {
|
||||
public void readEvents(int[] tags, Collection<Event> events) throws IOException {
|
||||
// Testing in Android: the Static Final Class Strikes Back!
|
||||
ArrayList<EventLog.Event> nativeEvents = new ArrayList<>();
|
||||
EventLog.readEvents(tags, nativeEvents);
|
||||
for (EventLog.Event nativeEvent : nativeEvents) {
|
||||
Event event = new Event(nativeEvent);
|
||||
events.add(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
/**
|
||||
* Parse the Android histogram event logs.
|
||||
* @hide
|
||||
*/
|
||||
public class HistogramParser extends CounterParser {
|
||||
private static final String TAG = "HistogramParser";
|
||||
private static final int EVENTLOG_TAG = 524291;
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void logCount(TronLogger logger, String name, int value) {
|
||||
logger.incrementIntHistogram("tron_varz_" + name, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
/** @hide */
|
||||
public class LegacyConversionLogger implements TronLogger {
|
||||
public static final String VIEW_KEY = "view";
|
||||
public static final String TYPE_KEY = "type";
|
||||
public static final String EVENT_KEY = "data";
|
||||
|
||||
public static final int TYPE_COUNTER = 1;
|
||||
public static final int TYPE_HISTOGRAM = 2;
|
||||
public static final int TYPE_EVENT = 3;
|
||||
|
||||
private final Queue<LogBuilder> mQueue;
|
||||
private HashMap<String, Boolean> mConfig;
|
||||
|
||||
public LegacyConversionLogger() {
|
||||
mQueue = new LinkedList<>();
|
||||
}
|
||||
|
||||
public Queue<LogBuilder> getEvents() {
|
||||
return mQueue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increment(String counterName) {
|
||||
LogBuilder b = new LogBuilder(MetricsEvent.RESERVED_FOR_LOGBUILDER_COUNTER)
|
||||
.setCounterName(counterName)
|
||||
.setCounterValue(1);
|
||||
mQueue.add(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementBy(String counterName, int value) {
|
||||
LogBuilder b = new LogBuilder(MetricsEvent.RESERVED_FOR_LOGBUILDER_COUNTER)
|
||||
.setCounterName(counterName)
|
||||
.setCounterValue(value);
|
||||
mQueue.add(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementIntHistogram(String counterName, int bucket) {
|
||||
LogBuilder b = new LogBuilder(MetricsEvent.RESERVED_FOR_LOGBUILDER_HISTOGRAM)
|
||||
.setCounterName(counterName)
|
||||
.setCounterBucket(bucket)
|
||||
.setCounterValue(1);
|
||||
mQueue.add(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void incrementLongHistogram(String counterName, long bucket) {
|
||||
LogBuilder b = new LogBuilder(MetricsEvent.RESERVED_FOR_LOGBUILDER_HISTOGRAM)
|
||||
.setCounterName(counterName)
|
||||
.setCounterBucket(bucket)
|
||||
.setCounterValue(1);
|
||||
mQueue.add(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LogBuilder obtain() {
|
||||
return new LogBuilder(MetricsEvent.VIEW_UNKNOWN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose(LogBuilder proto) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEvent(LogBuilder proto) {
|
||||
mQueue.add(proto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getConfig(String configName) {
|
||||
if (mConfig != null && mConfig.containsKey(configName)) {
|
||||
return mConfig.get(configName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfig(String configName, boolean newValue) {
|
||||
if (mConfig == null) {
|
||||
mConfig = new HashMap<>();
|
||||
}
|
||||
mConfig.put(configName, newValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
/**
|
||||
* Parse the Android lockscreen gesture logs.
|
||||
* @hide
|
||||
*/
|
||||
public class LockscreenGestureParser extends TagParser {
|
||||
private static final String TAG = "LockscreenGestureParser";
|
||||
private static final int EVENTLOG_TAG = 36021;
|
||||
|
||||
// source of truth is com.android.systemui.EventLogConstants
|
||||
public static final int[] GESTURE_TYPE_MAP = {
|
||||
MetricsEvent.VIEW_UNKNOWN, // there is no type 0
|
||||
MetricsEvent.ACTION_LS_UNLOCK, // SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK = 1
|
||||
MetricsEvent.ACTION_LS_SHADE, // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE = 2
|
||||
MetricsEvent.ACTION_LS_HINT, // SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT = 3
|
||||
MetricsEvent.ACTION_LS_CAMERA, // SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA = 4
|
||||
MetricsEvent.ACTION_LS_DIALER, // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER = 5
|
||||
MetricsEvent.ACTION_LS_LOCK, // SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK = 6
|
||||
MetricsEvent.ACTION_LS_NOTE, // SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE = 7
|
||||
MetricsEvent.ACTION_LS_QS, // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS = 8
|
||||
MetricsEvent.ACTION_SHADE_QS_PULL, // SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS = 9
|
||||
MetricsEvent.ACTION_SHADE_QS_TAP // SYSUI_TAP_TO_OPEN_QS = 10
|
||||
};
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
|
||||
final boolean debug = Util.debug();
|
||||
if (operands.length >= 1) {
|
||||
try {
|
||||
int type = ((Integer) operands[0]).intValue();
|
||||
// ignore gesture length in operands[1]
|
||||
// ignore gesture velocity in operands[2]
|
||||
|
||||
int category = MetricsEvent.VIEW_UNKNOWN;
|
||||
if (type < GESTURE_TYPE_MAP.length) {
|
||||
category = GESTURE_TYPE_MAP[type];
|
||||
}
|
||||
if (category != MetricsEvent.VIEW_UNKNOWN) {
|
||||
LogBuilder proto = logger.obtain();
|
||||
proto.setCategory(category);
|
||||
proto.setType(MetricsEvent.TYPE_ACTION);
|
||||
proto.setTimestamp(eventTimeMs);
|
||||
logger.addEvent(proto);
|
||||
}
|
||||
} catch (ClassCastException e) {
|
||||
if (debug) {
|
||||
Log.e(TAG, "unexpected operand type: ", e);
|
||||
}
|
||||
}
|
||||
} else if (debug) {
|
||||
Log.w(TAG, "wrong number of operands: " + operands.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
/**
|
||||
* Parse the Android notification action button interaction event logs.
|
||||
* @hide
|
||||
*/
|
||||
public class NotificationActionClickedParser extends TagParser {
|
||||
private static final String TAG = "NotificationAction";
|
||||
private static final int EVENTLOG_TAG = 27521;
|
||||
|
||||
private final NotificationKey mKey;
|
||||
|
||||
public NotificationActionClickedParser() {
|
||||
mKey = new NotificationKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
|
||||
final boolean debug = Util.debug();
|
||||
if (operands.length > 1) {
|
||||
try {
|
||||
if (mKey.parse((String) operands[0])) {
|
||||
int index = (Integer) operands[1];
|
||||
parseTimes(operands, 2);
|
||||
LogBuilder proto = logger.obtain();
|
||||
proto.setCategory(MetricsEvent.NOTIFICATION_ITEM_ACTION);
|
||||
proto.setType(MetricsEvent.TYPE_ACTION);
|
||||
proto.setSubtype(index);
|
||||
proto.setTimestamp(eventTimeMs);
|
||||
proto.setPackageName(mKey.mPackageName);
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_ID, mKey.mId);
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_TAG, mKey.mTag);
|
||||
filltimes(proto);
|
||||
logger.addEvent(proto);
|
||||
} else if (debug) {
|
||||
Log.e(TAG, "unable to parse key.");
|
||||
}
|
||||
} catch (ClassCastException e) {
|
||||
if (debug) {
|
||||
Log.e(TAG, "unexpected operand type: ", e);
|
||||
}
|
||||
}
|
||||
} else if (debug) {
|
||||
Log.w(TAG, "wrong number of operands: " + operands.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
/**
|
||||
* Parse the new Android notification alert event logs.
|
||||
* @hide
|
||||
*/
|
||||
public class NotificationAlertParser extends TagParser {
|
||||
private static final String TAG = "NotificationAlertParser";
|
||||
private static final int EVENTLOG_TAG = 27532;
|
||||
|
||||
@VisibleForTesting
|
||||
static final int BUZZ = 0x00000001;
|
||||
@VisibleForTesting
|
||||
static final int BEEP = 0x00000002;
|
||||
@VisibleForTesting
|
||||
static final int BLINK = 0x00000004;
|
||||
|
||||
private final NotificationKey mKey;
|
||||
|
||||
public NotificationAlertParser() {
|
||||
mKey = new NotificationKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
|
||||
final boolean debug = Util.debug();
|
||||
if (operands.length > 3) {
|
||||
try {
|
||||
final String keyString = (String) operands[0];
|
||||
final boolean buzz = ((Integer) operands[1]) == 1;
|
||||
final boolean beep = ((Integer) operands[2]) == 1;
|
||||
final boolean blink = ((Integer) operands[3]) == 1;
|
||||
|
||||
if (mKey.parse(keyString)) {
|
||||
LogBuilder proto = logger.obtain();
|
||||
proto.setCategory(MetricsEvent.NOTIFICATION_ALERT);
|
||||
proto.setType(MetricsEvent.TYPE_OPEN);
|
||||
proto.setSubtype((buzz ? BUZZ : 0) | (beep ? BEEP : 0) | (blink ? BLINK : 0));
|
||||
proto.setTimestamp(eventTimeMs);
|
||||
proto.setPackageName(mKey.mPackageName);
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_ID, mKey.mId);
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_TAG, mKey.mTag);
|
||||
filltimes(proto);
|
||||
logger.addEvent(proto);
|
||||
} else {
|
||||
if (debug) {
|
||||
Log.e(TAG, "unable to parse key: " + keyString);
|
||||
}
|
||||
}
|
||||
} catch (ClassCastException e) {
|
||||
if (debug) {
|
||||
Log.e(TAG, "unexpected operand type: ", e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (debug) {
|
||||
Log.w(TAG, "wrong number of operands: " + operands.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
/**
|
||||
* Parse the Android notification cancellation event logs.
|
||||
* @hide
|
||||
*/
|
||||
public class NotificationCanceledParser extends TagParser {
|
||||
private static final String TAG = "NotificationCanceled";
|
||||
private static final int EVENTLOG_TAG = 27530;
|
||||
|
||||
// from com.android.server.notification.NotificationManagerService
|
||||
static final int REASON_DELEGATE_CLICK = 1;
|
||||
static final int REASON_DELEGATE_CANCEL = 2;
|
||||
static final int REASON_DELEGATE_CANCEL_ALL = 3;
|
||||
static final int REASON_PACKAGE_BANNED = 7;
|
||||
static final int REASON_LISTENER_CANCEL = 10;
|
||||
static final int REASON_LISTENER_CANCEL_ALL = 11;
|
||||
|
||||
private final NotificationKey mKey;
|
||||
|
||||
public NotificationCanceledParser() {
|
||||
mKey = new NotificationKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
|
||||
final boolean debug = Util.debug();
|
||||
if (operands.length > 1) {
|
||||
try {
|
||||
final String keyString = (String) operands[0];
|
||||
final int reason = (Integer) operands[1];
|
||||
parseTimes(operands, 2);
|
||||
|
||||
// handle old style log
|
||||
// TODO: delete once M is launched
|
||||
if (operands.length < 5) {
|
||||
mSinceVisibleMillis = mSinceUpdateMillis;
|
||||
mSinceUpdateMillis = 0;
|
||||
}
|
||||
|
||||
boolean intentional = true;
|
||||
switch (reason) {
|
||||
case REASON_DELEGATE_CANCEL:
|
||||
case REASON_DELEGATE_CANCEL_ALL:
|
||||
case REASON_LISTENER_CANCEL:
|
||||
case REASON_LISTENER_CANCEL_ALL:
|
||||
case REASON_DELEGATE_CLICK:
|
||||
case REASON_PACKAGE_BANNED:
|
||||
break;
|
||||
default:
|
||||
intentional = false;
|
||||
}
|
||||
|
||||
if (mKey.parse(keyString)) {
|
||||
if (intentional) {
|
||||
LogBuilder proto = logger.obtain();
|
||||
proto.setCategory(MetricsEvent.NOTIFICATION_ITEM);
|
||||
proto.setType(MetricsEvent.TYPE_DISMISS);
|
||||
proto.setSubtype(reason);
|
||||
proto.setTimestamp(eventTimeMs);
|
||||
proto.setPackageName(mKey.mPackageName);
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_ID, mKey.mId);
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_TAG, mKey.mTag);
|
||||
filltimes(proto);
|
||||
logger.addEvent(proto);
|
||||
}
|
||||
} else if (debug) {
|
||||
Log.e(TAG, "unable to parse key: " + keyString);
|
||||
}
|
||||
} catch (ClassCastException e) {
|
||||
if (debug) {
|
||||
Log.e(TAG, "unexpected operand type: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
/**
|
||||
* Parse the Android notification interaction event logs.
|
||||
* @hide
|
||||
*/
|
||||
public class NotificationClickedParser extends TagParser {
|
||||
private static final String TAG = "NotificationClicked";
|
||||
private static final int EVENTLOG_TAG = 27520;
|
||||
|
||||
private final NotificationKey mKey;
|
||||
|
||||
public NotificationClickedParser() {
|
||||
mKey = new NotificationKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
|
||||
final boolean debug = Util.debug();
|
||||
if (operands.length > 0) {
|
||||
try {
|
||||
if (mKey.parse((String) operands[0])) {
|
||||
parseTimes(operands, 1);
|
||||
LogBuilder proto = logger.obtain();
|
||||
proto.setCategory(MetricsEvent.NOTIFICATION_ITEM);
|
||||
proto.setType(MetricsEvent.TYPE_ACTION);
|
||||
proto.setTimestamp(eventTimeMs);
|
||||
proto.setPackageName(mKey.mPackageName);
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_ID, mKey.mId);
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_TAG, mKey.mTag);
|
||||
filltimes(proto);
|
||||
logger.addEvent(proto);
|
||||
} else if (debug) {
|
||||
Log.e(TAG, "unable to parse key.");
|
||||
}
|
||||
} catch (ClassCastException e) {
|
||||
if (debug) {
|
||||
Log.e(TAG, "unexpected operand type: ", e);
|
||||
}
|
||||
}
|
||||
} else if (debug) {
|
||||
Log.w(TAG, "wrong number of operands: " + operands.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
/**
|
||||
* Parse the Android notification expansion event logs.
|
||||
* @hide
|
||||
*/
|
||||
public class NotificationExpansionParser extends TagParser {
|
||||
private static final String TAG = "NotificationExpansion";
|
||||
private static final int EVENTLOG_TAG = 27511;
|
||||
|
||||
private final NotificationKey mKey;
|
||||
|
||||
public NotificationExpansionParser() {
|
||||
mKey = new NotificationKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
|
||||
final boolean debug = Util.debug();
|
||||
if (operands.length > 2) {
|
||||
try {
|
||||
if (mKey.parse((String) operands[0])) {
|
||||
boolean byUser = ((Integer) operands[1]) == 1;
|
||||
boolean expanded = ((Integer) operands[2]) == 1;
|
||||
parseTimes(operands, 3);
|
||||
|
||||
if (!byUser || !expanded) {
|
||||
return;
|
||||
}
|
||||
LogBuilder proto = logger.obtain();
|
||||
proto.setCategory(MetricsEvent.NOTIFICATION_ITEM);
|
||||
proto.setType(MetricsEvent.TYPE_DETAIL);
|
||||
proto.setTimestamp(eventTimeMs);
|
||||
proto.setPackageName(mKey.mPackageName);
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_ID, mKey.mId);
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_TAG, mKey.mTag);
|
||||
filltimes(proto);
|
||||
logger.addEvent(proto);
|
||||
} else if (debug) {
|
||||
Log.e(TAG, "unable to parse key.");
|
||||
}
|
||||
} catch (ClassCastException e) {
|
||||
if (debug) {
|
||||
Log.e(TAG, "unexpected operand type: ", e);
|
||||
}
|
||||
}
|
||||
} else if (debug) {
|
||||
Log.w(TAG, "wrong number of operands: " + operands.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Parse Android notification keys
|
||||
* @hide
|
||||
*/
|
||||
public class NotificationKey {
|
||||
|
||||
private static final String TAG = "NotificationKey";
|
||||
|
||||
public int mUser;
|
||||
public String mPackageName;
|
||||
public int mId;
|
||||
public String mTag;
|
||||
public int mUid;
|
||||
|
||||
public boolean parse(String key) {
|
||||
if (key == null) {
|
||||
return false;
|
||||
}
|
||||
boolean debug = Util.debug();
|
||||
String[] parts = key.split("\\|");
|
||||
if (parts.length == 5) {
|
||||
try {
|
||||
mUser = Integer.valueOf(parts[0]);
|
||||
mPackageName = parts[1];
|
||||
mId = Integer.valueOf(parts[2]);
|
||||
mTag = parts[3].equals("null") ? "" : parts[3];
|
||||
mUid = Integer.valueOf(parts[4]);
|
||||
return true;
|
||||
} catch (NumberFormatException e) {
|
||||
if (debug) {
|
||||
Log.w(TAG, "could not parse notification key.", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (debug) {
|
||||
Log.w(TAG, "wrong number of parts in notification key: " + key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
/**
|
||||
* Parse the Android notification panel visibility event logs.
|
||||
* @hide
|
||||
*/
|
||||
public class NotificationPanelHiddenParser extends TagParser {
|
||||
private static final String TAG = "NotificationPanelHidden";
|
||||
private static final int EVENTLOG_TAG = 27501;
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
|
||||
LogBuilder proto = logger.obtain();
|
||||
proto.setCategory(MetricsEvent.NOTIFICATION_PANEL);
|
||||
proto.setType(MetricsEvent.TYPE_CLOSE);
|
||||
proto.setTimestamp(eventTimeMs);
|
||||
logger.addEvent(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
/**
|
||||
* Parse the Android notification panel visibility event logs.
|
||||
* @hide
|
||||
*/
|
||||
public class NotificationPanelRevealedParser extends TagParser {
|
||||
private static final String TAG = "NotificationPanelRevea";
|
||||
private static final int EVENTLOG_TAG = 27500;
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
|
||||
final boolean debug = Util.debug();
|
||||
if (operands.length >= 1) {
|
||||
try {
|
||||
int load = ((Integer) operands[0]).intValue();
|
||||
//logger.incrementBy(TronCounters.TRON_NOTIFICATION_LOAD, load);
|
||||
} catch (ClassCastException e) {
|
||||
if (debug) {
|
||||
Log.e(TAG, "unexpected operand type: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogBuilder proto = logger.obtain();
|
||||
proto.setCategory(MetricsEvent.NOTIFICATION_PANEL);
|
||||
proto.setType(MetricsEvent.TYPE_OPEN);
|
||||
proto.setTimestamp(eventTimeMs);
|
||||
logger.addEvent(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
/**
|
||||
* Parse the new Android notification visibility event logs.
|
||||
* @hide
|
||||
*/
|
||||
public class NotificationVisibilityParser extends TagParser {
|
||||
private static final String TAG = "NotificationVisibility";
|
||||
private static final int EVENTLOG_TAG = 27531;
|
||||
|
||||
private final NotificationKey mKey;
|
||||
|
||||
public NotificationVisibilityParser() {
|
||||
mKey = new NotificationKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
|
||||
final boolean debug = Util.debug();
|
||||
if (operands.length > 1) {
|
||||
try {
|
||||
final String keyString = (String) operands[0];
|
||||
final boolean visible = ((Integer) operands[1]) == 1;
|
||||
parseTimes(operands, 2);
|
||||
int index = 0;
|
||||
if (operands.length > 5 && operands[5] instanceof Integer) {
|
||||
index = (Integer) operands[5];
|
||||
}
|
||||
|
||||
if (mKey.parse(keyString)) {
|
||||
LogBuilder proto = logger.obtain();
|
||||
proto.setCategory(MetricsEvent.NOTIFICATION_ITEM);
|
||||
proto.setType(visible ? MetricsEvent.TYPE_OPEN : MetricsEvent.TYPE_CLOSE);
|
||||
proto.setTimestamp(eventTimeMs);
|
||||
proto.setPackageName(mKey.mPackageName);
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_ID, mKey.mId);
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_TAG, mKey.mTag);
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_SHADE_INDEX, index);
|
||||
filltimes(proto);
|
||||
logger.addEvent(proto);
|
||||
} else {
|
||||
if (debug) {
|
||||
Log.e(TAG, "unable to parse key: " + keyString);
|
||||
}
|
||||
}
|
||||
} catch (ClassCastException e) {
|
||||
if (debug) {
|
||||
Log.e(TAG, "unexpected operand type: ", e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} else if (debug) {
|
||||
Log.w(TAG, "wrong number of operands: " + operands.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
/**
|
||||
* Parse the Android lockscreen gesture logs.
|
||||
* @hide
|
||||
*/
|
||||
public class PowerScreenStateParser extends TagParser {
|
||||
private static final String TAG = "PowerScreenStateParser";
|
||||
private static final int EVENTLOG_TAG = 2728;
|
||||
|
||||
// source of truth is android.view.WindowManagerPolicy, why:
|
||||
// 0: on
|
||||
// 1: OFF_BECAUSE_OF_ADMIN
|
||||
// 2: OFF_BECAUSE_OF_USER
|
||||
// 3: OFF_BECAUSE_OF_TIMEOUT
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
|
||||
final boolean debug = Util.debug();
|
||||
if (operands.length >= 2) {
|
||||
try {
|
||||
// (offOrOn|1|5),(becauseOfUser|1|5),(totalTouchDownTime|2|3),(touchCycles|1|1)
|
||||
boolean state = (((Integer) operands[0]).intValue()) == 1;
|
||||
int why = ((Integer) operands[1]).intValue();
|
||||
|
||||
LogBuilder proto = logger.obtain();
|
||||
proto.setCategory(MetricsEvent.SCREEN);
|
||||
proto.setType(state ? MetricsEvent.TYPE_OPEN : MetricsEvent.TYPE_CLOSE);
|
||||
proto.setTimestamp(eventTimeMs);
|
||||
proto.setSubtype(why);
|
||||
logger.addEvent(proto);
|
||||
} catch (ClassCastException e) {
|
||||
if (debug) {
|
||||
Log.e(TAG, "unexpected operand type: ", e);
|
||||
}
|
||||
}
|
||||
} else if (debug) {
|
||||
Log.w(TAG, "wrong number of operands: " + operands.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
/**
|
||||
* Parse the Android lockscreen gesture logs.
|
||||
* @hide
|
||||
*/
|
||||
public class StatusBarStateParser extends TagParser {
|
||||
private static final String TAG = "StatusBarStateParser";
|
||||
private static final int EVENTLOG_TAG = 36004;
|
||||
|
||||
// source of truth is com.android.systemui.statusbar.StatusBarState
|
||||
public static final int SHADE = 0;
|
||||
public static final int KEYGUARD = 1;
|
||||
public static final int SHADE_LOCKED = 2;
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
|
||||
final boolean debug = Util.debug();
|
||||
if (operands.length >= 6) {
|
||||
try {
|
||||
// [state, isShowing, isOccluded, isBouncerShowing, isSecure, isCurrentlyInsecure]
|
||||
int state = ((Integer) operands[0]).intValue();
|
||||
boolean isBouncerShowing = (((Integer) operands[3]).intValue()) == 1;
|
||||
int isSecure = ((Integer) operands[4]).intValue();
|
||||
|
||||
int view = MetricsEvent.LOCKSCREEN;
|
||||
int type = MetricsEvent.TYPE_OPEN;
|
||||
if (state == SHADE) {
|
||||
type = MetricsEvent.TYPE_CLOSE;
|
||||
} else if (isBouncerShowing) {
|
||||
view = MetricsEvent.BOUNCER;
|
||||
}
|
||||
|
||||
LogBuilder proto = logger.obtain();
|
||||
proto.setCategory(view);
|
||||
proto.setType(type);
|
||||
proto.setTimestamp(eventTimeMs);
|
||||
proto.setSubtype(isSecure);
|
||||
logger.addEvent(proto);
|
||||
} catch (ClassCastException e) {
|
||||
if (debug) {
|
||||
Log.e(TAG, "unexpected operand type: ", e);
|
||||
}
|
||||
}
|
||||
} else if (debug) {
|
||||
Log.w(TAG, "wrong number of operands: " + operands.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
/**
|
||||
* Parse the Android framework sysui action logs.
|
||||
* @hide
|
||||
*/
|
||||
public class SysuiActionParser extends TagParser {
|
||||
private static final String TAG = "SysuiActionParser";
|
||||
private static final int EVENTLOG_TAG = 524288;
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
|
||||
final boolean debug = Util.debug();
|
||||
try {
|
||||
String packageName = null;
|
||||
int subType = -1;
|
||||
boolean hasSubType = false;
|
||||
if (operands.length > 1) {
|
||||
String arg = (String) operands[1];
|
||||
if (arg.equals("true")) {
|
||||
hasSubType = true;
|
||||
subType = 1;
|
||||
} else if (arg.equals("false")) {
|
||||
hasSubType = true;
|
||||
subType = 0;
|
||||
} else if (arg.matches("^-?\\d+$")) {
|
||||
try {
|
||||
subType = Integer.valueOf(arg);
|
||||
hasSubType = true;
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
} else {
|
||||
packageName = arg;
|
||||
}
|
||||
}
|
||||
if (operands.length > 0) {
|
||||
int category = ((Integer) operands[0]).intValue();
|
||||
LogBuilder proto = logger.obtain();
|
||||
proto.setCategory(category);
|
||||
proto.setType(MetricsEvent.TYPE_ACTION);
|
||||
proto.setTimestamp(eventTimeMs);
|
||||
if (packageName != null) {
|
||||
proto.setPackageName(packageName);
|
||||
}
|
||||
if (hasSubType) {
|
||||
proto.setSubtype(subType);
|
||||
}
|
||||
logger.addEvent(proto);
|
||||
}
|
||||
} catch (ClassCastException e) {
|
||||
if (debug) {
|
||||
Log.e(TAG, "unexpected operand type: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
/**
|
||||
* ...and one parser to rule them all.
|
||||
*
|
||||
* This should, at some point in the future, be the only parser.
|
||||
* @hide
|
||||
*/
|
||||
public class SysuiMultiActionParser extends TagParser {
|
||||
private static final String TAG = "SysuiMultiActionParser";
|
||||
private static final int EVENTLOG_TAG = 524292;
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
|
||||
final boolean debug = Util.debug();
|
||||
try {
|
||||
logger.addEvent(new LogBuilder(operands).setTimestamp(eventTimeMs));
|
||||
} catch (ClassCastException e) {
|
||||
if (debug) {
|
||||
Log.e(TAG, "unexpected operand type: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
/**
|
||||
* Parse the Android framework sysui search query logs.
|
||||
* For now just treat them like actions.
|
||||
* @hide
|
||||
*/
|
||||
public class SysuiQueryParser extends SysuiActionParser {
|
||||
private static final String TAG = "SysuiQueryParser";
|
||||
|
||||
private static final int EVENTLOG_TAG = 524289;
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
/**
|
||||
* Parse the Android framework sysui view visibility logs.
|
||||
* @hide
|
||||
*/
|
||||
public class SysuiViewVisibilityParser extends TagParser {
|
||||
private static final String TAG = "SysuiViewVisibility";
|
||||
private static final int EVENTLOG_TAG = 524287;
|
||||
|
||||
@Override
|
||||
public int getTag() {
|
||||
return EVENTLOG_TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
|
||||
final boolean debug = Util.debug();
|
||||
if (operands.length >= 2) {
|
||||
try {
|
||||
int category = ((Integer) operands[0]).intValue();
|
||||
boolean visibility = ((Integer) operands[1]).intValue() != 0;
|
||||
|
||||
LogBuilder proto = logger.obtain();
|
||||
proto.setCategory(category);
|
||||
proto.setType(visibility ? MetricsEvent.TYPE_OPEN : MetricsEvent.TYPE_CLOSE);
|
||||
proto.setTimestamp(eventTimeMs);
|
||||
logger.addEvent(proto);
|
||||
} catch (ClassCastException e) {
|
||||
if (debug) {
|
||||
Log.e(TAG, "unexpected operand type: ", e);
|
||||
}
|
||||
}
|
||||
} else if (debug) {
|
||||
Log.w(TAG, "wrong number of operands: " + operands.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
104
core/java/com/android/internal/logging/legacy/TagParser.java
Executable file
104
core/java/com/android/internal/logging/legacy/TagParser.java
Executable file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
/**
|
||||
* Abstraction layer between EventLog static classes and the actual TagParsers.
|
||||
* @hide
|
||||
*/
|
||||
public abstract class TagParser {
|
||||
private static final String TAG = "TagParser";
|
||||
|
||||
protected int mSinceCreationMillis;
|
||||
protected int mSinceUpdateMillis;
|
||||
protected int mSinceVisibleMillis;
|
||||
|
||||
abstract int getTag();
|
||||
|
||||
@VisibleForTesting
|
||||
abstract public void parseEvent(TronLogger logger, long eventTimeMs, Object[] objects);
|
||||
|
||||
/**
|
||||
* Parse the event into the proto: return true if proto was modified.
|
||||
*/
|
||||
public void parseEvent(TronLogger logger, EventLogCollector.Event event) {
|
||||
final boolean debug = Util.debug();
|
||||
Object data = event.getData();
|
||||
Object[] objects;
|
||||
if (data instanceof Object[]) {
|
||||
objects = (Object[]) data;
|
||||
for (int i = 0; i < objects.length; i++) {
|
||||
if (objects[i] == null) {
|
||||
if (debug) {
|
||||
Log.d(TAG, "unexpected null value:" + event.getTag());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// wrap scalar objects
|
||||
objects = new Object[1];
|
||||
objects[0] = data;
|
||||
}
|
||||
|
||||
parseEvent(logger, event.getTimeNanos() / 1000000, objects);
|
||||
}
|
||||
|
||||
protected void resetTimes() {
|
||||
mSinceCreationMillis = 0;
|
||||
mSinceUpdateMillis = 0;
|
||||
mSinceVisibleMillis = 0;
|
||||
}
|
||||
|
||||
public void parseTimes(Object[] operands, int index) {
|
||||
resetTimes();
|
||||
|
||||
if (operands.length > index && operands[index] instanceof Integer) {
|
||||
mSinceCreationMillis = (Integer) operands[index];
|
||||
}
|
||||
|
||||
index++;
|
||||
if (operands.length > index && operands[index] instanceof Integer) {
|
||||
mSinceUpdateMillis = (Integer) operands[index];
|
||||
}
|
||||
|
||||
index++;
|
||||
if (operands.length > index && operands[index] instanceof Integer) {
|
||||
mSinceVisibleMillis = (Integer) operands[index];
|
||||
}
|
||||
}
|
||||
|
||||
public void filltimes(LogBuilder proto) {
|
||||
if (mSinceCreationMillis != 0) {
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_SINCE_CREATE_MILLIS,
|
||||
mSinceCreationMillis);
|
||||
}
|
||||
if (mSinceUpdateMillis != 0) {
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_SINCE_UPDATE_MILLIS,
|
||||
mSinceUpdateMillis);
|
||||
}
|
||||
if (mSinceVisibleMillis != 0) {
|
||||
proto.addTaggedData(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS,
|
||||
mSinceVisibleMillis);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
/**
|
||||
* Names of the counters that the Tron package defines.
|
||||
*
|
||||
* Other counter names may be generated by AOSP code.
|
||||
* @hide
|
||||
*/
|
||||
public class TronCounters {
|
||||
|
||||
static final String TRON_COLLECTIONS = "tron_collections";
|
||||
|
||||
static final String TRON_COLLECTION_PERIOD = "tron_collection_period_minutes";
|
||||
|
||||
static final String TRON_EVENTLOG_LENGTH = "tron_eventlog_horizon";
|
||||
|
||||
static final String TRON_NOTE_DISMISS = "tron_note_dismiss";
|
||||
|
||||
static final String TRON_NOTE_DISMISS_BY_USER = "tron_note_dismiss_user";
|
||||
|
||||
static final String TRON_NOTE_DISMISS_BY_CLICK = "tron_note_dismiss_click";
|
||||
|
||||
static final String TRON_NOTE_DISMISS_BY_LISTENER = "tron_note_dismiss_listener";
|
||||
|
||||
static final String TRON_NOTE_DISMISS_BY_BAN = "tron_note_dismiss_ban";
|
||||
|
||||
static final String TRON_NOTE_REVEALED = "tron_note_revealed";
|
||||
|
||||
static final String TRON_NOTIFICATION_LOAD = "tron_notification_load";
|
||||
|
||||
static final String TRON_VIEW = "tron_view";
|
||||
|
||||
static final String TRON_ACTION = "tron_action";
|
||||
|
||||
static final String TRON_DETAIL = "tron_detail";
|
||||
|
||||
static final String TRON_NOTE_LIFETIME = "tron_note_lifetime";
|
||||
|
||||
/** Append the AOSP-generated name */
|
||||
static final String TRON_AOSP_PREFIX = "tron_varz_";
|
||||
|
||||
static final String TRON_ACTION_BAD_INT = "tron_action_bad_int";
|
||||
|
||||
static final String TRON_NOTE_FRESHNESS = "tron_note_freshness";
|
||||
|
||||
static final String TRON_NOTE_BUZZ = "tron_note_buzz";
|
||||
|
||||
static final String TRON_NOTE_BEEP = "tron_note_beep";
|
||||
|
||||
static final String TRON_NOTE_BLINK = "tron_note_blink";
|
||||
|
||||
static final String TRON_DISABLE = "tron_disable";
|
||||
|
||||
static final String TRON_LAST_HEART_AGE = "tron_last_heart_minutes";
|
||||
|
||||
static final String TRON_HEARTS_SEEN = "tron_hearts_seen";
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
import com.android.internal.logging.LogBuilder;
|
||||
|
||||
/**
|
||||
* An entity that knows how to log events and counters.
|
||||
*/
|
||||
public interface TronLogger {
|
||||
/** Add one to the named counter. */
|
||||
void increment(String counterName);
|
||||
|
||||
/** Add an arbitrary value to the named counter. */
|
||||
void incrementBy(String counterName, int value);
|
||||
|
||||
/** Increment a specified bucket on the named histogram by one. */
|
||||
void incrementIntHistogram(String counterName, int bucket);
|
||||
|
||||
/** Increment the specified bucket on the named histogram by one. */
|
||||
void incrementLongHistogram(String counterName, long bucket);
|
||||
|
||||
/** Obtain a SystemUiEvent proto, must release this with dispose() or addEvent(). */
|
||||
LogBuilder obtain();
|
||||
|
||||
void dispose(LogBuilder proto);
|
||||
|
||||
/** Submit an event to be logged. Logger will dispose of proto. */
|
||||
void addEvent(LogBuilder proto);
|
||||
|
||||
/** Get a config flag. */
|
||||
boolean getConfig(String configName);
|
||||
|
||||
/** Set a config flag. */
|
||||
void setConfig(String configName, boolean newValue);
|
||||
}
|
||||
25
core/java/com/android/internal/logging/legacy/Util.java
Normal file
25
core/java/com/android/internal/logging/legacy/Util.java
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.internal.logging.legacy;
|
||||
|
||||
/**
|
||||
* Created by cwren on 11/21/16.
|
||||
*/
|
||||
public class Util {
|
||||
public static boolean debug() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user