Move SharedPreferenceLogger to instrumentation package.

Bug: 30914916
Test: SettingsUnitTests and RunSettingsRoboTests

- Added interface to abstract logger
- Added test for SharePrefLogger
- Moved Existing tests for instrumentation to robotests.

Change-Id: I2b431ea4b0fd09d0f11389d8b9181448f08a52c5
This commit is contained in:
Fan Zhang
2016-08-18 16:04:19 -07:00
parent cbb2f5f498
commit 5f79ae9677
9 changed files with 184 additions and 26 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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());
}
}

View File

@@ -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);
}
}

View File

@@ -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());
}
}

View File

@@ -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