Avoid over logging preference changes.

When preference screen is created all prefence goes through
SharedPreferenceLogger once. We don't want to log it as preference
change because it's just initial display. Subsequent preference logger
calls should result in logging.

Bug: 30914916
Test: make RunSettingsRoboTests
Change-Id: Icaee9137c55555f4db7839ff0381a13ccd420190
This commit is contained in:
Fan Zhang
2016-09-23 17:26:41 -07:00
parent 3cf6ed8b40
commit 2d6bf057f8
2 changed files with 52 additions and 14 deletions

View File

@@ -21,6 +21,7 @@ import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.ArraySet;
import com.android.internal.logging.MetricsProto.MetricsEvent; import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
@@ -33,11 +34,13 @@ public class SharedPreferencesLogger implements SharedPreferences {
private final String mTag; private final String mTag;
private final Context mContext; private final Context mContext;
private final MetricsFeatureProvider mMetricsFeature; private final MetricsFeatureProvider mMetricsFeature;
private final Set<String> mPreferenceKeySet;
public SharedPreferencesLogger(Context context, String tag) { public SharedPreferencesLogger(Context context, String tag) {
mContext = context; mContext = context;
mTag = tag; mTag = tag;
mMetricsFeature = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); mMetricsFeature = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
mPreferenceKeySet = new ArraySet<>();
} }
@Override @Override
@@ -96,7 +99,15 @@ public class SharedPreferencesLogger implements SharedPreferences {
} }
private void logValue(String key, String value) { private void logValue(String key, String value) {
mMetricsFeature.count(mContext, mTag + "/" + key + "|" + value, 1); final String prefKey = mTag + "/" + key;
if (!mPreferenceKeySet.contains(prefKey)) {
// Pref key doesn't exist in set, this is initial display so we skip metrics but
// keeps track of this key.
mPreferenceKeySet.add(prefKey);
return;
}
// Pref key exists in set, log it's change in metrics.
mMetricsFeature.count(mContext, prefKey + "|" + value, 1);
} }
private void logPackageName(String key, String value) { private void logPackageName(String key, String value) {

View File

@@ -16,6 +16,7 @@
package com.android.settings.core.instrumentation; package com.android.settings.core.instrumentation;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import com.android.settings.TestConfig; import com.android.settings.TestConfig;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
@@ -32,7 +33,7 @@ import org.robolectric.shadows.ShadowApplication;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@@ -62,27 +63,53 @@ public class SharedPreferenceLoggerTest {
} }
@Test @Test
public void putInt_shouldLogCount() { public void putInt_shouldNotLogInitialPut() {
mSharedPrefLogger.edit().putInt(TEST_KEY, 1); final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
verify(mLogWriter).count(any(Context.class), anyString(), anyInt()); editor.putInt(TEST_KEY, 1);
editor.putInt(TEST_KEY, 1);
editor.putInt(TEST_KEY, 1);
editor.putInt(TEST_KEY, 2);
editor.putInt(TEST_KEY, 2);
editor.putInt(TEST_KEY, 2);
editor.putInt(TEST_KEY, 2);
verify(mLogWriter, times(6)).count(any(Context.class), anyString(), anyInt());
} }
@Test @Test
public void putBoolean_shouldLogCount() { public void putBoolean_shouldNotLogInitialPut() {
mSharedPrefLogger.edit().putBoolean(TEST_KEY, true); final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
verify(mLogWriter).count(any(Context.class), anyString(), anyInt()); editor.putBoolean(TEST_KEY, true);
editor.putBoolean(TEST_KEY, true);
editor.putBoolean(TEST_KEY, false);
editor.putBoolean(TEST_KEY, false);
editor.putBoolean(TEST_KEY, false);
verify(mLogWriter, times(4)).count(any(Context.class), anyString(), anyInt());
} }
@Test @Test
public void putLong_shouldLogCount() { public void putLong_shouldNotLogInitialPut() {
mSharedPrefLogger.edit().putLong(TEST_KEY, 1); final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
verify(mLogWriter).count(any(Context.class), anyString(), anyInt()); editor.putLong(TEST_KEY, 1);
editor.putLong(TEST_KEY, 1);
editor.putLong(TEST_KEY, 1);
editor.putLong(TEST_KEY, 1);
editor.putLong(TEST_KEY, 2);
verify(mLogWriter, times(4)).count(any(Context.class), anyString(), anyInt());
} }
@Test @Test
public void putFloat_shouldLogCount() { public void putFloat_shouldNotLogInitialPut() {
mSharedPrefLogger.edit().putInt(TEST_KEY, 1); final SharedPreferences.Editor editor = mSharedPrefLogger.edit();
verify(mLogWriter).count(any(Context.class), anyString(), anyInt()); editor.putFloat(TEST_KEY, 1);
editor.putFloat(TEST_KEY, 1);
editor.putFloat(TEST_KEY, 1);
editor.putFloat(TEST_KEY, 1);
editor.putFloat(TEST_KEY, 2);
verify(mLogWriter, times(4)).count(any(Context.class), anyString(), anyInt());
} }
} }