Add logging whenever preference leads to intent.
Bug: 34774945 Test: make RunSettignsRoboTests Change-Id: I694e5a0a2b614c695193c9c525991a1558e0a81a
This commit is contained in:
@@ -29,9 +29,12 @@ public abstract class InstrumentedFragment extends ObservableFragment implements
|
|||||||
|
|
||||||
protected MetricsFeatureProvider mMetricsFeatureProvider;
|
protected MetricsFeatureProvider mMetricsFeatureProvider;
|
||||||
|
|
||||||
|
private final VisibilityLoggerMixin mVisibilityLoggerMixin;
|
||||||
|
|
||||||
public InstrumentedFragment() {
|
public InstrumentedFragment() {
|
||||||
// Mixin that logs visibility change for activity.
|
// Mixin that logs visibility change for activity.
|
||||||
getLifecycle().addObserver(new VisibilityLoggerMixin(getMetricsCategory()));
|
mVisibilityLoggerMixin = new VisibilityLoggerMixin(getMetricsCategory());
|
||||||
|
getLifecycle().addObserver(mVisibilityLoggerMixin);
|
||||||
getLifecycle().addObserver(new SurveyMixin(this, getClass().getSimpleName()));
|
getLifecycle().addObserver(new SurveyMixin(this, getClass().getSimpleName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,4 +43,10 @@ public abstract class InstrumentedFragment extends ObservableFragment implements
|
|||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
|
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
mVisibilityLoggerMixin.setSourceMetricsCategory(getActivity());
|
||||||
|
super.onResume();
|
||||||
|
}
|
||||||
}
|
}
|
@@ -15,7 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.settings.core.instrumentation;
|
package com.android.settings.core.instrumentation;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
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;
|
||||||
@@ -100,4 +103,27 @@ public class MetricsFeatureProvider {
|
|||||||
}
|
}
|
||||||
return ((Instrumentable) object).getMetricsCategory();
|
return ((Instrumentable) object).getMetricsCategory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void logDashboardStartIntent(Context context, Intent intent,
|
||||||
|
int sourceMetricsCategory) {
|
||||||
|
if (intent == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final ComponentName cn = intent.getComponent();
|
||||||
|
if (cn == null) {
|
||||||
|
final String action = intent.getAction();
|
||||||
|
if (TextUtils.isEmpty(action)) {
|
||||||
|
// Not loggable
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
action(context, MetricsProto.MetricsEvent.ACTION_SETTINGS_TILE_CLICK, action,
|
||||||
|
Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, sourceMetricsCategory));
|
||||||
|
} else if (TextUtils.equals(cn.getPackageName(), context.getPackageName())) {
|
||||||
|
// Going to a Setting internal page, skip click logging in favor of page's own
|
||||||
|
// visibility logging.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
action(context, MetricsProto.MetricsEvent.ACTION_SETTINGS_TILE_CLICK, cn.flattenToString(),
|
||||||
|
Pair.create(MetricsProto.MetricsEvent.FIELD_CONTEXT, sourceMetricsCategory));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,10 +27,8 @@ import android.support.v7.preference.Preference;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
import com.android.settings.SettingsActivity;
|
import com.android.settings.SettingsActivity;
|
||||||
import com.android.settings.SubSettings;
|
|
||||||
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settingslib.drawer.CategoryManager;
|
import com.android.settingslib.drawer.CategoryManager;
|
||||||
@@ -154,7 +152,7 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
|
|||||||
intent.setAction(action);
|
intent.setAction(action);
|
||||||
}
|
}
|
||||||
pref.setOnPreferenceClickListener(preference -> {
|
pref.setOnPreferenceClickListener(preference -> {
|
||||||
launchIntentOrSelectProfile(activity, tile, intent);
|
launchIntentOrSelectProfile(activity, tile, intent, sourceMetricsCategory);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -204,37 +202,20 @@ public class DashboardFeatureProviderImpl implements DashboardFeatureProvider {
|
|||||||
MetricsEvent.DASHBOARD_SUMMARY)
|
MetricsEvent.DASHBOARD_SUMMARY)
|
||||||
.putExtra(SettingsDrawerActivity.EXTRA_SHOW_MENU, true)
|
.putExtra(SettingsDrawerActivity.EXTRA_SHOW_MENU, true)
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
launchIntentOrSelectProfile(activity, tile, intent);
|
launchIntentOrSelectProfile(activity, tile, intent, MetricsEvent.DASHBOARD_SUMMARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void launchIntentOrSelectProfile(Activity activity, Tile tile, Intent intent) {
|
private void launchIntentOrSelectProfile(Activity activity, Tile tile, Intent intent,
|
||||||
|
int sourceMetricCategory) {
|
||||||
ProfileSelectDialog.updateUserHandlesIfNeeded(mContext, tile);
|
ProfileSelectDialog.updateUserHandlesIfNeeded(mContext, tile);
|
||||||
if (tile.userHandle == null) {
|
if (tile.userHandle == null) {
|
||||||
logStartActivity(intent);
|
mMetricsFeatureProvider.logDashboardStartIntent(mContext, intent, sourceMetricCategory);
|
||||||
activity.startActivityForResult(intent, 0);
|
activity.startActivityForResult(intent, 0);
|
||||||
} else if (tile.userHandle.size() == 1) {
|
} else if (tile.userHandle.size() == 1) {
|
||||||
logStartActivity(intent);
|
mMetricsFeatureProvider.logDashboardStartIntent(mContext, intent, sourceMetricCategory);
|
||||||
activity.startActivityForResultAsUser(intent, 0, tile.userHandle.get(0));
|
activity.startActivityForResultAsUser(intent, 0, tile.userHandle.get(0));
|
||||||
} else {
|
} else {
|
||||||
ProfileSelectDialog.show(activity.getFragmentManager(), tile);
|
ProfileSelectDialog.show(activity.getFragmentManager(), tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logStartActivity(Intent intent) {
|
|
||||||
if (intent == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final ComponentName cn = intent.getComponent();
|
|
||||||
if (cn == null) {
|
|
||||||
// Not loggable
|
|
||||||
return;
|
|
||||||
} else if (TextUtils.equals(cn.getPackageName(), mContext.getPackageName())) {
|
|
||||||
// Going to a Setting internal page, skip click logging in favor of page's own
|
|
||||||
// visibility logging.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mMetricsFeatureProvider.action(mContext,
|
|
||||||
MetricsEvent.ACTION_SETTINGS_TILE_CLICK,
|
|
||||||
cn.flattenToString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -157,6 +157,9 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
|
|||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceTreeClick(Preference preference) {
|
public boolean onPreferenceTreeClick(Preference preference) {
|
||||||
Collection<PreferenceController> controllers = mPreferenceControllers.values();
|
Collection<PreferenceController> controllers = mPreferenceControllers.values();
|
||||||
|
// If preference contains intent, log it before handling.
|
||||||
|
mMetricsFeatureProvider.logDashboardStartIntent(
|
||||||
|
getContext(), preference.getIntent(), getMetricsCategory());
|
||||||
// Give all controllers a chance to handle click.
|
// Give all controllers a chance to handle click.
|
||||||
for (PreferenceController controller : controllers) {
|
for (PreferenceController controller : controllers) {
|
||||||
if (controller.handlePreferenceTreeClick(preference)) {
|
if (controller.handlePreferenceTreeClick(preference)) {
|
||||||
|
@@ -15,35 +15,51 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.settings.core.instrumentation;
|
package com.android.settings.core.instrumentation;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
import com.android.settings.SettingsRobolectricTestRunner;
|
import com.android.settings.SettingsRobolectricTestRunner;
|
||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
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.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
import org.robolectric.shadows.ShadowApplication;
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
|
|
||||||
@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 ShadowApplication mApplication;
|
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private LogWriter mLogWriter;
|
private LogWriter mLogWriter;
|
||||||
|
private Context mContext;
|
||||||
|
private MetricsFeatureProvider mProvider;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mApplication = ShadowApplication.getInstance();
|
mContext = RuntimeEnvironment.application;
|
||||||
mContext = mApplication.getApplicationContext();
|
mProvider = new MetricsFeatureProvider();
|
||||||
|
List<LogWriter> writers = new ArrayList<>();
|
||||||
|
writers.add(mLogWriter);
|
||||||
|
ReflectionHelpers.setField(mProvider, "mLoggerWriters", writers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -55,4 +71,25 @@ public class MetricsFeatureProviderTest {
|
|||||||
|
|
||||||
assertThat(feature1 == feature2).isTrue();
|
assertThat(feature1 == feature2).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void logDashboardStartIntent_intentEmpty_shouldNotLog() {
|
||||||
|
mProvider.logDashboardStartIntent(mContext, null /* intent */,
|
||||||
|
MetricsEvent.SETTINGS_GESTURES);
|
||||||
|
|
||||||
|
verifyNoMoreInteractions(mLogWriter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void logDashboardStartIntent_intentIsExternal_shouldLog() {
|
||||||
|
final Intent intent = new Intent().setComponent(new ComponentName("pkg", "cls"));
|
||||||
|
|
||||||
|
mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES);
|
||||||
|
|
||||||
|
verify(mLogWriter).action(
|
||||||
|
eq(mContext),
|
||||||
|
eq(MetricsEvent.ACTION_SETTINGS_TILE_CLICK),
|
||||||
|
anyString(),
|
||||||
|
eq(Pair.create(MetricsEvent.FIELD_CONTEXT, MetricsEvent.SETTINGS_GESTURES)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -56,7 +56,6 @@ import static org.mockito.Matchers.any;
|
|||||||
import static org.mockito.Matchers.anyInt;
|
import static org.mockito.Matchers.anyInt;
|
||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@@ -166,10 +165,11 @@ public class DashboardFeatureProviderImplTest {
|
|||||||
mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.SETTINGS_GESTURES,
|
mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.SETTINGS_GESTURES,
|
||||||
preference, tile, "123", Preference.DEFAULT_ORDER);
|
preference, tile, "123", Preference.DEFAULT_ORDER);
|
||||||
preference.getOnPreferenceClickListener().onPreferenceClick(null);
|
preference.getOnPreferenceClickListener().onPreferenceClick(null);
|
||||||
verify(mFeatureFactory.metricsFeatureProvider).action(
|
|
||||||
|
verify(mFeatureFactory.metricsFeatureProvider).logDashboardStartIntent(
|
||||||
any(Context.class),
|
any(Context.class),
|
||||||
eq(MetricsProto.MetricsEvent.ACTION_SETTINGS_TILE_CLICK),
|
any(Intent.class),
|
||||||
eq(tile.intent.getComponent().flattenToString()));
|
eq(MetricsProto.MetricsEvent.SETTINGS_GESTURES));
|
||||||
verify(mActivity)
|
verify(mActivity)
|
||||||
.startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class));
|
.startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class));
|
||||||
}
|
}
|
||||||
@@ -193,10 +193,10 @@ public class DashboardFeatureProviderImplTest {
|
|||||||
mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.SETTINGS_GESTURES,
|
mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.SETTINGS_GESTURES,
|
||||||
preference, tile, "123", Preference.DEFAULT_ORDER);
|
preference, tile, "123", Preference.DEFAULT_ORDER);
|
||||||
preference.getOnPreferenceClickListener().onPreferenceClick(null);
|
preference.getOnPreferenceClickListener().onPreferenceClick(null);
|
||||||
verify(mFeatureFactory.metricsFeatureProvider, never()).action(
|
verify(mFeatureFactory.metricsFeatureProvider).logDashboardStartIntent(
|
||||||
any(Context.class),
|
any(Context.class),
|
||||||
eq(MetricsProto.MetricsEvent.ACTION_SETTINGS_TILE_CLICK),
|
any(Intent.class),
|
||||||
eq(tile.intent.getComponent().flattenToString()));
|
anyInt());
|
||||||
verify(mActivity)
|
verify(mActivity)
|
||||||
.startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class));
|
.startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user