summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/metrics
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialer/metrics')
-rw-r--r--java/com/android/dialer/metrics/FutureTimer.java28
-rw-r--r--java/com/android/dialer/metrics/Metrics.java26
-rw-r--r--java/com/android/dialer/metrics/MetricsComponent.java2
-rw-r--r--java/com/android/dialer/metrics/StubMetrics.java77
4 files changed, 124 insertions, 9 deletions
diff --git a/java/com/android/dialer/metrics/FutureTimer.java b/java/com/android/dialer/metrics/FutureTimer.java
index f7ba3feef..a45fb3835 100644
--- a/java/com/android/dialer/metrics/FutureTimer.java
+++ b/java/com/android/dialer/metrics/FutureTimer.java
@@ -21,6 +21,7 @@ import android.support.annotation.IntDef;
import android.support.annotation.VisibleForTesting;
import com.android.dialer.common.LogUtil;
import com.android.dialer.common.concurrent.Annotations.LightweightExecutor;
+import com.google.common.base.Function;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
@@ -72,7 +73,7 @@ public final class FutureTimer {
* of tracking heavyweight operations (which is what this method is intended for).
*/
public <T> void applyTiming(ListenableFuture<T> future, String eventName) {
- applyTiming(future, eventName, LogCatMode.DONT_LOG_VALUES);
+ applyTiming(future, unused -> eventName, LogCatMode.DONT_LOG_VALUES);
}
/**
@@ -81,14 +82,35 @@ public final class FutureTimer {
*/
public <T> void applyTiming(
ListenableFuture<T> future, String eventName, @LogCatMode int logCatMode) {
+ applyTiming(future, unused -> eventName, logCatMode);
+ }
+
+ /**
+ * Overload of {@link #applyTiming(ListenableFuture, String)} that accepts a function which
+ * specifies how to compute an event name from the result of the future.
+ *
+ * <p>This is useful when the event name depends on the result of the future.
+ */
+ public <T> void applyTiming(
+ ListenableFuture<T> future, Function<T, String> eventNameFromResultFunction) {
+ applyTiming(future, eventNameFromResultFunction, LogCatMode.DONT_LOG_VALUES);
+ }
+
+ private <T> void applyTiming(
+ ListenableFuture<T> future,
+ Function<T, String> eventNameFromResultFunction,
+ @LogCatMode int logCatMode) {
long startTime = SystemClock.elapsedRealtime();
- metrics.startTimer(eventName);
+ Integer timerId = metrics.startUnnamedTimer();
Futures.addCallback(
future,
new FutureCallback<T>() {
@Override
public void onSuccess(T result) {
- metrics.stopTimer(eventName);
+ String eventName = eventNameFromResultFunction.apply(result);
+ if (timerId != null) {
+ metrics.stopUnnamedTimer(timerId, eventName);
+ }
long operationTime = SystemClock.elapsedRealtime() - startTime;
// If the operation took a long time, do some WARNING logging.
diff --git a/java/com/android/dialer/metrics/Metrics.java b/java/com/android/dialer/metrics/Metrics.java
index b460f3ecf..e9e22c353 100644
--- a/java/com/android/dialer/metrics/Metrics.java
+++ b/java/com/android/dialer/metrics/Metrics.java
@@ -17,6 +17,7 @@
package com.android.dialer.metrics;
import android.app.Application;
+import android.support.annotation.Nullable;
/** Logs metrics. */
public interface Metrics {
@@ -36,6 +37,14 @@ public interface Metrics {
String NEW_CALL_LOG_JANK_EVENT_NAME = "NewCallLog.Jank";
// Events related to refreshing the annotated call log.
+ String NEW_CALL_LOG_COALESCE = "NewCallLog.Coalesce";
+ String REFRESH_NOT_DIRTY = "RefreshAnnotatedCallLogReceiver.NotDirty";
+ String REFRESH_CHANGES_NEEDED = "RefreshAnnotatedCallLogReceiver.ChangesNeeded";
+ String REFRESH_NO_CHANGES_NEEDED = "RefreshAnnotatedCallLogReceiver.NoChangesNeeded";
+ String FORCE_REFRESH_CHANGES_NEEDED = "RefreshAnnotatedCallLogReceiver.ForceRefreshChangesNeeded";
+ String FORCE_REFRESH_NO_CHANGES_NEEDED =
+ "RefreshAnnotatedCallLogReceiver.ForceRefreshNoChangesNeeded";
+
String INITIAL_FILL_EVENT_NAME = "RefreshAnnotatedCallLog.Initial.Fill";
String INITIAL_ON_SUCCESSFUL_FILL_EVENT_NAME = "RefreshAnnotatedCallLog.Initial.OnSuccessfulFill";
String INITIAL_APPLY_MUTATIONS_EVENT_NAME = "RefreshAnnotatedCallLog.Initial.ApplyMutations";
@@ -61,6 +70,23 @@ public interface Metrics {
/** Start a timer. */
void startTimer(String timerEventName);
+ /**
+ * Starts a timer for which the name is not yet known.
+ *
+ * @return opaque identifier for the event which should be provided back to {@link
+ * #stopUnnamedTimer(int, String)} to stop the timer. Null if the timer cannot be started, for
+ * example because the user is locked.
+ */
+ @Nullable
+ Integer startUnnamedTimer();
+
+ /**
+ * Stop a timer which was started with {@link #startUnnamedTimer()}.
+ *
+ * @param timerId the value returned in the corresponding call to {@link #startUnnamedTimer()}
+ */
+ void stopUnnamedTimer(int timerId, String timerEventName);
+
/** Stop a timer. */
void stopTimer(String timerEventName);
diff --git a/java/com/android/dialer/metrics/MetricsComponent.java b/java/com/android/dialer/metrics/MetricsComponent.java
index f37129791..a3570db10 100644
--- a/java/com/android/dialer/metrics/MetricsComponent.java
+++ b/java/com/android/dialer/metrics/MetricsComponent.java
@@ -28,6 +28,8 @@ public abstract class MetricsComponent {
public abstract Metrics.Initializer metricsInitializer();
+ public abstract FutureTimer futureTimer();
+
public static MetricsComponent get(Context context) {
return ((MetricsComponent.HasComponent)
((HasRootComponent) context.getApplicationContext()).component())
diff --git a/java/com/android/dialer/metrics/StubMetrics.java b/java/com/android/dialer/metrics/StubMetrics.java
index 99c3d7691..ecd2382b9 100644
--- a/java/com/android/dialer/metrics/StubMetrics.java
+++ b/java/com/android/dialer/metrics/StubMetrics.java
@@ -16,26 +16,91 @@
package com.android.dialer.metrics;
+import android.os.SystemClock;
+import com.android.dialer.common.Assert;
+import com.android.dialer.common.LogUtil;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.annotation.concurrent.ThreadSafe;
import javax.inject.Inject;
+import javax.inject.Singleton;
-/** Stub {@link Metrics}. */
+/** Stub {@link Metrics} which simply logs debug messages to logcat. */
+@ThreadSafe
+@Singleton
public final class StubMetrics implements Metrics {
+ private final ConcurrentMap<String, StubTimerEvent> namedEvents = new ConcurrentHashMap<>();
+ private final ConcurrentMap<Integer, StubTimerEvent> unnamedEvents = new ConcurrentHashMap<>();
+
@Inject
StubMetrics() {}
@Override
- public void startTimer(String timerEventName) {}
+ public void startTimer(String timerEventName) {
+ namedEvents.put(timerEventName, new StubTimerEvent());
+ }
@Override
- public void stopTimer(String timerEventName) {}
+ public Integer startUnnamedTimer() {
+ StubTimerEvent stubTimerEvent = new StubTimerEvent();
+ int id = stubTimerEvent.hashCode();
+ LogUtil.d("StubMetrics.startUnnamedTimer", "started timer for id: %d", id);
+ unnamedEvents.put(id, stubTimerEvent);
+ return id;
+ }
@Override
- public void startJankRecorder(String eventName) {}
+ public void stopTimer(String timerEventName) {
+ StubTimerEvent stubTimerEvent = namedEvents.remove(timerEventName);
+ if (stubTimerEvent == null) {
+ return;
+ }
+
+ LogUtil.d(
+ "StubMetrics.stopTimer",
+ "%s took %dms",
+ timerEventName,
+ SystemClock.elapsedRealtime() - stubTimerEvent.startTime);
+ }
+
+ @Override
+ public void stopUnnamedTimer(int timerId, String timerEventName) {
+ long startTime =
+ Assert.isNotNull(
+ unnamedEvents.remove(timerId),
+ "no timer found for id: %d (%s)",
+ timerId,
+ timerEventName)
+ .startTime;
+
+ LogUtil.d(
+ "StubMetrics.stopUnnamedTimer",
+ "%s took %dms",
+ timerEventName,
+ SystemClock.elapsedRealtime() - startTime);
+ }
@Override
- public void stopJankRecorder(String eventName) {}
+ public void startJankRecorder(String eventName) {
+ LogUtil.d("StubMetrics.startJankRecorder", "started jank recorder for %s", eventName);
+ }
@Override
- public void recordMemory(String memoryEventName) {}
+ public void stopJankRecorder(String eventName) {
+ LogUtil.d("StubMetrics.startJankRecorder", "stopped jank recorder for %s", eventName);
+ }
+
+ @Override
+ public void recordMemory(String memoryEventName) {
+ LogUtil.d("StubMetrics.startJankRecorder", "recorded memory for %s", memoryEventName);
+ }
+
+ private static class StubTimerEvent {
+ final long startTime;
+
+ StubTimerEvent() {
+ this.startTime = SystemClock.elapsedRealtime();
+ }
+ }
}