diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java index 7b5a635d6c87e..cd26fb5c2d524 100644 --- a/services/core/java/com/android/server/location/LocationManagerService.java +++ b/services/core/java/com/android/server/location/LocationManagerService.java @@ -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; } diff --git a/services/core/java/com/android/server/location/eventlog/LocalEventLog.java b/services/core/java/com/android/server/location/eventlog/LocalEventLog.java index 12dd3e6a4a4c3..47146c1a6d70b 100644 --- a/services/core/java/com/android/server/location/eventlog/LocalEventLog.java +++ b/services/core/java/com/android/server/location/eventlog/LocalEventLog.java @@ -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 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 { /** - * An abstraction of a log event to be implemented by subclasses. + * Consumer of log events for iterating over the log. + * + * @param 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 { + /** 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 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 consumer) { + public synchronized void iterate(LogConsumer 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 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 { + 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])); } } } - diff --git a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java index 2178672cbea91..94953e0b72f1f 100644 --- a/services/core/java/com/android/server/location/eventlog/LocationEventLog.java +++ b/services/core/java/com/android/server/location/eventlog/LocationEventLog.java @@ -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 { 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> 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 consumer) { + iterate(consumer, null); + } + + public void iterate(Consumer 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"); } }