Merge "Simplify EventLog"
This commit is contained in:
committed by
Android (Google) Code Review
commit
f0b76b80cf
@@ -1385,7 +1385,7 @@ public class LocationManagerService extends ILocationManager.Stub implements
|
||||
|
||||
ipw.println("Event Log:");
|
||||
ipw.increaseIndent();
|
||||
EVENT_LOG.iterate(manager.getName(), ipw::println);
|
||||
EVENT_LOG.iterate(ipw::println, manager.getName());
|
||||
ipw.decreaseIndent();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -16,217 +16,193 @@
|
||||
|
||||
package com.android.server.location.eventlog;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.os.SystemClock;
|
||||
import android.util.TimeUtils;
|
||||
import static java.lang.Integer.bitCount;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* An in-memory event log to support historical event information.
|
||||
* An in-memory event log to support historical event information. The log is of a constant size,
|
||||
* and new events will overwrite old events as the log fills up.
|
||||
*
|
||||
* @param <T> log event type
|
||||
*/
|
||||
public abstract class LocalEventLog {
|
||||
|
||||
private interface Log {
|
||||
// true if this is a filler element that should not be queried
|
||||
boolean isFiller();
|
||||
long getTimeDeltaMs();
|
||||
String getLogString();
|
||||
boolean filter(@Nullable String filter);
|
||||
}
|
||||
|
||||
private static final class FillerEvent implements Log {
|
||||
|
||||
static final long MAX_TIME_DELTA = (1L << 32) - 1;
|
||||
|
||||
private final int mTimeDelta;
|
||||
|
||||
FillerEvent(long timeDelta) {
|
||||
Preconditions.checkArgument(timeDelta >= 0);
|
||||
mTimeDelta = (int) timeDelta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFiller() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimeDeltaMs() {
|
||||
return Integer.toUnsignedLong(mTimeDelta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogString() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filter(String filter) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public class LocalEventLog<T> {
|
||||
|
||||
/**
|
||||
* An abstraction of a log event to be implemented by subclasses.
|
||||
* Consumer of log events for iterating over the log.
|
||||
*
|
||||
* @param <T> log event type
|
||||
*/
|
||||
public abstract static class LogEvent implements Log {
|
||||
|
||||
static final long MAX_TIME_DELTA = (1L << 32) - 1;
|
||||
|
||||
private final int mTimeDelta;
|
||||
|
||||
protected LogEvent(long timeDelta) {
|
||||
Preconditions.checkArgument(timeDelta >= 0);
|
||||
mTimeDelta = (int) timeDelta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isFiller() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final long getTimeDeltaMs() {
|
||||
return Integer.toUnsignedLong(mTimeDelta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filter(String filter) {
|
||||
return false;
|
||||
}
|
||||
public interface LogConsumer<T> {
|
||||
/** Invoked with a time and a logEvent. */
|
||||
void acceptLog(long time, T logEvent);
|
||||
}
|
||||
|
||||
// circular buffer of log entries
|
||||
private final Log[] mLog;
|
||||
private int mLogSize;
|
||||
private int mLogEndIndex;
|
||||
// masks for the entries field. 1 bit is used to indicate whether this is a filler event or not,
|
||||
// and 31 bits to store the time delta.
|
||||
private static final int IS_FILLER_MASK = 0b10000000000000000000000000000000;
|
||||
private static final int TIME_DELTA_MASK = 0b01111111111111111111111111111111;
|
||||
|
||||
private static final int IS_FILLER_OFFSET = countTrailingZeros(IS_FILLER_MASK);
|
||||
private static final int TIME_DELTA_OFFSET = countTrailingZeros(TIME_DELTA_MASK);
|
||||
|
||||
static final int MAX_TIME_DELTA = (1 << bitCount(TIME_DELTA_MASK)) - 1;
|
||||
|
||||
private static int countTrailingZeros(int i) {
|
||||
int c = 0;
|
||||
while (i != 0 && (i & 1) == 0) {
|
||||
c++;
|
||||
i = i >>> 1;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
private static int createEntry(boolean isFiller, int timeDelta) {
|
||||
Preconditions.checkArgument(timeDelta >= 0 && timeDelta <= MAX_TIME_DELTA);
|
||||
return (((isFiller ? 1 : 0) << IS_FILLER_OFFSET) & IS_FILLER_MASK)
|
||||
| ((timeDelta << TIME_DELTA_OFFSET) & TIME_DELTA_MASK);
|
||||
}
|
||||
|
||||
static int getTimeDelta(int entry) {
|
||||
return (entry & TIME_DELTA_MASK) >>> TIME_DELTA_OFFSET;
|
||||
}
|
||||
|
||||
static boolean isFiller(int entry) {
|
||||
return (entry & IS_FILLER_MASK) != 0;
|
||||
}
|
||||
|
||||
// circular buffer of log entries and events. each entry corrosponds to the log event at the
|
||||
// same index. the log entry holds the filler status and time delta according to the bit masks
|
||||
// above, and the log event is the log event.
|
||||
|
||||
@GuardedBy("this")
|
||||
final int[] mEntries;
|
||||
|
||||
@GuardedBy("this")
|
||||
final @Nullable T[] mLogEvents;
|
||||
|
||||
@GuardedBy("this")
|
||||
int mLogSize;
|
||||
|
||||
@GuardedBy("this")
|
||||
int mLogEndIndex;
|
||||
|
||||
// invalid if log is empty
|
||||
private long mStartRealtimeMs;
|
||||
private long mLastLogRealtimeMs;
|
||||
|
||||
public LocalEventLog(int size) {
|
||||
@GuardedBy("this")
|
||||
long mStartTime;
|
||||
|
||||
@GuardedBy("this")
|
||||
long mLastLogTime;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public LocalEventLog(int size, Class<T> clazz) {
|
||||
Preconditions.checkArgument(size > 0);
|
||||
mLog = new Log[size];
|
||||
|
||||
mEntries = new int[size];
|
||||
mLogEvents = (T[]) Array.newInstance(clazz, size);
|
||||
mLogSize = 0;
|
||||
mLogEndIndex = 0;
|
||||
|
||||
mStartRealtimeMs = -1;
|
||||
mLastLogRealtimeMs = -1;
|
||||
mStartTime = -1;
|
||||
mLastLogTime = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be overridden by subclasses to return a new immutable log event for the given
|
||||
* arguments (as passed into {@link #addLogEvent(int, Object...)}.
|
||||
*/
|
||||
protected abstract LogEvent createLogEvent(long timeDelta, int event, Object... args);
|
||||
|
||||
/**
|
||||
* May be optionally overridden by subclasses if they wish to change how log event time is
|
||||
* formatted.
|
||||
*/
|
||||
protected String getTimePrefix(long timeMs) {
|
||||
return TimeUtils.logTimeOfDay(timeMs) + ": ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Call to add a new log event at the current time. The arguments provided here will be passed
|
||||
* into {@link #createLogEvent(long, int, Object...)} in addition to a time delta, and should be
|
||||
* used to construct an appropriate {@link LogEvent} object.
|
||||
*/
|
||||
public synchronized void addLogEvent(int event, Object... args) {
|
||||
long timeMs = SystemClock.elapsedRealtime();
|
||||
/** Call to add a new log event at the given time. */
|
||||
protected synchronized void addLog(long time, T logEvent) {
|
||||
Preconditions.checkArgument(logEvent != null);
|
||||
|
||||
// calculate delta
|
||||
long delta = 0;
|
||||
if (!isEmpty()) {
|
||||
delta = timeMs - mLastLogRealtimeMs;
|
||||
delta = time - mLastLogTime;
|
||||
|
||||
// if the delta is invalid, or if the delta is great enough using filler elements would
|
||||
// if the delta is negative, or if the delta is great enough using filler elements would
|
||||
// result in an empty log anyways, just clear the log and continue, otherwise insert
|
||||
// filler elements until we have a reasonable delta
|
||||
if (delta < 0 || (delta / FillerEvent.MAX_TIME_DELTA) >= mLog.length - 1) {
|
||||
if (delta < 0 || (delta / MAX_TIME_DELTA) >= mEntries.length - 1) {
|
||||
clear();
|
||||
delta = 0;
|
||||
} else {
|
||||
while (delta >= LogEvent.MAX_TIME_DELTA) {
|
||||
long timeDelta = Math.min(FillerEvent.MAX_TIME_DELTA, delta);
|
||||
addLogEventInternal(new FillerEvent(timeDelta));
|
||||
delta -= timeDelta;
|
||||
while (delta >= MAX_TIME_DELTA) {
|
||||
addLogEventInternal(true, MAX_TIME_DELTA, null);
|
||||
delta -= MAX_TIME_DELTA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for first log entry, set initial times
|
||||
if (isEmpty()) {
|
||||
mStartRealtimeMs = timeMs;
|
||||
mLastLogRealtimeMs = mStartRealtimeMs;
|
||||
mStartTime = time;
|
||||
mLastLogTime = mStartTime;
|
||||
}
|
||||
|
||||
addLogEventInternal(createLogEvent(delta, event, args));
|
||||
addLogEventInternal(false, (int) delta, logEvent);
|
||||
}
|
||||
|
||||
private void addLogEventInternal(Log event) {
|
||||
Preconditions.checkState(mStartRealtimeMs != -1 && mLastLogRealtimeMs != -1);
|
||||
@GuardedBy("this")
|
||||
private void addLogEventInternal(boolean isFiller, int timeDelta, @Nullable T logEvent) {
|
||||
Preconditions.checkArgument(isFiller || logEvent != null);
|
||||
Preconditions.checkState(mStartTime != -1 && mLastLogTime != -1);
|
||||
|
||||
if (mLogSize == mLog.length) {
|
||||
if (mLogSize == mEntries.length) {
|
||||
// if log is full, size will remain the same, but update the start time
|
||||
mStartRealtimeMs += mLog[startIndex()].getTimeDeltaMs();
|
||||
mStartTime += getTimeDelta(mEntries[startIndex()]);
|
||||
} else {
|
||||
// otherwise add an item
|
||||
mLogSize++;
|
||||
}
|
||||
|
||||
// set log and increment end index
|
||||
mLog[mLogEndIndex] = event;
|
||||
mEntries[mLogEndIndex] = createEntry(isFiller, timeDelta);
|
||||
mLogEvents[mLogEndIndex] = logEvent;
|
||||
mLogEndIndex = incrementIndex(mLogEndIndex);
|
||||
mLastLogRealtimeMs = mLastLogRealtimeMs + event.getTimeDeltaMs();
|
||||
mLastLogTime = mLastLogTime + timeDelta;
|
||||
}
|
||||
|
||||
/** Clears the log of all entries. */
|
||||
public synchronized void clear() {
|
||||
// clear entries to allow gc
|
||||
Arrays.fill(mLogEvents, null);
|
||||
|
||||
mLogEndIndex = 0;
|
||||
mLogSize = 0;
|
||||
|
||||
mStartRealtimeMs = -1;
|
||||
mLastLogRealtimeMs = -1;
|
||||
mStartTime = -1;
|
||||
mLastLogTime = -1;
|
||||
}
|
||||
|
||||
// checks if the log is empty (if empty, times are invalid)
|
||||
private synchronized boolean isEmpty() {
|
||||
@GuardedBy("this")
|
||||
private boolean isEmpty() {
|
||||
return mLogSize == 0;
|
||||
}
|
||||
|
||||
/** Iterates over the event log, passing each log string to the given consumer. */
|
||||
public synchronized void iterate(Consumer<String> consumer) {
|
||||
public synchronized void iterate(LogConsumer<? super T> consumer) {
|
||||
LogIterator it = new LogIterator();
|
||||
while (it.hasNext()) {
|
||||
consumer.accept(it.next());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over the event log, passing each filter-matching log string to the given
|
||||
* consumer.
|
||||
*/
|
||||
public synchronized void iterate(String filter, Consumer<String> consumer) {
|
||||
LogIterator it = new LogIterator(filter);
|
||||
while (it.hasNext()) {
|
||||
consumer.accept(it.next());
|
||||
it.next();
|
||||
consumer.acceptLog(it.getTime(), it.getLog());
|
||||
}
|
||||
}
|
||||
|
||||
// returns the index of the first element
|
||||
@GuardedBy("this")
|
||||
private int startIndex() {
|
||||
return wrapIndex(mLogEndIndex - mLogSize);
|
||||
}
|
||||
|
||||
// returns the index after this one
|
||||
@GuardedBy("this")
|
||||
private int incrementIndex(int index) {
|
||||
if (index == -1) {
|
||||
return startIndex();
|
||||
@@ -238,69 +214,68 @@ public abstract class LocalEventLog {
|
||||
}
|
||||
|
||||
// rolls over the given index if necessary
|
||||
@GuardedBy("this")
|
||||
private int wrapIndex(int index) {
|
||||
// java modulo will keep negative sign, we need to rollover
|
||||
return (index % mLog.length + mLog.length) % mLog.length;
|
||||
return (index % mEntries.length + mEntries.length) % mEntries.length;
|
||||
}
|
||||
|
||||
private class LogIterator implements Iterator<String> {
|
||||
private class LogIterator {
|
||||
|
||||
private final @Nullable String mFilter;
|
||||
|
||||
private final long mSystemTimeDeltaMs;
|
||||
|
||||
private long mCurrentRealtimeMs;
|
||||
private long mLogTime;
|
||||
private int mIndex;
|
||||
private int mCount;
|
||||
|
||||
private long mCurrentTime;
|
||||
private T mCurrentLogEvent;
|
||||
|
||||
LogIterator() {
|
||||
this(null);
|
||||
}
|
||||
synchronized (LocalEventLog.this) {
|
||||
mLogTime = mStartTime;
|
||||
mIndex = -1;
|
||||
mCount = -1;
|
||||
|
||||
LogIterator(@Nullable String filter) {
|
||||
mFilter = filter;
|
||||
mSystemTimeDeltaMs = System.currentTimeMillis() - SystemClock.elapsedRealtime();
|
||||
mCurrentRealtimeMs = mStartRealtimeMs;
|
||||
mIndex = -1;
|
||||
mCount = -1;
|
||||
|
||||
increment();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return mCount < mLogSize;
|
||||
}
|
||||
|
||||
public String next() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
increment();
|
||||
}
|
||||
|
||||
Log log = mLog[mIndex];
|
||||
long timeMs = mCurrentRealtimeMs + log.getTimeDeltaMs() + mSystemTimeDeltaMs;
|
||||
|
||||
increment();
|
||||
|
||||
return getTimePrefix(timeMs) + log.getLogString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
public boolean hasNext() {
|
||||
synchronized (LocalEventLog.this) {
|
||||
return mCount < mLogSize;
|
||||
}
|
||||
}
|
||||
|
||||
private void increment() {
|
||||
long nextDeltaMs = mIndex == -1 ? 0 : mLog[mIndex].getTimeDeltaMs();
|
||||
public void next() {
|
||||
synchronized (LocalEventLog.this) {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
mCurrentTime = mLogTime + getTimeDelta(mEntries[mIndex]);
|
||||
mCurrentLogEvent = Objects.requireNonNull(mLogEvents[mIndex]);
|
||||
|
||||
increment();
|
||||
}
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return mCurrentTime;
|
||||
}
|
||||
|
||||
public T getLog() {
|
||||
return mCurrentLogEvent;
|
||||
}
|
||||
|
||||
@GuardedBy("LocalEventLog.this")
|
||||
private void increment(LogIterator this) {
|
||||
long nextDeltaMs = mIndex == -1 ? 0 : getTimeDelta(mEntries[mIndex]);
|
||||
do {
|
||||
mCurrentRealtimeMs += nextDeltaMs;
|
||||
mLogTime += nextDeltaMs;
|
||||
mIndex = incrementIndex(mIndex);
|
||||
if (++mCount < mLogSize) {
|
||||
nextDeltaMs = mLog[mIndex].getTimeDeltaMs();
|
||||
nextDeltaMs = getTimeDelta(mEntries[mIndex]);
|
||||
}
|
||||
} while (mCount < mLogSize && (mLog[mIndex].isFiller() || (mFilter != null
|
||||
&& !mLog[mIndex].filter(mFilter))));
|
||||
} while (mCount < mLogSize && isFiller(mEntries[mIndex]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,12 +36,15 @@ import android.location.util.identity.CallerIdentity;
|
||||
import android.os.PowerManager.LocationPowerSaveMode;
|
||||
import android.os.SystemClock;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.TimeUtils;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/** In memory event log for location events. */
|
||||
public class LocationEventLog extends LocalEventLog {
|
||||
public class LocationEventLog extends LocalEventLog<Object> {
|
||||
|
||||
public static final LocationEventLog EVENT_LOG = new LocationEventLog();
|
||||
|
||||
@@ -53,28 +56,11 @@ public class LocationEventLog extends LocalEventLog {
|
||||
}
|
||||
}
|
||||
|
||||
private static final int EVENT_USER_SWITCHED = 1;
|
||||
private static final int EVENT_LOCATION_ENABLED = 2;
|
||||
private static final int EVENT_ADAS_LOCATION_ENABLED = 3;
|
||||
private static final int EVENT_PROVIDER_ENABLED = 4;
|
||||
private static final int EVENT_PROVIDER_MOCKED = 5;
|
||||
private static final int EVENT_PROVIDER_CLIENT_REGISTER = 6;
|
||||
private static final int EVENT_PROVIDER_CLIENT_UNREGISTER = 7;
|
||||
private static final int EVENT_PROVIDER_CLIENT_FOREGROUND = 8;
|
||||
private static final int EVENT_PROVIDER_CLIENT_BACKGROUND = 9;
|
||||
private static final int EVENT_PROVIDER_CLIENT_PERMITTED = 10;
|
||||
private static final int EVENT_PROVIDER_CLIENT_UNPERMITTED = 11;
|
||||
private static final int EVENT_PROVIDER_UPDATE_REQUEST = 12;
|
||||
private static final int EVENT_PROVIDER_RECEIVE_LOCATION = 13;
|
||||
private static final int EVENT_PROVIDER_DELIVER_LOCATION = 14;
|
||||
private static final int EVENT_PROVIDER_STATIONARY_THROTTLED = 15;
|
||||
private static final int EVENT_LOCATION_POWER_SAVE_MODE_CHANGE = 16;
|
||||
|
||||
@GuardedBy("mAggregateStats")
|
||||
private final ArrayMap<String, ArrayMap<CallerIdentity, AggregateStats>> mAggregateStats;
|
||||
|
||||
public LocationEventLog() {
|
||||
super(getLogSize());
|
||||
super(getLogSize(), Object.class);
|
||||
mAggregateStats = new ArrayMap<>(4);
|
||||
}
|
||||
|
||||
@@ -109,39 +95,39 @@ public class LocationEventLog extends LocalEventLog {
|
||||
|
||||
/** Logs a user switched event. */
|
||||
public void logUserSwitched(int userIdFrom, int userIdTo) {
|
||||
addLogEvent(EVENT_USER_SWITCHED, userIdFrom, userIdTo);
|
||||
addLogEvent(new UserSwitchedEvent(userIdFrom, userIdTo));
|
||||
}
|
||||
|
||||
/** Logs a location enabled/disabled event. */
|
||||
public void logLocationEnabled(int userId, boolean enabled) {
|
||||
addLogEvent(EVENT_LOCATION_ENABLED, userId, enabled);
|
||||
addLogEvent(new LocationEnabledEvent(userId, enabled));
|
||||
}
|
||||
|
||||
/** Logs a location enabled/disabled event. */
|
||||
public void logAdasLocationEnabled(int userId, boolean enabled) {
|
||||
addLogEvent(EVENT_ADAS_LOCATION_ENABLED, userId, enabled);
|
||||
addLogEvent(new LocationAdasEnabledEvent(userId, enabled));
|
||||
}
|
||||
|
||||
/** Logs a location provider enabled/disabled event. */
|
||||
public void logProviderEnabled(String provider, int userId, boolean enabled) {
|
||||
addLogEvent(EVENT_PROVIDER_ENABLED, provider, userId, enabled);
|
||||
addLogEvent(new ProviderEnabledEvent(provider, userId, enabled));
|
||||
}
|
||||
|
||||
/** Logs a location provider being replaced/unreplaced by a mock provider. */
|
||||
public void logProviderMocked(String provider, boolean mocked) {
|
||||
addLogEvent(EVENT_PROVIDER_MOCKED, provider, mocked);
|
||||
addLogEvent(new ProviderMockedEvent(provider, mocked));
|
||||
}
|
||||
|
||||
/** Logs a new client registration for a location provider. */
|
||||
public void logProviderClientRegistered(String provider, CallerIdentity identity,
|
||||
LocationRequest request) {
|
||||
addLogEvent(EVENT_PROVIDER_CLIENT_REGISTER, provider, identity, request);
|
||||
addLogEvent(new ProviderClientRegisterEvent(provider, true, identity, request));
|
||||
getAggregateStats(provider, identity).markRequestAdded(request.getIntervalMillis());
|
||||
}
|
||||
|
||||
/** Logs a client unregistration for a location provider. */
|
||||
public void logProviderClientUnregistered(String provider, CallerIdentity identity) {
|
||||
addLogEvent(EVENT_PROVIDER_CLIENT_UNREGISTER, provider, identity);
|
||||
addLogEvent(new ProviderClientRegisterEvent(provider, false, identity, null));
|
||||
getAggregateStats(provider, identity).markRequestRemoved();
|
||||
}
|
||||
|
||||
@@ -158,7 +144,7 @@ public class LocationEventLog extends LocalEventLog {
|
||||
/** Logs a client for a location provider entering the foreground state. */
|
||||
public void logProviderClientForeground(String provider, CallerIdentity identity) {
|
||||
if (D) {
|
||||
addLogEvent(EVENT_PROVIDER_CLIENT_FOREGROUND, provider, identity);
|
||||
addLogEvent(new ProviderClientForegroundEvent(provider, true, identity));
|
||||
}
|
||||
getAggregateStats(provider, identity).markRequestForeground();
|
||||
}
|
||||
@@ -166,7 +152,7 @@ public class LocationEventLog extends LocalEventLog {
|
||||
/** Logs a client for a location provider leaving the foreground state. */
|
||||
public void logProviderClientBackground(String provider, CallerIdentity identity) {
|
||||
if (D) {
|
||||
addLogEvent(EVENT_PROVIDER_CLIENT_BACKGROUND, provider, identity);
|
||||
addLogEvent(new ProviderClientForegroundEvent(provider, false, identity));
|
||||
}
|
||||
getAggregateStats(provider, identity).markRequestBackground();
|
||||
}
|
||||
@@ -174,32 +160,32 @@ public class LocationEventLog extends LocalEventLog {
|
||||
/** Logs a client for a location provider entering the permitted state. */
|
||||
public void logProviderClientPermitted(String provider, CallerIdentity identity) {
|
||||
if (D) {
|
||||
addLogEvent(EVENT_PROVIDER_CLIENT_PERMITTED, provider, identity);
|
||||
addLogEvent(new ProviderClientPermittedEvent(provider, true, identity));
|
||||
}
|
||||
}
|
||||
|
||||
/** Logs a client for a location provider leaving the permitted state. */
|
||||
public void logProviderClientUnpermitted(String provider, CallerIdentity identity) {
|
||||
if (D) {
|
||||
addLogEvent(EVENT_PROVIDER_CLIENT_UNPERMITTED, provider, identity);
|
||||
addLogEvent(new ProviderClientPermittedEvent(provider, false, identity));
|
||||
}
|
||||
}
|
||||
|
||||
/** Logs a change to the provider request for a location provider. */
|
||||
public void logProviderUpdateRequest(String provider, ProviderRequest request) {
|
||||
addLogEvent(EVENT_PROVIDER_UPDATE_REQUEST, provider, request);
|
||||
addLogEvent(new ProviderUpdateEvent(provider, request));
|
||||
}
|
||||
|
||||
/** Logs a new incoming location for a location provider. */
|
||||
public void logProviderReceivedLocations(String provider, int numLocations) {
|
||||
addLogEvent(EVENT_PROVIDER_RECEIVE_LOCATION, provider, numLocations);
|
||||
addLogEvent(new ProviderReceiveLocationEvent(provider, numLocations));
|
||||
}
|
||||
|
||||
/** Logs a location deliver for a client of a location provider. */
|
||||
public void logProviderDeliveredLocations(String provider, int numLocations,
|
||||
CallerIdentity identity) {
|
||||
if (D) {
|
||||
addLogEvent(EVENT_PROVIDER_DELIVER_LOCATION, provider, numLocations, identity);
|
||||
addLogEvent(new ProviderDeliverLocationEvent(provider, numLocations, identity));
|
||||
}
|
||||
getAggregateStats(provider, identity).markLocationDelivered();
|
||||
}
|
||||
@@ -207,80 +193,47 @@ public class LocationEventLog extends LocalEventLog {
|
||||
/** Logs that a provider has entered or exited stationary throttling. */
|
||||
public void logProviderStationaryThrottled(String provider, boolean throttled,
|
||||
ProviderRequest request) {
|
||||
addLogEvent(EVENT_PROVIDER_STATIONARY_THROTTLED, provider, throttled, request);
|
||||
addLogEvent(new ProviderStationaryThrottledEvent(provider, throttled, request));
|
||||
}
|
||||
|
||||
/** Logs that the location power save mode has changed. */
|
||||
public void logLocationPowerSaveMode(
|
||||
@LocationPowerSaveMode int locationPowerSaveMode) {
|
||||
addLogEvent(EVENT_LOCATION_POWER_SAVE_MODE_CHANGE, locationPowerSaveMode);
|
||||
addLogEvent(new LocationPowerSaveModeEvent(locationPowerSaveMode));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LogEvent createLogEvent(long timeDelta, int event, Object... args) {
|
||||
switch (event) {
|
||||
case EVENT_USER_SWITCHED:
|
||||
return new UserSwitchedEvent(timeDelta, (Integer) args[0], (Integer) args[1]);
|
||||
case EVENT_LOCATION_ENABLED:
|
||||
return new LocationEnabledEvent(timeDelta, (Integer) args[0], (Boolean) args[1]);
|
||||
case EVENT_ADAS_LOCATION_ENABLED:
|
||||
return new LocationAdasEnabledEvent(timeDelta, (Integer) args[0],
|
||||
(Boolean) args[1]);
|
||||
case EVENT_PROVIDER_ENABLED:
|
||||
return new ProviderEnabledEvent(timeDelta, (String) args[0], (Integer) args[1],
|
||||
(Boolean) args[2]);
|
||||
case EVENT_PROVIDER_MOCKED:
|
||||
return new ProviderMockedEvent(timeDelta, (String) args[0], (Boolean) args[1]);
|
||||
case EVENT_PROVIDER_CLIENT_REGISTER:
|
||||
return new ProviderClientRegisterEvent(timeDelta, (String) args[0], true,
|
||||
(CallerIdentity) args[1], (LocationRequest) args[2]);
|
||||
case EVENT_PROVIDER_CLIENT_UNREGISTER:
|
||||
return new ProviderClientRegisterEvent(timeDelta, (String) args[0], false,
|
||||
(CallerIdentity) args[1], null);
|
||||
case EVENT_PROVIDER_CLIENT_FOREGROUND:
|
||||
return new ProviderClientForegroundEvent(timeDelta, (String) args[0], true,
|
||||
(CallerIdentity) args[1]);
|
||||
case EVENT_PROVIDER_CLIENT_BACKGROUND:
|
||||
return new ProviderClientForegroundEvent(timeDelta, (String) args[0], false,
|
||||
(CallerIdentity) args[1]);
|
||||
case EVENT_PROVIDER_CLIENT_PERMITTED:
|
||||
return new ProviderClientPermittedEvent(timeDelta, (String) args[0], true,
|
||||
(CallerIdentity) args[1]);
|
||||
case EVENT_PROVIDER_CLIENT_UNPERMITTED:
|
||||
return new ProviderClientPermittedEvent(timeDelta, (String) args[0], false,
|
||||
(CallerIdentity) args[1]);
|
||||
case EVENT_PROVIDER_UPDATE_REQUEST:
|
||||
return new ProviderUpdateEvent(timeDelta, (String) args[0],
|
||||
(ProviderRequest) args[1]);
|
||||
case EVENT_PROVIDER_RECEIVE_LOCATION:
|
||||
return new ProviderReceiveLocationEvent(timeDelta, (String) args[0],
|
||||
(Integer) args[1]);
|
||||
case EVENT_PROVIDER_DELIVER_LOCATION:
|
||||
return new ProviderDeliverLocationEvent(timeDelta, (String) args[0],
|
||||
(Integer) args[1], (CallerIdentity) args[2]);
|
||||
case EVENT_PROVIDER_STATIONARY_THROTTLED:
|
||||
return new ProviderStationaryThrottledEvent(timeDelta, (String) args[0],
|
||||
(Boolean) args[1], (ProviderRequest) args[2]);
|
||||
case EVENT_LOCATION_POWER_SAVE_MODE_CHANGE:
|
||||
return new LocationPowerSaveModeEvent(timeDelta, (Integer) args[0]);
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
private void addLogEvent(Object logEvent) {
|
||||
addLog(SystemClock.elapsedRealtime(), logEvent);
|
||||
}
|
||||
|
||||
private abstract static class ProviderEvent extends LogEvent {
|
||||
public void iterate(Consumer<String> consumer) {
|
||||
iterate(consumer, null);
|
||||
}
|
||||
|
||||
public void iterate(Consumer<String> consumer, @Nullable String providerFilter) {
|
||||
long systemTimeDeltaMs = System.currentTimeMillis() - SystemClock.elapsedRealtime();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
iterate(
|
||||
(time, logEvent) -> {
|
||||
boolean match = providerFilter == null || (logEvent instanceof ProviderEvent
|
||||
&& providerFilter.equals(((ProviderEvent) logEvent).mProvider));
|
||||
if (match) {
|
||||
builder.setLength(0);
|
||||
builder.append(TimeUtils.logTimeOfDay(time + systemTimeDeltaMs));
|
||||
builder.append(": ");
|
||||
builder.append(logEvent);
|
||||
consumer.accept(builder.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private abstract static class ProviderEvent {
|
||||
|
||||
protected final String mProvider;
|
||||
|
||||
ProviderEvent(long timeDelta, String provider) {
|
||||
super(timeDelta);
|
||||
ProviderEvent(String provider) {
|
||||
mProvider = provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filter(String filter) {
|
||||
return mProvider.equals(filter);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ProviderEnabledEvent extends ProviderEvent {
|
||||
@@ -288,15 +241,15 @@ public class LocationEventLog extends LocalEventLog {
|
||||
private final int mUserId;
|
||||
private final boolean mEnabled;
|
||||
|
||||
ProviderEnabledEvent(long timeDelta, String provider, int userId,
|
||||
ProviderEnabledEvent(String provider, int userId,
|
||||
boolean enabled) {
|
||||
super(timeDelta, provider);
|
||||
super(provider);
|
||||
mUserId = userId;
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogString() {
|
||||
public String toString() {
|
||||
return mProvider + " provider [u" + mUserId + "] " + (mEnabled ? "enabled"
|
||||
: "disabled");
|
||||
}
|
||||
@@ -306,13 +259,13 @@ public class LocationEventLog extends LocalEventLog {
|
||||
|
||||
private final boolean mMocked;
|
||||
|
||||
ProviderMockedEvent(long timeDelta, String provider, boolean mocked) {
|
||||
super(timeDelta, provider);
|
||||
ProviderMockedEvent(String provider, boolean mocked) {
|
||||
super(provider);
|
||||
mMocked = mocked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogString() {
|
||||
public String toString() {
|
||||
if (mMocked) {
|
||||
return mProvider + " provider added mock provider override";
|
||||
} else {
|
||||
@@ -327,16 +280,16 @@ public class LocationEventLog extends LocalEventLog {
|
||||
private final CallerIdentity mIdentity;
|
||||
@Nullable private final LocationRequest mLocationRequest;
|
||||
|
||||
ProviderClientRegisterEvent(long timeDelta, String provider, boolean registered,
|
||||
ProviderClientRegisterEvent(String provider, boolean registered,
|
||||
CallerIdentity identity, @Nullable LocationRequest locationRequest) {
|
||||
super(timeDelta, provider);
|
||||
super(provider);
|
||||
mRegistered = registered;
|
||||
mIdentity = identity;
|
||||
mLocationRequest = locationRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogString() {
|
||||
public String toString() {
|
||||
if (mRegistered) {
|
||||
return mProvider + " provider +registration " + mIdentity + " -> "
|
||||
+ mLocationRequest;
|
||||
@@ -351,15 +304,15 @@ public class LocationEventLog extends LocalEventLog {
|
||||
private final boolean mForeground;
|
||||
private final CallerIdentity mIdentity;
|
||||
|
||||
ProviderClientForegroundEvent(long timeDelta, String provider, boolean foreground,
|
||||
ProviderClientForegroundEvent(String provider, boolean foreground,
|
||||
CallerIdentity identity) {
|
||||
super(timeDelta, provider);
|
||||
super(provider);
|
||||
mForeground = foreground;
|
||||
mIdentity = identity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogString() {
|
||||
public String toString() {
|
||||
return mProvider + " provider client " + mIdentity + " -> "
|
||||
+ (mForeground ? "foreground" : "background");
|
||||
}
|
||||
@@ -370,15 +323,14 @@ public class LocationEventLog extends LocalEventLog {
|
||||
private final boolean mPermitted;
|
||||
private final CallerIdentity mIdentity;
|
||||
|
||||
ProviderClientPermittedEvent(long timeDelta, String provider, boolean permitted,
|
||||
CallerIdentity identity) {
|
||||
super(timeDelta, provider);
|
||||
ProviderClientPermittedEvent(String provider, boolean permitted, CallerIdentity identity) {
|
||||
super(provider);
|
||||
mPermitted = permitted;
|
||||
mIdentity = identity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogString() {
|
||||
public String toString() {
|
||||
return mProvider + " provider client " + mIdentity + " -> "
|
||||
+ (mPermitted ? "permitted" : "unpermitted");
|
||||
}
|
||||
@@ -388,13 +340,13 @@ public class LocationEventLog extends LocalEventLog {
|
||||
|
||||
private final ProviderRequest mRequest;
|
||||
|
||||
ProviderUpdateEvent(long timeDelta, String provider, ProviderRequest request) {
|
||||
super(timeDelta, provider);
|
||||
ProviderUpdateEvent(String provider, ProviderRequest request) {
|
||||
super(provider);
|
||||
mRequest = request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogString() {
|
||||
public String toString() {
|
||||
return mProvider + " provider request = " + mRequest;
|
||||
}
|
||||
}
|
||||
@@ -403,13 +355,13 @@ public class LocationEventLog extends LocalEventLog {
|
||||
|
||||
private final int mNumLocations;
|
||||
|
||||
ProviderReceiveLocationEvent(long timeDelta, String provider, int numLocations) {
|
||||
super(timeDelta, provider);
|
||||
ProviderReceiveLocationEvent(String provider, int numLocations) {
|
||||
super(provider);
|
||||
mNumLocations = numLocations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogString() {
|
||||
public String toString() {
|
||||
return mProvider + " provider received location[" + mNumLocations + "]";
|
||||
}
|
||||
}
|
||||
@@ -419,15 +371,15 @@ public class LocationEventLog extends LocalEventLog {
|
||||
private final int mNumLocations;
|
||||
@Nullable private final CallerIdentity mIdentity;
|
||||
|
||||
ProviderDeliverLocationEvent(long timeDelta, String provider, int numLocations,
|
||||
ProviderDeliverLocationEvent(String provider, int numLocations,
|
||||
@Nullable CallerIdentity identity) {
|
||||
super(timeDelta, provider);
|
||||
super(provider);
|
||||
mNumLocations = numLocations;
|
||||
mIdentity = identity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogString() {
|
||||
public String toString() {
|
||||
return mProvider + " provider delivered location[" + mNumLocations + "] to "
|
||||
+ mIdentity;
|
||||
}
|
||||
@@ -438,33 +390,31 @@ public class LocationEventLog extends LocalEventLog {
|
||||
private final boolean mStationaryThrottled;
|
||||
private final ProviderRequest mRequest;
|
||||
|
||||
ProviderStationaryThrottledEvent(long timeDelta, String provider,
|
||||
boolean stationaryThrottled, ProviderRequest request) {
|
||||
super(timeDelta, provider);
|
||||
ProviderStationaryThrottledEvent(String provider, boolean stationaryThrottled,
|
||||
ProviderRequest request) {
|
||||
super(provider);
|
||||
mStationaryThrottled = stationaryThrottled;
|
||||
mRequest = request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogString() {
|
||||
public String toString() {
|
||||
return mProvider + " provider stationary/idle " + (mStationaryThrottled ? "throttled"
|
||||
: "unthrottled") + ", request = " + mRequest;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class LocationPowerSaveModeEvent extends LogEvent {
|
||||
private static final class LocationPowerSaveModeEvent {
|
||||
|
||||
@LocationPowerSaveMode
|
||||
private final int mLocationPowerSaveMode;
|
||||
|
||||
LocationPowerSaveModeEvent(long timeDelta,
|
||||
@LocationPowerSaveMode int locationPowerSaveMode) {
|
||||
super(timeDelta);
|
||||
LocationPowerSaveModeEvent(@LocationPowerSaveMode int locationPowerSaveMode) {
|
||||
mLocationPowerSaveMode = locationPowerSaveMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogString() {
|
||||
public String toString() {
|
||||
String mode;
|
||||
switch (mLocationPowerSaveMode) {
|
||||
case LOCATION_MODE_NO_CHANGE:
|
||||
@@ -490,53 +440,50 @@ public class LocationEventLog extends LocalEventLog {
|
||||
}
|
||||
}
|
||||
|
||||
private static final class UserSwitchedEvent extends LogEvent {
|
||||
private static final class UserSwitchedEvent {
|
||||
|
||||
private final int mUserIdFrom;
|
||||
private final int mUserIdTo;
|
||||
|
||||
UserSwitchedEvent(long timeDelta, int userIdFrom, int userIdTo) {
|
||||
super(timeDelta);
|
||||
UserSwitchedEvent(int userIdFrom, int userIdTo) {
|
||||
mUserIdFrom = userIdFrom;
|
||||
mUserIdTo = userIdTo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogString() {
|
||||
public String toString() {
|
||||
return "current user switched from u" + mUserIdFrom + " to u" + mUserIdTo;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class LocationEnabledEvent extends LogEvent {
|
||||
private static final class LocationEnabledEvent {
|
||||
|
||||
private final int mUserId;
|
||||
private final boolean mEnabled;
|
||||
|
||||
LocationEnabledEvent(long timeDelta, int userId, boolean enabled) {
|
||||
super(timeDelta);
|
||||
LocationEnabledEvent(int userId, boolean enabled) {
|
||||
mUserId = userId;
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogString() {
|
||||
public String toString() {
|
||||
return "location [u" + mUserId + "] " + (mEnabled ? "enabled" : "disabled");
|
||||
}
|
||||
}
|
||||
|
||||
private static final class LocationAdasEnabledEvent extends LogEvent {
|
||||
private static final class LocationAdasEnabledEvent {
|
||||
|
||||
private final int mUserId;
|
||||
private final boolean mEnabled;
|
||||
|
||||
LocationAdasEnabledEvent(long timeDelta, int userId, boolean enabled) {
|
||||
super(timeDelta);
|
||||
LocationAdasEnabledEvent(int userId, boolean enabled) {
|
||||
mUserId = userId;
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLogString() {
|
||||
public String toString() {
|
||||
return "adas location [u" + mUserId + "] " + (mEnabled ? "enabled" : "disabled");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user