diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java index 5df66f1dcb3..600b23b46b4 100644 --- a/src/com/android/settings/dashboard/DashboardAdapter.java +++ b/src/com/android/settings/dashboard/DashboardAdapter.java @@ -47,6 +47,8 @@ import com.android.settings.dashboard.DashboardData.SuggestionConditionHeaderDat import com.android.settings.dashboard.conditional.Condition; import com.android.settings.dashboard.conditional.ConditionAdapter; import com.android.settings.dashboard.suggestions.SuggestionAdapter; +import com.android.settings.dashboard.suggestions.SuggestionController; +import com.android.settings.dashboard.suggestions.SuggestionControllerMixin; import com.android.settings.dashboard.suggestions.SuggestionDismissController; import com.android.settings.dashboard.suggestions.SuggestionFeatureProvider; import com.android.settings.dashboard.suggestions.SuggestionLogHelper; @@ -76,6 +78,7 @@ public class DashboardAdapter extends RecyclerView.Adapter conditions, SuggestionParser suggestionParser, + SuggestionControllerMixin suggestionControllerMixin, SuggestionDismissController.Callback callback) { // @deprecated In favor of suggestionsV2 below. @@ -110,6 +114,7 @@ public class DashboardAdapter extends RecyclerView.Adapter 0) { conditionOnly = false; @@ -496,7 +501,7 @@ public class DashboardAdapter extends RecyclerView.Adapter) mDashboardData.getItemEntityByPosition(position), mSuggestionsShownLogged); mSuggestionDismissHandler = new SuggestionDismissController(mContext, - holder.data, null /* parser */, mCallback); + holder.data, mSuggestionControllerMixin, null /* parser */, mCallback); holder.data.setAdapter(mSuggestionAdapter); } } diff --git a/src/com/android/settings/dashboard/DashboardSummary.java b/src/com/android/settings/dashboard/DashboardSummary.java index 769a3d70c86..c0ace7d61ca 100644 --- a/src/com/android/settings/dashboard/DashboardSummary.java +++ b/src/com/android/settings/dashboard/DashboardSummary.java @@ -91,6 +91,7 @@ public class DashboardSummary extends InstrumentedFragment mSuggestionFeatureProvider = FeatureFactory.getFactory(context) .getSuggestionFeatureProvider(context); if (mSuggestionFeatureProvider.isSuggestionV2Enabled(context)) { + Log.d(TAG, "Suggestion v2 is enabled, creating SuggestionControllerMixin"); mSuggestionControllerMixin = new SuggestionControllerMixin(context, this /* host */, getLifecycle()); } @@ -207,7 +208,8 @@ public class DashboardSummary extends InstrumentedFragment mDashboard.setHasFixedSize(true); mDashboard.setListener(this); mAdapter = new DashboardAdapter(getContext(), bundle, mConditionManager.getConditions(), - mSuggestionParser, this /* SuggestionDismissController.Callback */); + mSuggestionParser, mSuggestionControllerMixin, + this /* SuggestionDismissController.Callback */); mDashboard.setAdapter(mAdapter); mDashboard.setItemAnimator(new DashboardItemAnimator()); mSummaryLoader.setSummaryConsumer(mAdapter); @@ -224,7 +226,7 @@ public class DashboardSummary extends InstrumentedFragment @VisibleForTesting void rebuildUI() { if (!mSuggestionFeatureProvider.isSuggestionEnabled(getContext())) { - Log.d(TAG, "Suggestion feature is disabled, skipping suggestion entirely"); + Log.d(TAG, "Suggestion v1 feature is disabled, skipping suggestion v1"); updateCategory(); } else { new SuggestionLoader().execute(); diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionController.java b/src/com/android/settings/dashboard/suggestions/SuggestionController.java index ac20433bc69..865e045de74 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionController.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionController.java @@ -110,6 +110,18 @@ public class SuggestionController { } } + public void dismissSuggestions(Suggestion suggestion) { + if (!isReady()) { + Log.w(TAG, "SuggestionController not ready, cannot dismiss " + suggestion.getId()); + return; + } + try { + mRemoteService.dismissSuggestion(suggestion); + } catch (RemoteException e) { + Log.w(TAG, "Error when calling dismissSuggestion()", e); + } + } + /** * Whether or not the manager is ready */ diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java b/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java index 44744ecebf1..cf015ac66ac 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionControllerMixin.java @@ -111,4 +111,8 @@ public class SuggestionControllerMixin implements SuggestionController.ServiceCo public void onLoaderReset(Loader> loader) { } + + public void dismissSuggestion(Suggestion suggestion) { + mSuggestionController.dismissSuggestions(suggestion); + } } diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionDismissController.java b/src/com/android/settings/dashboard/suggestions/SuggestionDismissController.java index 6affa8cedf7..b3636c16797 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionDismissController.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionDismissController.java @@ -57,6 +57,7 @@ public class SuggestionDismissController extends ItemTouchHelper.SimpleCallback private final Context mContext; private final SuggestionFeatureProvider mSuggestionFeatureProvider; + private final SuggestionControllerMixin mSuggestionMixin; /** * @deprecated in favor of the new Suggestion backend. @@ -66,8 +67,9 @@ public class SuggestionDismissController extends ItemTouchHelper.SimpleCallback private final Callback mCallback; public SuggestionDismissController(Context context, RecyclerView recyclerView, - SuggestionParser parser, Callback callback) { + SuggestionControllerMixin suggestionMixin, SuggestionParser parser, Callback callback) { super(0, ItemTouchHelper.START | ItemTouchHelper.END); + mSuggestionMixin = suggestionMixin; mContext = context; mSuggestionParser = parser; mSuggestionFeatureProvider = FeatureFactory.getFactory(context) @@ -102,7 +104,7 @@ public class SuggestionDismissController extends ItemTouchHelper.SimpleCallback final int position = viewHolder.getAdapterPosition(); final Suggestion suggestionV2 = mCallback.getSuggestionAt(position); if (suggestionV2 != null) { - mSuggestionFeatureProvider.dismissSuggestion(mContext, suggestionV2); + mSuggestionFeatureProvider.dismissSuggestion(mContext, mSuggestionMixin, suggestionV2); mCallback.onSuggestionDismissed(suggestionV2); } else { final Tile suggestion = mCallback.getSuggestionForPosition(position); diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java index 14654082696..86708232e41 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java @@ -79,7 +79,8 @@ public interface SuggestionFeatureProvider { /** * Dismisses a suggestion. * - * @deprecated in favor of {@link #dismissSuggestion(Context, Suggestion)} + * @deprecated in favor of {@link #dismissSuggestion(Context, SuggestionControllerMixin, + * Suggestion)} */ @Deprecated void dismissSuggestion(Context context, SuggestionParser parser, Tile suggestion); @@ -87,7 +88,8 @@ public interface SuggestionFeatureProvider { /** * Dismisses a suggestion. */ - void dismissSuggestion(Context context, Suggestion suggestion); + void dismissSuggestion(Context context, SuggestionControllerMixin suggestionMixin, + Suggestion suggestion); /** * Returns an identifier for the suggestion diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java index 715964bc638..d4002b255c3 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java @@ -173,14 +173,15 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider } @Override - public void dismissSuggestion(Context context, Suggestion suggestion) { - if (suggestion == null || context == null) { + public void dismissSuggestion(Context context, SuggestionControllerMixin mixin, + Suggestion suggestion) { + if (mixin == null || suggestion == null || context == null) { return; } mMetricsFeatureProvider.action( context, MetricsProto.MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION, suggestion.getId()); - // TODO: Call SettingsIntelligence to dismiss suggestion. + mixin.dismissSuggestion(suggestion); } @Override diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java index b14a80ffe16..595a9c6f739 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java @@ -120,7 +120,7 @@ public class DashboardAdapterTest { mConditionList = new ArrayList<>(); mConditionList.add(mCondition); when(mCondition.shouldShow()).thenReturn(true); - mDashboardAdapter = new DashboardAdapter(mContext, null, mConditionList, null, null); + mDashboardAdapter = new DashboardAdapter(mContext, null, mConditionList, null, null, null); mSuggestionHeaderData = new DashboardData.SuggestionConditionHeaderData(mConditionList, 1); when(mView.getTag()).thenReturn(mCondition); } @@ -419,7 +419,7 @@ public class DashboardAdapterTest { @Test public void testSuggestionDismissed_notOnlySuggestion_updateSuggestionOnly() { final DashboardAdapter adapter = - spy(new DashboardAdapter(mContext, null, null, null, null)); + spy(new DashboardAdapter(mContext, null, null, null, null, null)); final List suggestions = makeSuggestions("pkg1", "pkg2", "pkg3"); adapter.setCategoriesAndSuggestions(null /* category */, suggestions); @@ -457,7 +457,8 @@ public class DashboardAdapterTest { final List suggestions = makeSuggestions("pkg1", "pkg2", "pkg3", "pkg4"); final DashboardAdapter adapter = spy(new DashboardAdapter(mContext, null /*savedInstance */, - null /* conditions */, null /* suggestionParser */, null /* callback */)); + null /* conditions */, null /* suggestionParser */, + null /* suggestionControllerMixin */, null /* callback */)); adapter.setCategoriesAndSuggestions(null /* category */, suggestions); adapter.onBindConditionAndSuggestion( holder, DashboardAdapter.SUGGESTION_CONDITION_HEADER_POSITION); @@ -474,7 +475,7 @@ public class DashboardAdapterTest { @Test public void testSuggestionDismissed_onlySuggestion_updateDashboardData() { DashboardAdapter adapter = - spy(new DashboardAdapter(mContext, null, null, null, null)); + spy(new DashboardAdapter(mContext, null, null, null, null, null)); final List suggestions = makeSuggestions("pkg1"); adapter.setCategoriesAndSuggestions(null /* category */, suggestions); final DashboardData dashboardData = adapter.mDashboardData; @@ -534,7 +535,7 @@ public class DashboardAdapterTest { @Test public void testBindConditionAndSuggestion_shouldSetSuggestionAdapterAndNoCrash() { - mDashboardAdapter = new DashboardAdapter(mContext, null, null, null, null); + mDashboardAdapter = new DashboardAdapter(mContext, null, null, null, null, null); final List suggestions = makeSuggestions("pkg1"); final DashboardCategory category = mock(DashboardCategory.class); final List tiles = new ArrayList<>(); @@ -561,7 +562,7 @@ public class DashboardAdapterTest { @Test public void testBindConditionAndSuggestion_v2_shouldSetSuggestionAdapterAndNoCrash() { - mDashboardAdapter = new DashboardAdapter(mContext, null, null, null, null); + mDashboardAdapter = new DashboardAdapter(mContext, null, null, null, null, null); final List suggestions = makeSuggestionsV2("pkg1"); final DashboardCategory category = mock(DashboardCategory.class); final List tiles = new ArrayList<>(); @@ -592,7 +593,8 @@ public class DashboardAdapterTest { savedInstance.putInt(DashboardAdapter.STATE_SUGGESTION_CONDITION_MODE, DashboardData.HEADER_MODE_FULLY_EXPANDED); mDashboardAdapter = new DashboardAdapter(mContext, savedInstance, mConditionList, - null /* SuggestionParser */, null /* SuggestionDismissController.Callback */); + null /* SuggestionParser */, null /* suggestionControllerMixin */, + null /* SuggestionDismissController.Callback */); final List suggestions = new ArrayList<>(); final DashboardCategory category = mock(DashboardCategory.class); diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionDismissControllerTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionDismissControllerTest.java index ca9faf56d51..93bc5491198 100644 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionDismissControllerTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionDismissControllerTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; +import android.service.settings.suggestions.Suggestion; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; @@ -55,6 +56,8 @@ public class SuggestionDismissControllerTest { @Mock private SuggestionParser mSuggestionParser; @Mock + private SuggestionControllerMixin mSuggestionControllerMixin; + @Mock private SuggestionDismissController.Callback mCallback; private FakeFeatureFactory mFactory; @@ -69,7 +72,7 @@ public class SuggestionDismissControllerTest { when(mRecyclerView.getResources().getDimension(anyInt())).thenReturn(50F); mController = new SuggestionDismissController(mContext, mRecyclerView, - mSuggestionParser, mCallback); + mSuggestionControllerMixin, mSuggestionParser, mCallback); } @Test @@ -114,4 +117,17 @@ public class SuggestionDismissControllerTest { eq(mContext), eq(mSuggestionParser), nullable(Tile.class)); verify(mCallback).onSuggestionDismissed(nullable(Tile.class)); } + + @Test + public void onSwiped_v2_shouldTriggerDismissSuggestion() { + final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class); + when(mCallback.getSuggestionAt(anyInt())).thenReturn( + new Suggestion.Builder("id").build()); + + mController.onSwiped(vh, ItemTouchHelper.START); + + verify(mFactory.suggestionsFeatureProvider).dismissSuggestion( + eq(mContext), eq(mSuggestionControllerMixin), nullable(Suggestion.class)); + verify(mCallback).onSuggestionDismissed(nullable(Suggestion.class)); + } } 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 59822109dee..deb860d9978 100644 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java @@ -35,11 +35,12 @@ import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.hardware.fingerprint.FingerprintManager; import android.provider.Settings.Secure; +import android.service.settings.suggestions.Suggestion; import android.util.FeatureFlagUtils; import android.util.Pair; -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.Settings.AmbientDisplayPickupSuggestionActivity; import com.android.settings.Settings.AmbientDisplaySuggestionActivity; @@ -95,6 +96,8 @@ public class SuggestionFeatureProviderImplTest { @Mock private SuggestionParser mSuggestionParser; @Mock + private SuggestionControllerMixin mSuggestionControllerMixin; + @Mock private Tile mSuggestion; @Mock private ActivityManager mActivityManager; @@ -325,13 +328,23 @@ public class SuggestionFeatureProviderImplTest { @Test public void dismissSuggestion_noParserOrSuggestion_noop() { - mProvider.dismissSuggestion(mContext, null, null); + mProvider.dismissSuggestion(mContext, null, (Tile) null); mProvider.dismissSuggestion(mContext, mSuggestionParser, null); mProvider.dismissSuggestion(mContext, null, mSuggestion); verifyZeroInteractions(mFactory.metricsFeatureProvider); } + @Test + public void dismissSuggestion_noControllerOrSuggestion_noop() { + mProvider.dismissSuggestion(mContext, null, (Suggestion) null); + mProvider.dismissSuggestion(mContext, mSuggestionControllerMixin, null); + mProvider.dismissSuggestion(mContext, null, new Suggestion.Builder("id").build()); + + verifyZeroInteractions(mFactory.metricsFeatureProvider); + verifyZeroInteractions(mSuggestionControllerMixin); + } + @Test public void getSuggestionIdentifier_samePackage_returnClassName() { final Tile suggestion = new Tile();