diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index ee0d2eca83b..36350f54f2d 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -71,6 +71,7 @@ import com.android.settings.applications.UsageAccessDetails; import com.android.settings.applications.VrListenerSettings; import com.android.settings.applications.WriteSettingsDetails; import com.android.settings.bluetooth.BluetoothSettings; +import com.android.settings.core.instrumentation.SharedPreferencesLogger; import com.android.settings.dashboard.DashboardContainerFragment; import com.android.settings.dashboard.SearchResultsSummary; import com.android.settings.datausage.DataUsageSummary; diff --git a/src/com/android/settings/core/instrumentation/EventLogWriter.java b/src/com/android/settings/core/instrumentation/EventLogWriter.java index 1ec5b94299f..de37cba27b6 100644 --- a/src/com/android/settings/core/instrumentation/EventLogWriter.java +++ b/src/com/android/settings/core/instrumentation/EventLogWriter.java @@ -21,9 +21,9 @@ import android.content.Context; import com.android.internal.logging.MetricsLogger; /** - * Pass-through Metrics logger for {@link MetricsLogger}. + * {@link LogWriter} that writes data to eventlog. */ -public class EventLogWriter { +public class EventLogWriter implements LogWriter { public void visible(Context context, int category) { MetricsLogger.visible(context, category); diff --git a/src/com/android/settings/core/instrumentation/LogWriter.java b/src/com/android/settings/core/instrumentation/LogWriter.java new file mode 100644 index 00000000000..45f1d57d663 --- /dev/null +++ b/src/com/android/settings/core/instrumentation/LogWriter.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.settings.core.instrumentation; + +import android.content.Context; + +/** + * Generic log writer interface. + */ +public interface LogWriter { + + /** + * Logs a visibility event when view becomes visible. + */ + void visible(Context context, int category); + + /** + * Logs a visibility event when view becomes hidden. + */ + void hidden(Context context, int category); + + /** + * Logs an user action. + */ + void action(Context context, int category); + + /** + * Logs an user action. + */ + void action(Context context, int category, int value); + + /** + * Logs an user action. + */ + void action(Context context, int category, boolean value); + + /** + * Logs an user action. + */ + void action(Context context, int category, String pkg); + + /** + * Logs a count. + */ + void count(Context context, String name, int value); + + /** + * Logs a histogram event. + */ + void histogram(Context context, String name, int bucket); +} diff --git a/src/com/android/settings/core/instrumentation/MetricsFactory.java b/src/com/android/settings/core/instrumentation/MetricsFactory.java index 3f315dfdc9a..8ea6d7005ef 100644 --- a/src/com/android/settings/core/instrumentation/MetricsFactory.java +++ b/src/com/android/settings/core/instrumentation/MetricsFactory.java @@ -16,11 +16,13 @@ package com.android.settings.core.instrumentation; +import android.support.annotation.VisibleForTesting; + public class MetricsFactory { private static MetricsFactory sInstance; - private EventLogWriter mLogger; + private LogWriter mLogger; public static MetricsFactory get() { if (sInstance == null) { @@ -29,10 +31,15 @@ public class MetricsFactory { return sInstance; } - public EventLogWriter getLogger() { + public LogWriter getLogger() { if (mLogger == null) { mLogger = new EventLogWriter(); } return mLogger; } + + @VisibleForTesting + void setLogger(LogWriter logger) { + mLogger = logger; + } } diff --git a/src/com/android/settings/SharedPreferencesLogger.java b/src/com/android/settings/core/instrumentation/SharedPreferencesLogger.java similarity index 93% rename from src/com/android/settings/SharedPreferencesLogger.java rename to src/com/android/settings/core/instrumentation/SharedPreferencesLogger.java index af34f16ba73..594ab96a2c1 100644 --- a/src/com/android/settings/SharedPreferencesLogger.java +++ b/src/com/android/settings/core/instrumentation/SharedPreferencesLogger.java @@ -12,9 +12,7 @@ * permissions and limitations under the License. */ -package com.android.settings; - -import com.android.internal.logging.MetricsLogger; +package com.android.settings.core.instrumentation; import android.annotation.Nullable; import android.content.ComponentName; @@ -23,7 +21,7 @@ import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.AsyncTask; import android.text.TextUtils; -import android.util.Log; + import com.android.internal.logging.MetricsProto.MetricsEvent; import java.util.Map; @@ -33,10 +31,12 @@ public class SharedPreferencesLogger implements SharedPreferences { private final String mTag; private final Context mContext; + private final LogWriter mLogWriter; public SharedPreferencesLogger(Context context, String tag) { mContext = context; mTag = tag; + mLogWriter = MetricsFactory.get().getLogger(); } @Override @@ -95,12 +95,12 @@ public class SharedPreferencesLogger implements SharedPreferences { } private void logValue(String key, String value) { - MetricsLogger.count(mContext, mTag + "/" + key + "|" + value, 1); + mLogWriter.count(mContext, mTag + "/" + key + "|" + value, 1); } private void logPackageName(String key, String value) { - MetricsLogger.count(mContext, mTag + "/" + key, 1); - MetricsLogger.action(mContext, MetricsEvent.ACTION_GENERIC_PACKAGE, + mLogWriter.count(mContext, mTag + "/" + key, 1); + mLogWriter.action(mContext, MetricsEvent.ACTION_GENERIC_PACKAGE, mTag + "/" + key + "|" + value); } diff --git a/src/com/android/settings/core/instrumentation/VisibilityLoggerMixin.java b/src/com/android/settings/core/instrumentation/VisibilityLoggerMixin.java index 4e52478e1c9..29a804b6a7c 100644 --- a/src/com/android/settings/core/instrumentation/VisibilityLoggerMixin.java +++ b/src/com/android/settings/core/instrumentation/VisibilityLoggerMixin.java @@ -24,22 +24,22 @@ import android.content.Context; public class VisibilityLoggerMixin { private final Instrumentable mInstrumentable; - private final EventLogWriter mEventLogWriter; + private final LogWriter mLogWriter; public VisibilityLoggerMixin(Instrumentable instrumentable) { this(instrumentable, MetricsFactory.get().getLogger()); } - public VisibilityLoggerMixin(Instrumentable instrumentable, EventLogWriter eventLogWriter) { + public VisibilityLoggerMixin(Instrumentable instrumentable, LogWriter logWriter) { mInstrumentable = instrumentable; - mEventLogWriter = eventLogWriter; + mLogWriter = logWriter; } public void onResume(Context context) { - mEventLogWriter.visible(context, mInstrumentable.getMetricsCategory()); + mLogWriter.visible(context, mInstrumentable.getMetricsCategory()); } public void onPause(Context context) { - mEventLogWriter.hidden(context, mInstrumentable.getMetricsCategory()); + mLogWriter.hidden(context, mInstrumentable.getMetricsCategory()); } } diff --git a/tests/unit/src/com/android/settings/core/instrumentation/MetricsFactoryTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFactoryTest.java similarity index 77% rename from tests/unit/src/com/android/settings/core/instrumentation/MetricsFactoryTest.java rename to tests/robotests/src/com/android/settings/core/instrumentation/MetricsFactoryTest.java index 7802b8697a5..552353539b0 100644 --- a/tests/unit/src/com/android/settings/core/instrumentation/MetricsFactoryTest.java +++ b/tests/robotests/src/com/android/settings/core/instrumentation/MetricsFactoryTest.java @@ -15,16 +15,17 @@ */ package com.android.settings.core.instrumentation; -import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; +import com.android.settings.TestConfig; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import static org.junit.Assert.assertTrue; -@RunWith(AndroidJUnit4.class) -@SmallTest +@RunWith(RobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class MetricsFactoryTest { @Test @@ -37,8 +38,8 @@ public class MetricsFactoryTest { @Test public void factoryShouldCacheLogger() { MetricsFactory factory = MetricsFactory.get(); - EventLogWriter logger1 = factory.getLogger(); - EventLogWriter logger2 = factory.getLogger(); + LogWriter logger1 = factory.getLogger(); + LogWriter logger2 = factory.getLogger(); assertTrue(logger1 == logger2); } } diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java new file mode 100644 index 00000000000..ccea6f0c3a5 --- /dev/null +++ b/tests/robotests/src/com/android/settings/core/instrumentation/SharedPreferenceLoggerTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.settings.core.instrumentation; + +import android.content.Context; + +import com.android.settings.TestConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowApplication; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.verify; + +@RunWith(RobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class SharedPreferenceLoggerTest { + + private static final String TEST_TAG = "tag"; + private static final String TEST_KEY = "key"; + + @Mock + private LogWriter mLogWriter; + + private ShadowApplication mApplication; + private SharedPreferencesLogger mSharedPrefLogger; + + @Before + public void init() { + MockitoAnnotations.initMocks(this); + mApplication = ShadowApplication.getInstance(); + MetricsFactory.get().setLogger(mLogWriter); + mSharedPrefLogger = new SharedPreferencesLogger( + mApplication.getApplicationContext(), TEST_TAG); + } + + @Test + public void putInt_shouldLogCount() { + mSharedPrefLogger.edit().putInt(TEST_KEY, 1); + verify(mLogWriter).count(any(Context.class), anyString(), anyInt()); + } + + @Test + public void putBoolean_shouldLogCount() { + mSharedPrefLogger.edit().putBoolean(TEST_KEY, true); + verify(mLogWriter).count(any(Context.class), anyString(), anyInt()); + } + + @Test + public void putLong_shouldLogCount() { + mSharedPrefLogger.edit().putLong(TEST_KEY, 1); + verify(mLogWriter).count(any(Context.class), anyString(), anyInt()); + } + + @Test + public void putFloat_shouldLogCount() { + mSharedPrefLogger.edit().putInt(TEST_KEY, 1); + verify(mLogWriter).count(any(Context.class), anyString(), anyInt()); + } + +} diff --git a/tests/unit/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java similarity index 88% rename from tests/unit/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java rename to tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java index e7932295519..3940029356c 100644 --- a/tests/unit/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java +++ b/tests/robotests/src/com/android/settings/core/instrumentation/VisibilityLoggerMixinTest.java @@ -16,22 +16,25 @@ package com.android.settings.core.instrumentation; import android.content.Context; -import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; + +import com.android.settings.TestConfig; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -@RunWith(AndroidJUnit4.class) -@SmallTest + +@RunWith(RobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class VisibilityLoggerMixinTest { @Mock