diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java index 4b4e03f0bc7..73c11777979 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java @@ -17,13 +17,14 @@ package com.android.settings.dashboard.suggestions; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; -import android.support.annotation.NonNull; -import android.content.ContentResolver; import android.provider.Settings.Secure; +import android.support.annotation.NonNull; import android.support.annotation.VisibleForTesting; +import android.text.format.DateUtils; import android.util.Log; import com.android.internal.logging.nano.MetricsProto; @@ -43,6 +44,12 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider private static final String SHARED_PREF_FILENAME = "suggestions"; + // Suggestion category name and expiration threshold for first impression type. Needs to keep + // in sync with suggestion_ordering.xml + private static final String CATEGORY_FIRST_IMPRESSION = + "com.android.settings.suggested.category.FIRST_IMPRESSION"; + private static final long FIRST_IMPRESSION_EXPIRE_DAY_IN_MILLIS = 14 * DateUtils.DAY_IN_MILLIS; + private final SuggestionRanker mSuggestionRanker; private final MetricsFeatureProvider mMetricsFeatureProvider; @@ -101,7 +108,11 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider context, MetricsProto.MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION, getSuggestionIdentifier(context, suggestion)); - final boolean isSmartSuggestionEnabled = isSmartSuggestionEnabled(context); + boolean isSmartSuggestionEnabled = isSmartSuggestionEnabled(context); + if (isSmartSuggestionEnabled) { + // Disable smart suggestion if we are still showing first impression suggestions. + isSmartSuggestionEnabled = !isShowingFirstImpressionSuggestion(context); + } if (!parser.dismissSuggestion(suggestion, isSmartSuggestionEnabled)) { return; } @@ -111,6 +122,19 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider PackageManager.DONT_KILL_APP); } + private boolean isShowingFirstImpressionSuggestion(Context context) { + final String keySetupTime = CATEGORY_FIRST_IMPRESSION + SuggestionParser.SETUP_TIME; + final long currentTime = System.currentTimeMillis(); + final SharedPreferences sharedPrefs = getSharedPrefs(context); + if (!sharedPrefs.contains(keySetupTime)) { + return true; + } + final long setupTime = sharedPrefs.getLong(keySetupTime, 0); + final long elapsedTime = currentTime - setupTime; + Log.d(TAG, "Day " + elapsedTime / DateUtils.DAY_IN_MILLIS + " for first impression"); + return elapsedTime <= FIRST_IMPRESSION_EXPIRE_DAY_IN_MILLIS; + } + @Override public String getSuggestionIdentifier(Context context, Tile suggestion) { if (suggestion.intent == null || suggestion.intent.getComponent() == null @@ -130,7 +154,7 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider boolean hasUsedNightDisplay(Context context) { final ContentResolver cr = context.getContentResolver(); final long lastActivatedTimeMillis = Secure.getLong(cr, - Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, -1); + Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, -1); return lastActivatedTimeMillis > 0; } } diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java index e263e2cc0ec..93cd3147508 100644 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java @@ -19,15 +19,15 @@ package com.android.settings.dashboard.suggestions; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.content.pm.PackageManager; - import android.provider.Settings.Secure; + import com.android.internal.logging.nano.MetricsProto; import com.android.settings.Settings.NightDisplaySuggestionActivity; -import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settings.Settings; import com.android.settings.TestConfig; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.ShadowSecureSettings; import com.android.settingslib.drawer.Tile; import com.android.settingslib.suggestions.SuggestionParser; @@ -50,14 +50,15 @@ import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, - sdk = TestConfig.SDK_VERSION, - shadows = ShadowSecureSettings.class) + sdk = TestConfig.SDK_VERSION, + shadows = ShadowSecureSettings.class) public class SuggestionFeatureProviderImplTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) @@ -139,6 +140,25 @@ public class SuggestionFeatureProviderImplTest { verify(mContext, never()).getPackageManager(); } + @Test + public void dismissSuggestion_isShowingFirstImpressionType_dismissWithoutSmartSuggestionRule() { + mProvider = spy(mProvider); + when(mProvider.isSmartSuggestionEnabled(any(Context.class))).thenReturn(true); + final SharedPreferences pref = RuntimeEnvironment.application.getSharedPreferences( + "test_pref", Context.MODE_PRIVATE); + when(mProvider.getSharedPrefs(mContext)).thenReturn(pref); + when(mSuggestionParser.dismissSuggestion(any(Tile.class), anyBoolean())) + .thenReturn(false); + + mProvider.dismissSuggestion(mContext, mSuggestionParser, mSuggestion); + + verify(mFactory.metricsFeatureProvider).action( + eq(mContext), + eq(MetricsProto.MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION), + anyString()); + verify(mSuggestionParser).dismissSuggestion(any(Tile.class), eq(false)); + } + @Test public void dismissSuggestion_noContext_shouldDoNothing() { mProvider.dismissSuggestion(null, mSuggestionParser, mSuggestion); @@ -195,14 +215,14 @@ public class SuggestionFeatureProviderImplTest { public void nightDisplaySuggestion_isCompleted_ifPreviouslyActivated() { Secure.putLong(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, 1L); final ComponentName componentName = - new ComponentName(mContext, NightDisplaySuggestionActivity.class); + new ComponentName(mContext, NightDisplaySuggestionActivity.class); assertThat(mProvider.isSuggestionCompleted(mContext, componentName)).isTrue(); } @Test public void nightDisplaySuggestion_isNotCompleted_byDefault() { final ComponentName componentName = - new ComponentName(mContext, NightDisplaySuggestionActivity.class); + new ComponentName(mContext, NightDisplaySuggestionActivity.class); assertThat(mProvider.isSuggestionCompleted(mContext, componentName)).isFalse(); } }