From 4f6a1c0fc4f2a8b98dc0db9651b04f6628861e0f Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Thu, 12 Dec 2019 17:31:32 +0800 Subject: [PATCH] [SettingsLib] Add preference click metric log Add a method to log preference click event. The log order of priority is: 1. preference key 2. preference intent component name 3. preference intent action 4. preference fragment Bug: 137559984 Test: robotest Change-Id: Idecd7ada120a70b523ccd134c878f5753183211b --- .../MetricsFeatureProvider.java | 55 ++++++++----- .../MetricsFeatureProviderTest.java | 80 +++++++++++++++++-- 2 files changed, 108 insertions(+), 27 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java index 5cf44e1f6725a..a82231a597c34 100644 --- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java +++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java @@ -23,6 +23,9 @@ import android.content.Intent; import android.text.TextUtils; import android.util.Pair; +import androidx.annotation.NonNull; +import androidx.preference.Preference; + import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import java.util.ArrayList; @@ -132,34 +135,44 @@ public class MetricsFeatureProvider { return ((Instrumentable) object).getMetricsCategory(); } - public void logDashboardStartIntent(Context context, Intent intent, - int sourceMetricsCategory) { + /** + * Logs an event when the preference is clicked. + * + * @return true if the preference is loggable, otherwise false + */ + public boolean logClickedPreference(@NonNull Preference preference, int sourceMetricsCategory) { + if (preference == null) { + return false; + } + return logSettingsTileClick(preference.getKey(), sourceMetricsCategory) + || logStartedIntent(preference.getIntent(), sourceMetricsCategory) + || logSettingsTileClick(preference.getFragment(), sourceMetricsCategory); + } + + /** + * Logs an event when the intent is started. + * + * @return true if the intent is loggable, otherwise false + */ + public boolean logStartedIntent(Intent intent, int sourceMetricsCategory) { if (intent == null) { - return; + return false; } final ComponentName cn = intent.getComponent(); - if (cn == null) { - final String action = intent.getAction(); - if (TextUtils.isEmpty(action)) { - // Not loggable - return; - } - action(sourceMetricsCategory, - MetricsEvent.ACTION_SETTINGS_TILE_CLICK, - SettingsEnums.PAGE_UNKNOWN, - action, - 0); - return; - } 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; + return logSettingsTileClick(cn != null ? cn.flattenToString() : intent.getAction(), + sourceMetricsCategory); + } + + private boolean logSettingsTileClick(String logKey, int sourceMetricsCategory) { + if (TextUtils.isEmpty(logKey)) { + // Not loggable + return false; } action(sourceMetricsCategory, MetricsEvent.ACTION_SETTINGS_TILE_CLICK, SettingsEnums.PAGE_UNKNOWN, - cn.flattenToString(), + logKey, 0); + return true; } - } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java index 8a0ae9190a8cb..ed0857ca21dc1 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java @@ -26,6 +26,8 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import androidx.preference.Preference; + import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import org.junit.Before; @@ -60,19 +62,42 @@ public class MetricsFeatureProviderTest { } @Test - public void logDashboardStartIntent_intentEmpty_shouldNotLog() { - mProvider.logDashboardStartIntent(mContext, null /* intent */, + public void logClickedPreference_preferenceEmpty_shouldNotLog() { + final boolean loggable = mProvider.logClickedPreference(null /* preference */, MetricsEvent.SETTINGS_GESTURES); + assertThat(loggable).isFalse(); verifyNoMoreInteractions(mLogWriter); } @Test - public void logDashboardStartIntent_intentHasNoComponent_shouldLog() { + public void logClickedPreference_preferenceHasKey_shouldLog() { + final String key = "abc"; + final Preference preference = new Preference(mContext); + preference.setKey(key); + + final boolean loggable = mProvider.logClickedPreference(preference, + MetricsEvent.SETTINGS_GESTURES); + + assertThat(loggable).isTrue(); + verify(mLogWriter).action( + MetricsEvent.SETTINGS_GESTURES, + MetricsEvent.ACTION_SETTINGS_TILE_CLICK, + SettingsEnums.PAGE_UNKNOWN, + key, + 0); + } + + @Test + public void logClickedPreference_preferenceHasIntent_shouldLog() { + final Preference preference = new Preference(mContext); final Intent intent = new Intent(Intent.ACTION_ASSIST); + preference.setIntent(intent); - mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES); + final boolean loggable = mProvider.logClickedPreference(preference, + MetricsEvent.SETTINGS_GESTURES); + assertThat(loggable).isTrue(); verify(mLogWriter).action( MetricsEvent.SETTINGS_GESTURES, MetricsEvent.ACTION_SETTINGS_TILE_CLICK, @@ -82,11 +107,54 @@ public class MetricsFeatureProviderTest { } @Test - public void logDashboardStartIntent_intentIsExternal_shouldLog() { + public void logClickedPreference_preferenceHasFragment_shouldLog() { + final Preference preference = new Preference(mContext); + final String fragment = "com.android.settings.tts.TextToSpeechSettings"; + preference.setFragment(fragment); + + final boolean loggable = mProvider.logClickedPreference(preference, + MetricsEvent.SETTINGS_GESTURES); + + assertThat(loggable).isTrue(); + verify(mLogWriter).action( + MetricsEvent.SETTINGS_GESTURES, + MetricsEvent.ACTION_SETTINGS_TILE_CLICK, + SettingsEnums.PAGE_UNKNOWN, + fragment, + 0); + } + + @Test + public void logStartedIntent_intentEmpty_shouldNotLog() { + final boolean loggable = mProvider.logStartedIntent(null /* intent */, + MetricsEvent.SETTINGS_GESTURES); + + assertThat(loggable).isFalse(); + verifyNoMoreInteractions(mLogWriter); + } + + @Test + public void logStartedIntent_intentHasNoComponent_shouldLog() { + final Intent intent = new Intent(Intent.ACTION_ASSIST); + + final boolean loggable = mProvider.logStartedIntent(intent, MetricsEvent.SETTINGS_GESTURES); + + assertThat(loggable).isTrue(); + verify(mLogWriter).action( + MetricsEvent.SETTINGS_GESTURES, + MetricsEvent.ACTION_SETTINGS_TILE_CLICK, + SettingsEnums.PAGE_UNKNOWN, + Intent.ACTION_ASSIST, + 0); + } + + @Test + public void logStartedIntent_intentIsExternal_shouldLog() { final Intent intent = new Intent().setComponent(new ComponentName("pkg", "cls")); - mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES); + final boolean loggable = mProvider.logStartedIntent(intent, MetricsEvent.SETTINGS_GESTURES); + assertThat(loggable).isTrue(); verify(mLogWriter).action( MetricsEvent.SETTINGS_GESTURES, MetricsEvent.ACTION_SETTINGS_TILE_CLICK,