Add since_visible_millis to Settings action logs.
This change adds a new action logging method on MetricsFeatureProvider within Settings. Uses the VisibilityLoggerMixin to calculate the elapsed time since the fragment has been visible. Adds tagged data in MetricsFeatureProvider#action() to store this elapsed time in NOTIFICATION_SINCE_VISIBLE_MILLIS in MetricsEvents. Modifies the LogWriter interface to accept variadic taggedData args in its action() methods. Annotates the old subtype #action() methods as deprecated. EventLogWriter also no longer casts the subtype values to strings before sending them to MetricsLogger, so they are correctly stored as subtype instead of package. Bug: 65371699, 65631695 Test: make RunSettingsRoboTests Change-Id: Iec6a61dd6a49ab237e2bdc4469fed45e89d9c380
This commit is contained in:
@@ -65,4 +65,8 @@ public abstract class InstrumentedPreferenceFragment extends ObservablePreferenc
|
|||||||
protected final Context getPrefContext() {
|
protected final Context getPrefContext() {
|
||||||
return getPreferenceManager().getContext();
|
return getPreferenceManager().getContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final VisibilityLoggerMixin getVisibilityLogger() {
|
||||||
|
return mVisibilityLoggerMixin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,7 @@ package com.android.settings.core.instrumentation;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.metrics.LogMaker;
|
import android.metrics.LogMaker;
|
||||||
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
import com.android.internal.logging.MetricsLogger;
|
import com.android.internal.logging.MetricsLogger;
|
||||||
@@ -28,6 +29,8 @@ import com.android.internal.logging.nano.MetricsProto;
|
|||||||
*/
|
*/
|
||||||
public class EventLogWriter implements LogWriter {
|
public class EventLogWriter implements LogWriter {
|
||||||
|
|
||||||
|
private final MetricsLogger mMetricsLogger = new MetricsLogger();
|
||||||
|
|
||||||
public void visible(Context context, int source, int category) {
|
public void visible(Context context, int source, int category) {
|
||||||
final LogMaker logMaker = new LogMaker(category)
|
final LogMaker logMaker = new LogMaker(category)
|
||||||
.setType(MetricsProto.MetricsEvent.TYPE_OPEN)
|
.setType(MetricsProto.MetricsEvent.TYPE_OPEN)
|
||||||
@@ -39,6 +42,24 @@ public class EventLogWriter implements LogWriter {
|
|||||||
MetricsLogger.hidden(context, category);
|
MetricsLogger.hidden(context, category);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void action(int category, int value, Pair<Integer, Object>... taggedData) {
|
||||||
|
if (taggedData == null || taggedData.length == 0) {
|
||||||
|
mMetricsLogger.action(category, value);
|
||||||
|
} else {
|
||||||
|
final LogMaker logMaker = new LogMaker(category)
|
||||||
|
.setType(MetricsProto.MetricsEvent.TYPE_ACTION)
|
||||||
|
.setSubtype(value);
|
||||||
|
for (Pair<Integer, Object> pair : taggedData) {
|
||||||
|
logMaker.addTaggedData(pair.first, pair.second);
|
||||||
|
}
|
||||||
|
mMetricsLogger.write(logMaker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void action(int category, boolean value, Pair<Integer, Object>... taggedData) {
|
||||||
|
action(category, value ? 1 : 0, taggedData);
|
||||||
|
}
|
||||||
|
|
||||||
public void action(Context context, int category, Pair<Integer, Object>... taggedData) {
|
public void action(Context context, int category, Pair<Integer, Object>... taggedData) {
|
||||||
action(context, category, "", taggedData);
|
action(context, category, "", taggedData);
|
||||||
}
|
}
|
||||||
@@ -52,12 +73,16 @@ public class EventLogWriter implements LogWriter {
|
|||||||
MetricsLogger.action(logMaker);
|
MetricsLogger.action(logMaker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @deprecated use {@link #action(int, int, Pair[])} */
|
||||||
|
@Deprecated
|
||||||
public void action(Context context, int category, int value) {
|
public void action(Context context, int category, int value) {
|
||||||
MetricsLogger.action(context, category, Integer.toString(value));
|
MetricsLogger.action(context, category, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @deprecated use {@link #action(int, boolean, Pair[])} */
|
||||||
|
@Deprecated
|
||||||
public void action(Context context, int category, boolean value) {
|
public void action(Context context, int category, boolean value) {
|
||||||
MetricsLogger.action(context, category, Boolean.toString(value));
|
MetricsLogger.action(context, category, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void action(Context context, int category, String pkg,
|
public void action(Context context, int category, String pkg,
|
||||||
|
@@ -33,6 +33,16 @@ public interface LogWriter {
|
|||||||
*/
|
*/
|
||||||
void hidden(Context context, int category);
|
void hidden(Context context, int category);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a user action.
|
||||||
|
*/
|
||||||
|
void action(int category, int value, Pair<Integer, Object>... taggedData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a user action.
|
||||||
|
*/
|
||||||
|
void action(int category, boolean value, Pair<Integer, Object>... taggedData);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs an user action.
|
* Logs an user action.
|
||||||
*/
|
*/
|
||||||
@@ -45,12 +55,16 @@ public interface LogWriter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs an user action.
|
* Logs an user action.
|
||||||
|
* @deprecated use {@link #action(int, int, Pair[])}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
void action(Context context, int category, int value);
|
void action(Context context, int category, int value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs an user action.
|
* Logs an user action.
|
||||||
|
* @deprecated use {@link #action(int, boolean, Pair[])}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
void action(Context context, int category, boolean value);
|
void action(Context context, int category, boolean value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -21,7 +21,7 @@ import android.content.Intent;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -60,18 +60,44 @@ public class MetricsFeatureProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a user action. Includes the elapsed time since the containing
|
||||||
|
* fragment has been visible.
|
||||||
|
*/
|
||||||
|
public void action(VisibilityLoggerMixin visibilityLogger, int category, int value) {
|
||||||
|
for (LogWriter writer : mLoggerWriters) {
|
||||||
|
writer.action(category, value,
|
||||||
|
sinceVisibleTaggedData(visibilityLogger.elapsedTimeSinceVisible()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a user action. Includes the elapsed time since the containing
|
||||||
|
* fragment has been visible.
|
||||||
|
*/
|
||||||
|
public void action(VisibilityLoggerMixin visibilityLogger, int category, boolean value) {
|
||||||
|
for (LogWriter writer : mLoggerWriters) {
|
||||||
|
writer.action(category, value,
|
||||||
|
sinceVisibleTaggedData(visibilityLogger.elapsedTimeSinceVisible()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void action(Context context, int category, Pair<Integer, Object>... taggedData) {
|
public void action(Context context, int category, Pair<Integer, Object>... taggedData) {
|
||||||
for (LogWriter writer : mLoggerWriters) {
|
for (LogWriter writer : mLoggerWriters) {
|
||||||
writer.action(context, category, taggedData);
|
writer.action(context, category, taggedData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @deprecated use {@link #action(VisibilityLoggerMixin, int, int)} */
|
||||||
|
@Deprecated
|
||||||
public void action(Context context, int category, int value) {
|
public void action(Context context, int category, int value) {
|
||||||
for (LogWriter writer : mLoggerWriters) {
|
for (LogWriter writer : mLoggerWriters) {
|
||||||
writer.action(context, category, value);
|
writer.action(context, category, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @deprecated use {@link #action(VisibilityLoggerMixin, int, boolean)} */
|
||||||
|
@Deprecated
|
||||||
public void action(Context context, int category, boolean value) {
|
public void action(Context context, int category, boolean value) {
|
||||||
for (LogWriter writer : mLoggerWriters) {
|
for (LogWriter writer : mLoggerWriters) {
|
||||||
writer.action(context, category, value);
|
writer.action(context, category, value);
|
||||||
@@ -99,7 +125,7 @@ public class MetricsFeatureProvider {
|
|||||||
|
|
||||||
public int getMetricsCategory(Object object) {
|
public int getMetricsCategory(Object object) {
|
||||||
if (object == null || !(object instanceof Instrumentable)) {
|
if (object == null || !(object instanceof Instrumentable)) {
|
||||||
return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
|
return MetricsEvent.VIEW_UNKNOWN;
|
||||||
}
|
}
|
||||||
return ((Instrumentable) object).getMetricsCategory();
|
return ((Instrumentable) object).getMetricsCategory();
|
||||||
}
|
}
|
||||||
@@ -116,15 +142,19 @@ public class MetricsFeatureProvider {
|
|||||||
// Not loggable
|
// Not loggable
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
action(context, MetricsProto.MetricsEvent.ACTION_SETTINGS_TILE_CLICK, action,
|
action(context, MetricsEvent.ACTION_SETTINGS_TILE_CLICK, action,
|
||||||
Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, sourceMetricsCategory));
|
Pair.create(MetricsEvent.FIELD_CONTEXT, sourceMetricsCategory));
|
||||||
return;
|
return;
|
||||||
} else if (TextUtils.equals(cn.getPackageName(), context.getPackageName())) {
|
} else if (TextUtils.equals(cn.getPackageName(), context.getPackageName())) {
|
||||||
// Going to a Setting internal page, skip click logging in favor of page's own
|
// Going to a Setting internal page, skip click logging in favor of page's own
|
||||||
// visibility logging.
|
// visibility logging.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
action(context, MetricsProto.MetricsEvent.ACTION_SETTINGS_TILE_CLICK, cn.flattenToString(),
|
action(context, MetricsEvent.ACTION_SETTINGS_TILE_CLICK, cn.flattenToString(),
|
||||||
Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, sourceMetricsCategory));
|
Pair.create(MetricsEvent.FIELD_CONTEXT, sourceMetricsCategory));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Pair<Integer, Object> sinceVisibleTaggedData(long timestamp) {
|
||||||
|
return Pair.create(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS, timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -45,6 +45,14 @@ public class SettingSuggestionsLogWriter implements LogWriter {
|
|||||||
public void actionWithSource(Context context, int source, int category) {
|
public void actionWithSource(Context context, int source, int category) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void action(int category, int value, Pair<Integer, Object>... taggedData) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void action(int category, boolean value, Pair<Integer, Object>... taggedData) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void action(Context context, int category, int value) {
|
public void action(Context context, int category, int value) {
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@ import android.app.Activity;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import android.os.SystemClock;
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
import com.android.settings.SettingsActivity;
|
import com.android.settings.SettingsActivity;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
@@ -41,6 +42,7 @@ public class VisibilityLoggerMixin implements LifecycleObserver, OnResume, OnPau
|
|||||||
|
|
||||||
private MetricsFeatureProvider mMetricsFeature;
|
private MetricsFeatureProvider mMetricsFeature;
|
||||||
private int mSourceMetricsCategory = MetricsProto.MetricsEvent.VIEW_UNKNOWN;
|
private int mSourceMetricsCategory = MetricsProto.MetricsEvent.VIEW_UNKNOWN;
|
||||||
|
private long mVisibleTimestamp;
|
||||||
|
|
||||||
public VisibilityLoggerMixin(int metricsCategory) {
|
public VisibilityLoggerMixin(int metricsCategory) {
|
||||||
// MetricsFeature will be set during onAttach.
|
// MetricsFeature will be set during onAttach.
|
||||||
@@ -59,6 +61,7 @@ public class VisibilityLoggerMixin implements LifecycleObserver, OnResume, OnPau
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
|
mVisibleTimestamp = SystemClock.elapsedRealtime();
|
||||||
if (mMetricsFeature != null && mMetricsCategory != METRICS_CATEGORY_UNKNOWN) {
|
if (mMetricsFeature != null && mMetricsCategory != METRICS_CATEGORY_UNKNOWN) {
|
||||||
mMetricsFeature.visible(null /* context */, mSourceMetricsCategory, mMetricsCategory);
|
mMetricsFeature.visible(null /* context */, mSourceMetricsCategory, mMetricsCategory);
|
||||||
}
|
}
|
||||||
@@ -66,6 +69,7 @@ public class VisibilityLoggerMixin implements LifecycleObserver, OnResume, OnPau
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
|
mVisibleTimestamp = 0;
|
||||||
if (mMetricsFeature != null && mMetricsCategory != METRICS_CATEGORY_UNKNOWN) {
|
if (mMetricsFeature != null && mMetricsCategory != METRICS_CATEGORY_UNKNOWN) {
|
||||||
mMetricsFeature.hidden(null /* context */, mMetricsCategory);
|
mMetricsFeature.hidden(null /* context */, mMetricsCategory);
|
||||||
}
|
}
|
||||||
@@ -85,4 +89,12 @@ public class VisibilityLoggerMixin implements LifecycleObserver, OnResume, OnPau
|
|||||||
mSourceMetricsCategory = intent.getIntExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY,
|
mSourceMetricsCategory = intent.getIntExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY,
|
||||||
MetricsProto.MetricsEvent.VIEW_UNKNOWN);
|
MetricsProto.MetricsEvent.VIEW_UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns elapsed time since onResume() */
|
||||||
|
public long elapsedTimeSinceVisible() {
|
||||||
|
if (mVisibleTimestamp == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return SystemClock.elapsedRealtime() - mVisibleTimestamp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1070,7 +1070,7 @@ public class WifiSettings extends RestrictedSettingsFragment
|
|||||||
|
|
||||||
protected void connect(final WifiConfiguration config, boolean isSavedNetwork) {
|
protected void connect(final WifiConfiguration config, boolean isSavedNetwork) {
|
||||||
// Log subtype if configuration is a saved network.
|
// Log subtype if configuration is a saved network.
|
||||||
mMetricsFeatureProvider.action(getActivity(), MetricsEvent.ACTION_WIFI_CONNECT,
|
mMetricsFeatureProvider.action(getVisibilityLogger(), MetricsEvent.ACTION_WIFI_CONNECT,
|
||||||
isSavedNetwork);
|
isSavedNetwork);
|
||||||
mWifiManager.connect(config, mConnectListener);
|
mWifiManager.connect(config, mConnectListener);
|
||||||
mClickedConnect = true;
|
mClickedConnect = true;
|
||||||
|
@@ -28,6 +28,8 @@ import com.android.settings.overlay.FeatureFactory;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
@@ -42,24 +44,35 @@ import static org.mockito.Matchers.anyString;
|
|||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
public class MetricsFeatureProviderTest {
|
public class MetricsFeatureProviderTest {
|
||||||
|
private static int CATEGORY = 10;
|
||||||
|
private static boolean SUBTYPE_BOOLEAN = true;
|
||||||
|
private static int SUBTYPE_INTEGER = 1;
|
||||||
|
private static long ELAPSED_TIME = 1000;
|
||||||
|
|
||||||
|
@Mock private LogWriter mockLogWriter;
|
||||||
|
@Mock private VisibilityLoggerMixin mockVisibilityLogger;
|
||||||
|
|
||||||
@Mock
|
|
||||||
private LogWriter mLogWriter;
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private MetricsFeatureProvider mProvider;
|
private MetricsFeatureProvider mProvider;
|
||||||
|
|
||||||
|
@Captor
|
||||||
|
private ArgumentCaptor<Pair> mPairCaptor;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = RuntimeEnvironment.application;
|
mContext = RuntimeEnvironment.application;
|
||||||
mProvider = new MetricsFeatureProvider();
|
mProvider = new MetricsFeatureProvider();
|
||||||
List<LogWriter> writers = new ArrayList<>();
|
List<LogWriter> writers = new ArrayList<>();
|
||||||
writers.add(mLogWriter);
|
writers.add(mockLogWriter);
|
||||||
ReflectionHelpers.setField(mProvider, "mLoggerWriters", writers);
|
ReflectionHelpers.setField(mProvider, "mLoggerWriters", writers);
|
||||||
|
|
||||||
|
when(mockVisibilityLogger.elapsedTimeSinceVisible()).thenReturn(ELAPSED_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -77,7 +90,7 @@ public class MetricsFeatureProviderTest {
|
|||||||
mProvider.logDashboardStartIntent(mContext, null /* intent */,
|
mProvider.logDashboardStartIntent(mContext, null /* intent */,
|
||||||
MetricsEvent.SETTINGS_GESTURES);
|
MetricsEvent.SETTINGS_GESTURES);
|
||||||
|
|
||||||
verifyNoMoreInteractions(mLogWriter);
|
verifyNoMoreInteractions(mockLogWriter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -86,7 +99,7 @@ public class MetricsFeatureProviderTest {
|
|||||||
|
|
||||||
mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES);
|
mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES);
|
||||||
|
|
||||||
verify(mLogWriter).action(
|
verify(mockLogWriter).action(
|
||||||
eq(mContext),
|
eq(mContext),
|
||||||
eq(MetricsEvent.ACTION_SETTINGS_TILE_CLICK),
|
eq(MetricsEvent.ACTION_SETTINGS_TILE_CLICK),
|
||||||
anyString(),
|
anyString(),
|
||||||
@@ -99,10 +112,32 @@ public class MetricsFeatureProviderTest {
|
|||||||
|
|
||||||
mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES);
|
mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES);
|
||||||
|
|
||||||
verify(mLogWriter).action(
|
verify(mockLogWriter).action(
|
||||||
eq(mContext),
|
eq(mContext),
|
||||||
eq(MetricsEvent.ACTION_SETTINGS_TILE_CLICK),
|
eq(MetricsEvent.ACTION_SETTINGS_TILE_CLICK),
|
||||||
anyString(),
|
anyString(),
|
||||||
eq(Pair.create(MetricsEvent.FIELD_CONTEXT, MetricsEvent.SETTINGS_GESTURES)));
|
eq(Pair.create(MetricsEvent.FIELD_CONTEXT, MetricsEvent.SETTINGS_GESTURES)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void action_BooleanLogsElapsedTime() {
|
||||||
|
mProvider.action(mockVisibilityLogger, CATEGORY, SUBTYPE_BOOLEAN);
|
||||||
|
verify(mockLogWriter).action(eq(CATEGORY), eq(SUBTYPE_BOOLEAN), mPairCaptor.capture());
|
||||||
|
|
||||||
|
Pair value = mPairCaptor.getValue();
|
||||||
|
assertThat(value.first instanceof Integer).isTrue();
|
||||||
|
assertThat((int) value.first).isEqualTo(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS);
|
||||||
|
assertThat(value.second).isEqualTo(ELAPSED_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void action_IntegerLogsElapsedTime() {
|
||||||
|
mProvider.action(mockVisibilityLogger, CATEGORY, SUBTYPE_INTEGER);
|
||||||
|
verify(mockLogWriter).action(eq(CATEGORY), eq(SUBTYPE_INTEGER), mPairCaptor.capture());
|
||||||
|
|
||||||
|
Pair value = mPairCaptor.getValue();
|
||||||
|
assertThat(value.first instanceof Integer).isTrue();
|
||||||
|
assertThat((int) value.first).isEqualTo(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS);
|
||||||
|
assertThat(value.second).isEqualTo(ELAPSED_TIME);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user