Loading services/core/java/com/android/server/location/eventlog/LocalEventLog.java +74 −16 Original line number Diff line number Diff line Loading @@ -21,26 +21,23 @@ import static java.lang.Integer.bitCount; import android.annotation.Nullable; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.ConcurrentModificationException; import java.util.NoSuchElementException; import java.util.Objects; /** * 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 class LocalEventLog<T> { /** * Consumer of log events for iterating over the log. * * @param <T> log event type */ /** Consumer of log events for iterating over the log. */ public interface LogConsumer<T> { /** Invoked with a time and a logEvent. */ void acceptLog(long time, T logEvent); Loading @@ -54,6 +51,7 @@ public class LocalEventLog<T> { private static final int IS_FILLER_OFFSET = countTrailingZeros(IS_FILLER_MASK); private static final int TIME_DELTA_OFFSET = countTrailingZeros(TIME_DELTA_MASK); @VisibleForTesting static final int MAX_TIME_DELTA = (1 << bitCount(TIME_DELTA_MASK)) - 1; private static int countTrailingZeros(int i) { Loading @@ -79,7 +77,7 @@ public class LocalEventLog<T> { return (entry & IS_FILLER_MASK) != 0; } // circular buffer of log entries and events. each entry corrosponds to the log event at the // circular buffer of log entries and events. each entry corresponds 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. Loading @@ -103,6 +101,9 @@ public class LocalEventLog<T> { @GuardedBy("this") long mLastLogTime; @GuardedBy("this") long mModificationCount; @SuppressWarnings("unchecked") public LocalEventLog(int size, Class<T> clazz) { Preconditions.checkArgument(size > 0); Loading Loading @@ -143,6 +144,7 @@ public class LocalEventLog<T> { if (isEmpty()) { mStartTime = time; mLastLogTime = mStartTime; mModificationCount++; } addLogEventInternal(false, (int) delta, logEvent); Loading @@ -156,6 +158,7 @@ public class LocalEventLog<T> { if (mLogSize == mEntries.length) { // if log is full, size will remain the same, but update the start time mStartTime += getTimeDelta(mEntries[startIndex()]); mModificationCount++; } else { // otherwise add an item mLogSize++; Loading @@ -170,11 +173,12 @@ public class LocalEventLog<T> { /** Clears the log of all entries. */ public synchronized void clear() { // clear entries to allow gc // clear entries to aid gc Arrays.fill(mLogEvents, null); mLogEndIndex = 0; mLogSize = 0; mModificationCount++; mStartTime = -1; mLastLogTime = -1; Loading @@ -186,7 +190,10 @@ public class LocalEventLog<T> { return mLogSize == 0; } /** Iterates over the event log, passing each log string to the given consumer. */ /** * Iterates over the event log, passing each log event to the given consumer. Locks the log * while executing so that {@link ConcurrentModificationException}s cannot occur. */ public synchronized void iterate(LogConsumer<? super T> consumer) { LogIterator it = new LogIterator(); while (it.hasNext()) { Loading @@ -195,15 +202,53 @@ public class LocalEventLog<T> { } } /** * Iterates over all the given event logs in time order, passing each log event to the given * consumer. It is the caller's responsibility to ensure that {@link * ConcurrentModificationException}s cannot occur, whether through locking or other means. */ @SafeVarargs public static <T> void iterate(LogConsumer<? super T> consumer, LocalEventLog<T>... logs) { ArrayList<LocalEventLog<T>.LogIterator> its = new ArrayList<>(logs.length); for (LocalEventLog<T> log : logs) { LocalEventLog<T>.LogIterator it = log.new LogIterator(); if (it.hasNext()) { its.add(it); it.next(); } } while (true) { LocalEventLog<T>.LogIterator next = null; for (LocalEventLog<T>.LogIterator it : its) { if (it != null && (next == null || it.getTime() < next.getTime())) { next = it; } } if (next == null) { return; } consumer.acceptLog(next.getTime(), next.getLog()); if (next.hasNext()) { next.next(); } else { its.remove(next); } } } // returns the index of the first element @GuardedBy("this") private int startIndex() { int startIndex() { return wrapIndex(mLogEndIndex - mLogSize); } // returns the index after this one @GuardedBy("this") private int incrementIndex(int index) { int incrementIndex(int index) { if (index == -1) { return startIndex(); } else if (index >= 0) { Loading @@ -215,12 +260,15 @@ public class LocalEventLog<T> { // rolls over the given index if necessary @GuardedBy("this") private int wrapIndex(int index) { int wrapIndex(int index) { // java modulo will keep negative sign, we need to rollover return (index % mEntries.length + mEntries.length) % mEntries.length; } private class LogIterator { /** Iterator over log times and events. */ protected final class LogIterator { private final long mModificationCount; private long mLogTime; private int mIndex; Loading @@ -229,8 +277,10 @@ public class LocalEventLog<T> { private long mCurrentTime; private T mCurrentLogEvent; LogIterator() { public LogIterator() { synchronized (LocalEventLog.this) { mModificationCount = LocalEventLog.this.mModificationCount; mLogTime = mStartTime; mIndex = -1; mCount = -1; Loading @@ -241,6 +291,7 @@ public class LocalEventLog<T> { public boolean hasNext() { synchronized (LocalEventLog.this) { checkModifications(); return mCount < mLogSize; } } Loading Loading @@ -277,5 +328,12 @@ public class LocalEventLog<T> { } } while (mCount < mLogSize && isFiller(mEntries[mIndex])); } @GuardedBy("LocalEventLog.this") private void checkModifications() { if (mModificationCount != LocalEventLog.this.mModificationCount) { throw new ConcurrentModificationException(); } } } } services/core/java/com/android/server/location/eventlog/LocationEventLog.java +58 −19 Original line number Diff line number Diff line Loading @@ -52,16 +52,28 @@ public class LocationEventLog extends LocalEventLog<Object> { if (D) { return 600; } else { return 300; } } private static int getLocationsLogSize() { if (D) { return 200; } else { return 100; } } @GuardedBy("mAggregateStats") private final ArrayMap<String, ArrayMap<CallerIdentity, AggregateStats>> mAggregateStats; public LocationEventLog() { @GuardedBy("this") private final LocationsEventLog mLocationsLog; private LocationEventLog() { super(getLogSize(), Object.class); mAggregateStats = new ArrayMap<>(4); mLocationsLog = new LocationsEventLog(getLocationsLogSize()); } /** Copies out all aggregated stats. */ Loading Loading @@ -95,39 +107,39 @@ public class LocationEventLog extends LocalEventLog<Object> { /** Logs a user switched event. */ public void logUserSwitched(int userIdFrom, int userIdTo) { addLogEvent(new UserSwitchedEvent(userIdFrom, userIdTo)); addLog(new UserSwitchedEvent(userIdFrom, userIdTo)); } /** Logs a location enabled/disabled event. */ public void logLocationEnabled(int userId, boolean enabled) { addLogEvent(new LocationEnabledEvent(userId, enabled)); addLog(new LocationEnabledEvent(userId, enabled)); } /** Logs a location enabled/disabled event. */ public void logAdasLocationEnabled(int userId, boolean enabled) { addLogEvent(new LocationAdasEnabledEvent(userId, enabled)); addLog(new LocationAdasEnabledEvent(userId, enabled)); } /** Logs a location provider enabled/disabled event. */ public void logProviderEnabled(String provider, int userId, boolean enabled) { addLogEvent(new ProviderEnabledEvent(provider, userId, enabled)); addLog(new ProviderEnabledEvent(provider, userId, enabled)); } /** Logs a location provider being replaced/unreplaced by a mock provider. */ public void logProviderMocked(String provider, boolean mocked) { addLogEvent(new ProviderMockedEvent(provider, mocked)); addLog(new ProviderMockedEvent(provider, mocked)); } /** Logs a new client registration for a location provider. */ public void logProviderClientRegistered(String provider, CallerIdentity identity, LocationRequest request) { addLogEvent(new ProviderClientRegisterEvent(provider, true, identity, request)); addLog(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(new ProviderClientRegisterEvent(provider, false, identity, null)); addLog(new ProviderClientRegisterEvent(provider, false, identity, null)); getAggregateStats(provider, identity).markRequestRemoved(); } Loading @@ -144,7 +156,7 @@ public class LocationEventLog extends LocalEventLog<Object> { /** Logs a client for a location provider entering the foreground state. */ public void logProviderClientForeground(String provider, CallerIdentity identity) { if (D) { addLogEvent(new ProviderClientForegroundEvent(provider, true, identity)); addLog(new ProviderClientForegroundEvent(provider, true, identity)); } getAggregateStats(provider, identity).markRequestForeground(); } Loading @@ -152,7 +164,7 @@ public class LocationEventLog extends LocalEventLog<Object> { /** Logs a client for a location provider leaving the foreground state. */ public void logProviderClientBackground(String provider, CallerIdentity identity) { if (D) { addLogEvent(new ProviderClientForegroundEvent(provider, false, identity)); addLog(new ProviderClientForegroundEvent(provider, false, identity)); } getAggregateStats(provider, identity).markRequestBackground(); } Loading @@ -160,32 +172,34 @@ public class LocationEventLog extends LocalEventLog<Object> { /** Logs a client for a location provider entering the permitted state. */ public void logProviderClientPermitted(String provider, CallerIdentity identity) { if (D) { addLogEvent(new ProviderClientPermittedEvent(provider, true, identity)); addLog(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(new ProviderClientPermittedEvent(provider, false, identity)); addLog(new ProviderClientPermittedEvent(provider, false, identity)); } } /** Logs a change to the provider request for a location provider. */ public void logProviderUpdateRequest(String provider, ProviderRequest request) { addLogEvent(new ProviderUpdateEvent(provider, request)); addLog(new ProviderUpdateEvent(provider, request)); } /** Logs a new incoming location for a location provider. */ public void logProviderReceivedLocations(String provider, int numLocations) { addLogEvent(new ProviderReceiveLocationEvent(provider, numLocations)); synchronized (this) { mLocationsLog.logProviderReceivedLocations(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(new ProviderDeliverLocationEvent(provider, numLocations, identity)); synchronized (this) { mLocationsLog.logProviderDeliveredLocations(provider, numLocations, identity); } getAggregateStats(provider, identity).markLocationDelivered(); } Loading @@ -193,19 +207,24 @@ public class LocationEventLog extends LocalEventLog<Object> { /** Logs that a provider has entered or exited stationary throttling. */ public void logProviderStationaryThrottled(String provider, boolean throttled, ProviderRequest request) { addLogEvent(new ProviderStationaryThrottledEvent(provider, throttled, request)); addLog(new ProviderStationaryThrottledEvent(provider, throttled, request)); } /** Logs that the location power save mode has changed. */ public void logLocationPowerSaveMode( @LocationPowerSaveMode int locationPowerSaveMode) { addLogEvent(new LocationPowerSaveModeEvent(locationPowerSaveMode)); addLog(new LocationPowerSaveModeEvent(locationPowerSaveMode)); } private void addLogEvent(Object logEvent) { private void addLog(Object logEvent) { addLog(SystemClock.elapsedRealtime(), logEvent); } @Override public synchronized void iterate(LogConsumer<? super Object> consumer) { iterate(consumer, this, mLocationsLog); } public void iterate(Consumer<String> consumer) { iterate(consumer, null); } Loading Loading @@ -488,6 +507,26 @@ public class LocationEventLog extends LocalEventLog<Object> { } } private static final class LocationsEventLog extends LocalEventLog<Object> { LocationsEventLog(int size) { super(size, Object.class); } public void logProviderReceivedLocations(String provider, int numLocations) { addLog(new ProviderReceiveLocationEvent(provider, numLocations)); } public void logProviderDeliveredLocations(String provider, int numLocations, CallerIdentity identity) { addLog(new ProviderDeliverLocationEvent(provider, numLocations, identity)); } private void addLog(Object logEvent) { this.addLog(SystemClock.elapsedRealtime(), logEvent); } } /** * Aggregate statistics for a single package under a single provider. */ Loading Loading
services/core/java/com/android/server/location/eventlog/LocalEventLog.java +74 −16 Original line number Diff line number Diff line Loading @@ -21,26 +21,23 @@ import static java.lang.Integer.bitCount; import android.annotation.Nullable; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.ConcurrentModificationException; import java.util.NoSuchElementException; import java.util.Objects; /** * 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 class LocalEventLog<T> { /** * Consumer of log events for iterating over the log. * * @param <T> log event type */ /** Consumer of log events for iterating over the log. */ public interface LogConsumer<T> { /** Invoked with a time and a logEvent. */ void acceptLog(long time, T logEvent); Loading @@ -54,6 +51,7 @@ public class LocalEventLog<T> { private static final int IS_FILLER_OFFSET = countTrailingZeros(IS_FILLER_MASK); private static final int TIME_DELTA_OFFSET = countTrailingZeros(TIME_DELTA_MASK); @VisibleForTesting static final int MAX_TIME_DELTA = (1 << bitCount(TIME_DELTA_MASK)) - 1; private static int countTrailingZeros(int i) { Loading @@ -79,7 +77,7 @@ public class LocalEventLog<T> { return (entry & IS_FILLER_MASK) != 0; } // circular buffer of log entries and events. each entry corrosponds to the log event at the // circular buffer of log entries and events. each entry corresponds 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. Loading @@ -103,6 +101,9 @@ public class LocalEventLog<T> { @GuardedBy("this") long mLastLogTime; @GuardedBy("this") long mModificationCount; @SuppressWarnings("unchecked") public LocalEventLog(int size, Class<T> clazz) { Preconditions.checkArgument(size > 0); Loading Loading @@ -143,6 +144,7 @@ public class LocalEventLog<T> { if (isEmpty()) { mStartTime = time; mLastLogTime = mStartTime; mModificationCount++; } addLogEventInternal(false, (int) delta, logEvent); Loading @@ -156,6 +158,7 @@ public class LocalEventLog<T> { if (mLogSize == mEntries.length) { // if log is full, size will remain the same, but update the start time mStartTime += getTimeDelta(mEntries[startIndex()]); mModificationCount++; } else { // otherwise add an item mLogSize++; Loading @@ -170,11 +173,12 @@ public class LocalEventLog<T> { /** Clears the log of all entries. */ public synchronized void clear() { // clear entries to allow gc // clear entries to aid gc Arrays.fill(mLogEvents, null); mLogEndIndex = 0; mLogSize = 0; mModificationCount++; mStartTime = -1; mLastLogTime = -1; Loading @@ -186,7 +190,10 @@ public class LocalEventLog<T> { return mLogSize == 0; } /** Iterates over the event log, passing each log string to the given consumer. */ /** * Iterates over the event log, passing each log event to the given consumer. Locks the log * while executing so that {@link ConcurrentModificationException}s cannot occur. */ public synchronized void iterate(LogConsumer<? super T> consumer) { LogIterator it = new LogIterator(); while (it.hasNext()) { Loading @@ -195,15 +202,53 @@ public class LocalEventLog<T> { } } /** * Iterates over all the given event logs in time order, passing each log event to the given * consumer. It is the caller's responsibility to ensure that {@link * ConcurrentModificationException}s cannot occur, whether through locking or other means. */ @SafeVarargs public static <T> void iterate(LogConsumer<? super T> consumer, LocalEventLog<T>... logs) { ArrayList<LocalEventLog<T>.LogIterator> its = new ArrayList<>(logs.length); for (LocalEventLog<T> log : logs) { LocalEventLog<T>.LogIterator it = log.new LogIterator(); if (it.hasNext()) { its.add(it); it.next(); } } while (true) { LocalEventLog<T>.LogIterator next = null; for (LocalEventLog<T>.LogIterator it : its) { if (it != null && (next == null || it.getTime() < next.getTime())) { next = it; } } if (next == null) { return; } consumer.acceptLog(next.getTime(), next.getLog()); if (next.hasNext()) { next.next(); } else { its.remove(next); } } } // returns the index of the first element @GuardedBy("this") private int startIndex() { int startIndex() { return wrapIndex(mLogEndIndex - mLogSize); } // returns the index after this one @GuardedBy("this") private int incrementIndex(int index) { int incrementIndex(int index) { if (index == -1) { return startIndex(); } else if (index >= 0) { Loading @@ -215,12 +260,15 @@ public class LocalEventLog<T> { // rolls over the given index if necessary @GuardedBy("this") private int wrapIndex(int index) { int wrapIndex(int index) { // java modulo will keep negative sign, we need to rollover return (index % mEntries.length + mEntries.length) % mEntries.length; } private class LogIterator { /** Iterator over log times and events. */ protected final class LogIterator { private final long mModificationCount; private long mLogTime; private int mIndex; Loading @@ -229,8 +277,10 @@ public class LocalEventLog<T> { private long mCurrentTime; private T mCurrentLogEvent; LogIterator() { public LogIterator() { synchronized (LocalEventLog.this) { mModificationCount = LocalEventLog.this.mModificationCount; mLogTime = mStartTime; mIndex = -1; mCount = -1; Loading @@ -241,6 +291,7 @@ public class LocalEventLog<T> { public boolean hasNext() { synchronized (LocalEventLog.this) { checkModifications(); return mCount < mLogSize; } } Loading Loading @@ -277,5 +328,12 @@ public class LocalEventLog<T> { } } while (mCount < mLogSize && isFiller(mEntries[mIndex])); } @GuardedBy("LocalEventLog.this") private void checkModifications() { if (mModificationCount != LocalEventLog.this.mModificationCount) { throw new ConcurrentModificationException(); } } } }
services/core/java/com/android/server/location/eventlog/LocationEventLog.java +58 −19 Original line number Diff line number Diff line Loading @@ -52,16 +52,28 @@ public class LocationEventLog extends LocalEventLog<Object> { if (D) { return 600; } else { return 300; } } private static int getLocationsLogSize() { if (D) { return 200; } else { return 100; } } @GuardedBy("mAggregateStats") private final ArrayMap<String, ArrayMap<CallerIdentity, AggregateStats>> mAggregateStats; public LocationEventLog() { @GuardedBy("this") private final LocationsEventLog mLocationsLog; private LocationEventLog() { super(getLogSize(), Object.class); mAggregateStats = new ArrayMap<>(4); mLocationsLog = new LocationsEventLog(getLocationsLogSize()); } /** Copies out all aggregated stats. */ Loading Loading @@ -95,39 +107,39 @@ public class LocationEventLog extends LocalEventLog<Object> { /** Logs a user switched event. */ public void logUserSwitched(int userIdFrom, int userIdTo) { addLogEvent(new UserSwitchedEvent(userIdFrom, userIdTo)); addLog(new UserSwitchedEvent(userIdFrom, userIdTo)); } /** Logs a location enabled/disabled event. */ public void logLocationEnabled(int userId, boolean enabled) { addLogEvent(new LocationEnabledEvent(userId, enabled)); addLog(new LocationEnabledEvent(userId, enabled)); } /** Logs a location enabled/disabled event. */ public void logAdasLocationEnabled(int userId, boolean enabled) { addLogEvent(new LocationAdasEnabledEvent(userId, enabled)); addLog(new LocationAdasEnabledEvent(userId, enabled)); } /** Logs a location provider enabled/disabled event. */ public void logProviderEnabled(String provider, int userId, boolean enabled) { addLogEvent(new ProviderEnabledEvent(provider, userId, enabled)); addLog(new ProviderEnabledEvent(provider, userId, enabled)); } /** Logs a location provider being replaced/unreplaced by a mock provider. */ public void logProviderMocked(String provider, boolean mocked) { addLogEvent(new ProviderMockedEvent(provider, mocked)); addLog(new ProviderMockedEvent(provider, mocked)); } /** Logs a new client registration for a location provider. */ public void logProviderClientRegistered(String provider, CallerIdentity identity, LocationRequest request) { addLogEvent(new ProviderClientRegisterEvent(provider, true, identity, request)); addLog(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(new ProviderClientRegisterEvent(provider, false, identity, null)); addLog(new ProviderClientRegisterEvent(provider, false, identity, null)); getAggregateStats(provider, identity).markRequestRemoved(); } Loading @@ -144,7 +156,7 @@ public class LocationEventLog extends LocalEventLog<Object> { /** Logs a client for a location provider entering the foreground state. */ public void logProviderClientForeground(String provider, CallerIdentity identity) { if (D) { addLogEvent(new ProviderClientForegroundEvent(provider, true, identity)); addLog(new ProviderClientForegroundEvent(provider, true, identity)); } getAggregateStats(provider, identity).markRequestForeground(); } Loading @@ -152,7 +164,7 @@ public class LocationEventLog extends LocalEventLog<Object> { /** Logs a client for a location provider leaving the foreground state. */ public void logProviderClientBackground(String provider, CallerIdentity identity) { if (D) { addLogEvent(new ProviderClientForegroundEvent(provider, false, identity)); addLog(new ProviderClientForegroundEvent(provider, false, identity)); } getAggregateStats(provider, identity).markRequestBackground(); } Loading @@ -160,32 +172,34 @@ public class LocationEventLog extends LocalEventLog<Object> { /** Logs a client for a location provider entering the permitted state. */ public void logProviderClientPermitted(String provider, CallerIdentity identity) { if (D) { addLogEvent(new ProviderClientPermittedEvent(provider, true, identity)); addLog(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(new ProviderClientPermittedEvent(provider, false, identity)); addLog(new ProviderClientPermittedEvent(provider, false, identity)); } } /** Logs a change to the provider request for a location provider. */ public void logProviderUpdateRequest(String provider, ProviderRequest request) { addLogEvent(new ProviderUpdateEvent(provider, request)); addLog(new ProviderUpdateEvent(provider, request)); } /** Logs a new incoming location for a location provider. */ public void logProviderReceivedLocations(String provider, int numLocations) { addLogEvent(new ProviderReceiveLocationEvent(provider, numLocations)); synchronized (this) { mLocationsLog.logProviderReceivedLocations(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(new ProviderDeliverLocationEvent(provider, numLocations, identity)); synchronized (this) { mLocationsLog.logProviderDeliveredLocations(provider, numLocations, identity); } getAggregateStats(provider, identity).markLocationDelivered(); } Loading @@ -193,19 +207,24 @@ public class LocationEventLog extends LocalEventLog<Object> { /** Logs that a provider has entered or exited stationary throttling. */ public void logProviderStationaryThrottled(String provider, boolean throttled, ProviderRequest request) { addLogEvent(new ProviderStationaryThrottledEvent(provider, throttled, request)); addLog(new ProviderStationaryThrottledEvent(provider, throttled, request)); } /** Logs that the location power save mode has changed. */ public void logLocationPowerSaveMode( @LocationPowerSaveMode int locationPowerSaveMode) { addLogEvent(new LocationPowerSaveModeEvent(locationPowerSaveMode)); addLog(new LocationPowerSaveModeEvent(locationPowerSaveMode)); } private void addLogEvent(Object logEvent) { private void addLog(Object logEvent) { addLog(SystemClock.elapsedRealtime(), logEvent); } @Override public synchronized void iterate(LogConsumer<? super Object> consumer) { iterate(consumer, this, mLocationsLog); } public void iterate(Consumer<String> consumer) { iterate(consumer, null); } Loading Loading @@ -488,6 +507,26 @@ public class LocationEventLog extends LocalEventLog<Object> { } } private static final class LocationsEventLog extends LocalEventLog<Object> { LocationsEventLog(int size) { super(size, Object.class); } public void logProviderReceivedLocations(String provider, int numLocations) { addLog(new ProviderReceiveLocationEvent(provider, numLocations)); } public void logProviderDeliveredLocations(String provider, int numLocations, CallerIdentity identity) { addLog(new ProviderDeliverLocationEvent(provider, numLocations, identity)); } private void addLog(Object logEvent) { this.addLog(SystemClock.elapsedRealtime(), logEvent); } } /** * Aggregate statistics for a single package under a single provider. */ Loading