diff --git a/res/layout/suggestion_tile_remote_container.xml b/res/layout/suggestion_tile_remote_container.xml deleted file mode 100644 index fd19b80eac6..00000000000 --- a/res/layout/suggestion_tile_remote_container.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - diff --git a/res/xml/suggestion_ordering.xml b/res/xml/suggestion_ordering.xml deleted file mode 100644 index e21fe5b82c1..00000000000 --- a/res/xml/suggestion_ordering.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java index 4371b4a830d..55f073754aa 100644 --- a/src/com/android/settings/core/FeatureFlags.java +++ b/src/com/android/settings/core/FeatureFlags.java @@ -21,7 +21,6 @@ package com.android.settings.core; */ public class FeatureFlags { public static final String SEARCH_V2 = "settings_search_v2"; - public static final String SUGGESTIONS_V2 = "new_settings_suggestion"; public static final String APP_INFO_V2 = "settings_app_info_v2"; public static final String CONNECTED_DEVICE_V2 = "settings_connected_device_v2"; public static final String BATTERY_SETTINGS_V2 = "settings_battery_v2"; diff --git a/src/com/android/settings/core/instrumentation/MetricsFeatureProvider.java b/src/com/android/settings/core/instrumentation/MetricsFeatureProvider.java index 532ec66316f..166cbb84471 100644 --- a/src/com/android/settings/core/instrumentation/MetricsFeatureProvider.java +++ b/src/com/android/settings/core/instrumentation/MetricsFeatureProvider.java @@ -39,7 +39,6 @@ public class MetricsFeatureProvider { protected void installLogWriters() { mLoggerWriters.add(new EventLogWriter()); - mLoggerWriters.add(new SettingSuggestionsLogWriter()); } public void visible(Context context, int source, int category) { diff --git a/src/com/android/settings/core/instrumentation/SettingSuggestionsLogWriter.java b/src/com/android/settings/core/instrumentation/SettingSuggestionsLogWriter.java deleted file mode 100644 index 697f0a3c902..00000000000 --- a/src/com/android/settings/core/instrumentation/SettingSuggestionsLogWriter.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2017 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 android.util.Pair; - -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.settings.dashboard.suggestions.EventStore; - -/** - * {@link LogWriter} that writes setting suggestion related logs. - */ -public class SettingSuggestionsLogWriter implements LogWriter { - - private EventStore mEventStore; - - @Override - public void visible(Context context, int source, int category) { - } - - @Override - public void hidden(Context context, int category) { - } - - @Override - public void action(Context context, int category, Pair... taggedData) { - } - - @Override - public void actionWithSource(Context context, int source, int category) { - } - - @Override - public void action(int category, int value, Pair... taggedData) { - } - - @Override - public void action(int category, boolean value, Pair... taggedData) { - } - - @Override - public void action(Context context, int category, int value) { - } - - @Override - public void action(Context context, int category, boolean value) { - } - - @Override - public void action(Context context, int category, String pkg, - Pair... taggedData) { - if (mEventStore == null) { - mEventStore = new EventStore(context); - } - switch (category) { - case MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION: - mEventStore.writeEvent(pkg, EventStore.EVENT_SHOWN); - break; - case MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION: - mEventStore.writeEvent(pkg, EventStore.EVENT_DISMISSED); - break; - case MetricsEvent.ACTION_SETTINGS_SUGGESTION: - mEventStore.writeEvent(pkg, EventStore.EVENT_CLICKED); - break; - } - } - - @Override - public void count(Context context, String name, int value) { - } - - @Override - public void histogram(Context context, String name, int bucket) { - } - -} diff --git a/src/com/android/settings/dashboard/DashboardAdapter.java b/src/com/android/settings/dashboard/DashboardAdapter.java index 3d473f0a7ba..97eef1329d5 100644 --- a/src/com/android/settings/dashboard/DashboardAdapter.java +++ b/src/com/android/settings/dashboard/DashboardAdapter.java @@ -52,7 +52,6 @@ import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.Utils; import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.Tile; -import com.android.settingslib.suggestions.SuggestionParser; import java.util.ArrayList; import java.util.List; @@ -61,7 +60,6 @@ public class DashboardAdapter extends RecyclerView.Adapter mSuggestionsShownLogged; private boolean mFirstFrameDrawn; private RecyclerView mRecyclerView; - private SuggestionParser mSuggestionParser; private SuggestionAdapter mSuggestionAdapter; private SuggestionDismissController mSuggestionDismissHandler; private SuggestionDismissController.Callback mCallback; @@ -97,13 +92,10 @@ public class DashboardAdapter extends RecyclerView.Adapter conditions, SuggestionParser suggestionParser, - SuggestionControllerMixin suggestionControllerMixin, + List conditions, SuggestionControllerMixin suggestionControllerMixin, SuggestionDismissController.Callback callback) { - // @deprecated In favor of suggestionsV2 below. - List suggestions = null; - List suggestionsV2 = null; + List suggestions = null; DashboardCategory category = null; int suggestionConditionMode = DashboardData.HEADER_MODE_DEFAULT; @@ -113,14 +105,12 @@ public class DashboardAdapter extends RecyclerView.Adapter getSuggestions() { - return mDashboardData.getSuggestions(); - } - - /** - * @deprecated in favor of {@link #setCategory(DashboardCategory)} and - * {@link #setSuggestionsV2(List)}. - */ - @Deprecated - public void setCategoriesAndSuggestions(DashboardCategory category, List suggestions) { - tintIcons(category, suggestions); - + public void setSuggestions(List data) { final DashboardData prevData = mDashboardData; mDashboardData = new DashboardData.Builder(prevData) - .setSuggestions(suggestions.subList(0, - Math.min(suggestions.size(), MAX_SUGGESTION_TO_SHOW))) - .setCategory(category) - .build(); - notifyDashboardDataChanged(prevData); - } - - public void setSuggestionsV2(List data) { - final DashboardData prevData = mDashboardData; - mDashboardData = new DashboardData.Builder(prevData) - .setSuggestionsV2(data) + .setSuggestions(data) .build(); notifyDashboardDataChanged(prevData); } @@ -187,30 +155,8 @@ public class DashboardAdapter extends RecyclerView.Adapter suggestions = mDashboardData.getSuggestions(); - if (suggestions == null || suggestions.isEmpty()) { - return; - } - if (suggestions.size() == 1) { - // The only suggestion is dismissed, and the the empty suggestion container will - // remain as the dashboard item. Need to refresh the dashboard list. - final DashboardData prevData = mDashboardData; - mDashboardData = new DashboardData.Builder(prevData) - .setSuggestions(null) - .build(); - notifyDashboardDataChanged(prevData); - } else { - mSuggestionAdapter.removeSuggestion(suggestion); - } - } - public void onSuggestionDismissed(Suggestion suggestion) { - final List list = mDashboardData.getSuggestionsV2(); + final List list = mDashboardData.getSuggestions(); if (list == null || list.size() == 0) { return; } @@ -219,7 +165,7 @@ public class DashboardAdapter extends RecyclerView.Adapter suggestionsV2 = mDashboardData.getSuggestionsV2(); - final List suggestions = mDashboardData.getSuggestions(); + final List suggestions = mDashboardData.getSuggestions(); boolean conditionOnly = true; if (position == SUGGESTION_CONDITION_HEADER_POSITION) { - if (suggestions != null && suggestions.size() > 0) { + if (suggestions != null && suggestions.size() > 0) { conditionOnly = false; mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin, - (List) mDashboardData.getItemEntityByPosition(position), - null, mSuggestionsShownLogged); - mSuggestionDismissHandler = new SuggestionDismissController(mContext, - holder.data, mSuggestionControllerMixin, mSuggestionParser, mCallback); - holder.data.setAdapter(mSuggestionAdapter); - } else if (suggestionsV2 != null && suggestionsV2.size() > 0) { - conditionOnly = false; - mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin, - null, (List) mDashboardData.getItemEntityByPosition(position), + (List) mDashboardData.getItemEntityByPosition(position), mSuggestionsShownLogged); mSuggestionDismissHandler = new SuggestionDismissController(mContext, - holder.data, mSuggestionControllerMixin, null /* parser */, mCallback); + holder.data, mSuggestionControllerMixin, mCallback); holder.data.setAdapter(mSuggestionAdapter); } } @@ -494,14 +423,10 @@ public class DashboardAdapter extends RecyclerView.Adapter suggestions = mDashboardData.getSuggestions(); - final List suggestionV2 = mDashboardData.getSuggestionsV2(); + final List suggestions = mDashboardData.getSuggestions(); if (suggestions != null) { - outState.putParcelableArrayList(STATE_SUGGESTION_LIST, new ArrayList<>(suggestions)); - } - if (suggestionV2 != null) { - outState.putParcelableArrayList(STATE_SUGGESTION_LIST_V2, - new ArrayList<>(suggestionV2)); + outState.putParcelableArrayList(STATE_SUGGESTION_LIST, + new ArrayList<>(suggestions)); } if (category != null) { outState.putParcelable(STATE_CATEGORY_LIST, category); diff --git a/src/com/android/settings/dashboard/DashboardData.java b/src/com/android/settings/dashboard/DashboardData.java index 6407960f331..da2a526e1b5 100644 --- a/src/com/android/settings/dashboard/DashboardData.java +++ b/src/com/android/settings/dashboard/DashboardData.java @@ -69,16 +69,14 @@ public class DashboardData { private final List mItems; private final DashboardCategory mCategory; private final List mConditions; - private final List mSuggestions; - private final List mSuggestionsV2; + private final List mSuggestions; @HeaderMode private final int mSuggestionConditionMode; private DashboardData(Builder builder) { mCategory = builder.mCategory; mConditions = builder.mConditions; - mSuggestions = builder.mSuggestions; - mSuggestionsV2 = builder.mSuggestionsV2; + mSuggestions = builder.mSuggestionsV2; mSuggestionConditionMode = builder.mSuggestionConditionMode; mItems = new ArrayList<>(); @@ -123,14 +121,10 @@ public class DashboardData { return mConditions; } - public List getSuggestions() { + public List getSuggestions() { return mSuggestions; } - public List getSuggestionsV2() { - return mSuggestionsV2; - } - public int getSuggestionConditionMode() { return mSuggestionConditionMode; } @@ -197,22 +191,15 @@ public class DashboardData { * and mIsShowingAll, mSuggestionConditionMode flag. */ private void buildItemsData() { - final boolean useSuggestionV2 = mSuggestionsV2 != null; - final boolean hasSuggestions = useSuggestionV2 - ? sizeOf(mSuggestionsV2) > 0 - : sizeOf(mSuggestions) > 0; + final boolean hasSuggestions = sizeOf(mSuggestions) > 0; final List conditions = getConditionsToShow(mConditions); final boolean hasConditions = sizeOf(conditions) > 0; - final List suggestions = getSuggestionsToShow(mSuggestions); - final List suggestionsV2 = getSuggestionsV2ToShow(mSuggestionsV2); + final List suggestions = getSuggestionsToShow(mSuggestions); - final int hiddenSuggestion; - if (useSuggestionV2) { - hiddenSuggestion = hasSuggestions ? sizeOf(mSuggestionsV2) - sizeOf(suggestionsV2) : 0; - } else { - hiddenSuggestion = hasSuggestions ? sizeOf(mSuggestions) - sizeOf(suggestions) : 0; - } + final int hiddenSuggestion = hasSuggestions + ? sizeOf(mSuggestions) - sizeOf(suggestions) + : 0; final boolean hasSuggestionAndCollapsed = hasSuggestions && mSuggestionConditionMode == HEADER_MODE_COLLAPSED; @@ -231,15 +218,8 @@ public class DashboardData { R.layout.suggestion_condition_header, STABLE_ID_SUGGESTION_CONDITION_MIDDLE_HEADER, onlyHasConditionAndCollapsed); - if (useSuggestionV2) { - addToItemList(suggestionsV2, R.layout.suggestion_condition_container, - STABLE_ID_SUGGESTION_CONTAINER, sizeOf(suggestionsV2) > 0); - } else { - /* Suggestion container. This is the card view that contains the list of suggestions. - * This will be added whenever the suggestion list is not empty */ - addToItemList(suggestions, R.layout.suggestion_condition_container, - STABLE_ID_SUGGESTION_CONTAINER, sizeOf(suggestions) > 0); - } + addToItemList(suggestions, R.layout.suggestion_condition_container, + STABLE_ID_SUGGESTION_CONTAINER, sizeOf(suggestions) > 0); /* Second suggestion/condition header. This will be added when there is at least one * suggestion or condition that is not currently displayed, and the user can expand the @@ -296,22 +276,7 @@ public class DashboardData { return result; } - /** - * @deprecated in favor of {@link #getSuggestionsV2ToShow}. - */ - @Deprecated - private List getSuggestionsToShow(List suggestions) { - if (suggestions == null || mSuggestionConditionMode == HEADER_MODE_COLLAPSED) { - return null; - } - if (mSuggestionConditionMode != HEADER_MODE_DEFAULT - || suggestions.size() <= DEFAULT_SUGGESTION_COUNT) { - return suggestions; - } - return suggestions.subList(0, DEFAULT_SUGGESTION_COUNT); - } - - private List getSuggestionsV2ToShow(List suggestions) { + private List getSuggestionsToShow(List suggestions) { if (suggestions == null || mSuggestionConditionMode == HEADER_MODE_COLLAPSED) { return null; } @@ -333,11 +298,6 @@ public class DashboardData { private DashboardCategory mCategory; private List mConditions; - /** - * @deprecated in favor of SuggestionList - */ - @Deprecated - private List mSuggestions; private List mSuggestionsV2; public Builder() { @@ -346,8 +306,7 @@ public class DashboardData { public Builder(DashboardData dashboardData) { mCategory = dashboardData.mCategory; mConditions = dashboardData.mConditions; - mSuggestions = dashboardData.mSuggestions; - mSuggestionsV2 = dashboardData.mSuggestionsV2; + mSuggestionsV2 = dashboardData.mSuggestions; mSuggestionConditionMode = dashboardData.mSuggestionConditionMode; } @@ -361,16 +320,7 @@ public class DashboardData { return this; } - /** - * @deprecated in favor of {@link #setSuggestionsV2(List)})} - */ - @Deprecated - public Builder setSuggestions(List suggestions) { - this.mSuggestions = suggestions; - return this; - } - - public Builder setSuggestionsV2(List suggestions) { + public Builder setSuggestions(List suggestions) { this.mSuggestionsV2 = suggestions; return this; } diff --git a/src/com/android/settings/dashboard/DashboardSummary.java b/src/com/android/settings/dashboard/DashboardSummary.java index ff2a76aaad3..61c202e1637 100644 --- a/src/com/android/settings/dashboard/DashboardSummary.java +++ b/src/com/android/settings/dashboard/DashboardSummary.java @@ -19,7 +19,6 @@ package com.android.settings.dashboard; import android.app.Activity; import android.app.LoaderManager; import android.content.Context; -import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.service.settings.suggestions.Suggestion; @@ -41,19 +40,14 @@ import com.android.settings.dashboard.conditional.FocusRecyclerView; import com.android.settings.dashboard.conditional.FocusRecyclerView.FocusListener; 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.overlay.FeatureFactory; import com.android.settings.widget.ActionBarShadowController; import com.android.settingslib.drawer.CategoryKey; import com.android.settingslib.drawer.DashboardCategory; import com.android.settingslib.drawer.SettingsDrawerActivity; import com.android.settingslib.drawer.SettingsDrawerActivity.CategoryListener; -import com.android.settingslib.drawer.Tile; -import com.android.settingslib.suggestions.SuggestionList; -import com.android.settingslib.suggestions.SuggestionParser; import com.android.settingslib.utils.ThreadUtils; -import java.util.ArrayList; import java.util.List; public class DashboardSummary extends InstrumentedFragment @@ -73,11 +67,9 @@ public class DashboardSummary extends InstrumentedFragment private DashboardAdapter mAdapter; private SummaryLoader mSummaryLoader; private ConditionManager mConditionManager; - private SuggestionParser mSuggestionParser; private LinearLayoutManager mLayoutManager; private SuggestionControllerMixin mSuggestionControllerMixin; private DashboardFeatureProvider mDashboardFeatureProvider; - private SuggestionFeatureProvider mSuggestionFeatureProvider; private boolean isOnCategoriesChangedCalled; private boolean mOnConditionsChangedCalled; @@ -92,13 +84,9 @@ public class DashboardSummary extends InstrumentedFragment @Override public void onAttach(Context context) { super.onAttach(context); - 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()); - } + Log.d(TAG, "Creating SuggestionControllerMixin"); + mSuggestionControllerMixin = new SuggestionControllerMixin(context, this /* host */, + getLifecycle()); } @Override @@ -121,10 +109,6 @@ public class DashboardSummary extends InstrumentedFragment mConditionManager = ConditionManager.get(activity, false); getLifecycle().addObserver(mConditionManager); - if (mSuggestionFeatureProvider.isSuggestionEnabled(activity)) { - mSuggestionParser = new SuggestionParser(activity, - mSuggestionFeatureProvider.getSharedPrefs(activity), R.xml.suggestion_ordering); - } if (DEBUG_TIMING) { Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime) + " ms"); } @@ -211,8 +195,7 @@ public class DashboardSummary extends InstrumentedFragment mDashboard.setHasFixedSize(true); mDashboard.setListener(this); mAdapter = new DashboardAdapter(getContext(), bundle, mConditionManager.getConditions(), - mSuggestionParser, mSuggestionControllerMixin, - this /* SuggestionDismissController.Callback */); + mSuggestionControllerMixin, this /* SuggestionDismissController.Callback */); mDashboard.setAdapter(mAdapter); mDashboard.setItemAnimator(new DashboardItemAnimator()); mSummaryLoader.setSummaryConsumer(mAdapter); @@ -228,16 +211,7 @@ public class DashboardSummary extends InstrumentedFragment @VisibleForTesting void rebuildUI() { - if (!mSuggestionFeatureProvider.isSuggestionEnabled(getContext())) { - Log.d(TAG, "Suggestion v1 feature is disabled, skipping suggestion v1"); - ThreadUtils.postOnBackgroundThread(() -> updateCategory()); - } else { - new SuggestionLoader().execute(); - // Set categories on their own if loading suggestions takes too long. - mHandler.postDelayed(() -> { - updateCategory(); - }, MAX_WAIT_MILLIS); - } + ThreadUtils.postOnBackgroundThread(() -> updateCategory()); } @Override @@ -274,19 +248,9 @@ public class DashboardSummary extends InstrumentedFragment @Override public Suggestion getSuggestionAt(int position) { - return mAdapter.getSuggestionV2(position); - } - - @Override - public Tile getSuggestionForPosition(int position) { return mAdapter.getSuggestion(position); } - @Override - public void onSuggestionDismissed(Tile suggestion) { - mAdapter.onSuggestionDismissed(suggestion); - } - @Override public void onSuggestionDismissed(Suggestion suggestion) { mAdapter.onSuggestionDismissed(suggestion); @@ -295,7 +259,7 @@ public class DashboardSummary extends InstrumentedFragment @Override public void onSuggestionReady(List suggestions) { mStagingSuggestions = suggestions; - mAdapter.setSuggestionsV2(suggestions); + mAdapter.setSuggestions(suggestions); if (mStagingCategory != null) { Log.d(TAG, "Category has loaded, setting category from suggestionReady"); mHandler.removeCallbacksAndMessages(null); @@ -303,49 +267,6 @@ public class DashboardSummary extends InstrumentedFragment } } - /** - * @deprecated in favor of {@link #mSuggestionControllerMixin}. - */ - @Deprecated - private class SuggestionLoader extends AsyncTask> { - @Override - protected List doInBackground(Void... params) { - final Context context = getContext(); - boolean isSmartSuggestionEnabled = - mSuggestionFeatureProvider.isSmartSuggestionEnabled(context); - final SuggestionList sl = mSuggestionParser.getSuggestions(isSmartSuggestionEnabled); - final List suggestions = sl.getSuggestions(); - - if (isSmartSuggestionEnabled) { - List suggestionIds = new ArrayList<>(suggestions.size()); - for (Tile suggestion : suggestions) { - suggestionIds.add(mSuggestionFeatureProvider.getSuggestionIdentifier( - context, suggestion)); - } - // TODO: create a Suggestion class to maintain the id and other info - mSuggestionFeatureProvider.rankSuggestions(suggestions, suggestionIds); - } - for (int i = 0; i < suggestions.size(); i++) { - Tile suggestion = suggestions.get(i); - if (mSuggestionFeatureProvider.isSuggestionComplete(context, - suggestion.intent.getComponent())) { - suggestions.remove(i--); - } - } - if (sl.isExclusiveSuggestionCategory()) { - mSuggestionFeatureProvider.filterExclusiveSuggestions(suggestions); - } - return suggestions; - } - - @Override - protected void onPostExecute(List tiles) { - // tell handler that suggestions were loaded quickly enough - mHandler.removeCallbacksAndMessages(null); - updateCategoryAndSuggestion(tiles); - } - } - @WorkerThread void updateCategory() { final DashboardCategory category = mDashboardFeatureProvider.getTilesForCategory( @@ -356,7 +277,7 @@ public class DashboardSummary extends InstrumentedFragment Log.d(TAG, "Suggestion has loaded, setting suggestion/category"); ThreadUtils.postOnMainThread(() -> { if (mStagingSuggestions != null) { - mAdapter.setSuggestionsV2(mStagingSuggestions); + mAdapter.setSuggestions(mStagingSuggestions); } mAdapter.setCategory(mStagingCategory); }); @@ -365,26 +286,4 @@ public class DashboardSummary extends InstrumentedFragment mHandler.postDelayed(() -> mAdapter.setCategory(mStagingCategory), MAX_WAIT_MILLIS); } } - - /** - * @deprecated in favor of {@link #mSuggestionControllerMixin}. - */ - @Deprecated - @VisibleForTesting - void updateCategoryAndSuggestion(List suggestions) { - final Activity activity = getActivity(); - if (activity == null) { - return; - } - - final DashboardCategory category = mDashboardFeatureProvider.getTilesForCategory( - CategoryKey.CATEGORY_HOMEPAGE); - mSummaryLoader.updateSummaryToCache(category); - if (suggestions != null) { - mAdapter.setCategoriesAndSuggestions(category, suggestions); - } else { - mAdapter.setCategory(category); - } - } - } diff --git a/src/com/android/settings/dashboard/suggestions/EventStore.java b/src/com/android/settings/dashboard/suggestions/EventStore.java deleted file mode 100644 index cc3872e7ca0..00000000000 --- a/src/com/android/settings/dashboard/suggestions/EventStore.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2017 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.dashboard.suggestions; - -import android.content.Context; -import android.content.SharedPreferences; -import android.util.Log; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * Stores suggestion related statistics. - */ -public class EventStore { - - public static final String TAG = "SuggestionEventStore"; - - public static final String EVENT_SHOWN = "shown"; - public static final String EVENT_DISMISSED = "dismissed"; - public static final String EVENT_CLICKED = "clicked"; - public static final String METRIC_LAST_EVENT_TIME = "last_event_time"; - public static final String METRIC_COUNT = "count"; - - private static final Set EVENTS = new HashSet( - Arrays.asList(new String[] {EVENT_SHOWN, EVENT_DISMISSED, EVENT_CLICKED})); - private static final Set METRICS = new HashSet( - Arrays.asList(new String[] {METRIC_LAST_EVENT_TIME, METRIC_COUNT})); - - private final SharedPreferences mSharedPrefs; - - public EventStore(Context context) { - mSharedPrefs = context.getSharedPreferences(TAG, Context.MODE_PRIVATE); - } - - /** - * Writes individual log events. - * @param pkgName: Package for which this event is reported. - * @param eventType: Type of event (one of {@link #EVENTS}). - */ - public void writeEvent(String pkgName, String eventType) { - if (!EVENTS.contains(eventType)) { - Log.w(TAG, "Reported event type " + eventType + " is not a valid type!"); - return; - } - final String lastTimePrefKey = getPrefKey(pkgName, eventType, METRIC_LAST_EVENT_TIME); - final String countPrefKey = getPrefKey(pkgName, eventType, METRIC_COUNT); - writePref(lastTimePrefKey, System.currentTimeMillis()); - writePref(countPrefKey, readPref(countPrefKey, (long) 0) + 1); - } - - /** - * Reads metric of the the reported events (e.g., counts). - * @param pkgName: Package for which this metric is queried. - * @param eventType: Type of event (one of {@link #EVENTS}). - * @param metricType: Type of the queried metric (one of {@link #METRICS}). - * @return the corresponding metric. - */ - public long readMetric(String pkgName, String eventType, String metricType) { - if (!EVENTS.contains(eventType)) { - Log.w(TAG, "Reported event type " + eventType + " is not a valid event!"); - return 0; - } else if (!METRICS.contains(metricType)) { - Log.w(TAG, "Required stat type + " + metricType + " is not a valid stat!"); - return 0; - } - return readPref(getPrefKey(pkgName, eventType, metricType), (long) 0); - } - - private void writePref(String prefKey, long value) { - mSharedPrefs.edit().putLong(prefKey, value).apply(); - } - - private long readPref(String prefKey, Long defaultValue) { - return mSharedPrefs.getLong(prefKey, defaultValue); - } - - private String getPrefKey(String pkgName, String eventType, String statType) { - return new StringBuilder() - .append("setting_suggestion_") - .append(pkgName) - .append("_") - .append(eventType) - .append("_") - .append(statType) - .toString(); - } -} diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java index 293c95af9e9..fc1102901c0 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionAdapter.java @@ -27,12 +27,10 @@ import android.view.ViewGroup; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.SettingsActivity; import com.android.settings.core.instrumentation.MetricsFeatureProvider; import com.android.settings.dashboard.DashboardAdapter.DashboardItemHolder; import com.android.settings.dashboard.DashboardAdapter.IconCache; import com.android.settings.overlay.FeatureFactory; -import com.android.settingslib.drawer.Tile; import java.util.List; import java.util.Objects; @@ -42,26 +40,20 @@ public class SuggestionAdapter extends RecyclerView.Adapter private final Context mContext; private final MetricsFeatureProvider mMetricsFeatureProvider; - private final SuggestionFeatureProvider mSuggestionFeatureProvider; - @Deprecated // in favor of mSuggestionsV2 - private final List mSuggestions; - private final List mSuggestionsV2; + private final List mSuggestions; private final IconCache mCache; private final List mSuggestionsShownLogged; private final SuggestionControllerMixin mSuggestionControllerMixin; public SuggestionAdapter(Context context, SuggestionControllerMixin suggestionControllerMixin, - List suggestions, List suggestionsV2, - List suggestionsShownLogged) { + List suggestions, List suggestionsShownLogged) { mContext = context; mSuggestionControllerMixin = suggestionControllerMixin; mSuggestions = suggestions; - mSuggestionsV2 = suggestionsV2; mSuggestionsShownLogged = suggestionsShownLogged; mCache = new IconCache(context); final FeatureFactory factory = FeatureFactory.getFactory(context); mMetricsFeatureProvider = factory.getMetricsFeatureProvider(); - mSuggestionFeatureProvider = factory.getSuggestionFeatureProvider(context); setHasStableIds(true); } @@ -74,15 +66,11 @@ public class SuggestionAdapter extends RecyclerView.Adapter @Override public void onBindViewHolder(DashboardItemHolder holder, int position) { - if (mSuggestions != null) { - bindSuggestionTile(holder, position); - } else { - bindSuggestion(holder, position); - } + bindSuggestion(holder, position); } private void bindSuggestion(DashboardItemHolder holder, int position) { - final Suggestion suggestion = mSuggestionsV2.get(position); + final Suggestion suggestion = mSuggestions.get(position); final String id = suggestion.getId(); if (!mSuggestionsShownLogged.contains(id)) { mMetricsFeatureProvider.action( @@ -101,7 +89,7 @@ public class SuggestionAdapter extends RecyclerView.Adapter } final View divider = holder.itemView.findViewById(R.id.divider); if (divider != null) { - divider.setVisibility(position < mSuggestionsV2.size() - 1 ? View.VISIBLE : View.GONE); + divider.setVisibility(position < mSuggestions.size() - 1 ? View.VISIBLE : View.GONE); } View clickHandler = holder.itemView; // If a view with @android:id/primary is defined, use that as the click handler @@ -121,110 +109,32 @@ public class SuggestionAdapter extends RecyclerView.Adapter }); } - /** - * @deprecated in favor {@link #bindSuggestion(DashboardItemHolder, int)}. - */ - @Deprecated - private void bindSuggestionTile(DashboardItemHolder holder, int position) { - final Tile suggestion = (Tile) mSuggestions.get(position); - final String suggestionId = mSuggestionFeatureProvider.getSuggestionIdentifier( - mContext, suggestion); - // This is for cases when a suggestion is dismissed and the next one comes to view - if (!mSuggestionsShownLogged.contains(suggestionId)) { - mMetricsFeatureProvider.action( - mContext, MetricsEvent.ACTION_SHOW_SETTINGS_SUGGESTION, suggestionId, - mSuggestionFeatureProvider.getLoggingTaggedData(mContext)); - mSuggestionsShownLogged.add(suggestionId); - } - if (suggestion.remoteViews != null) { - final ViewGroup itemView = (ViewGroup) holder.itemView; - itemView.removeAllViews(); - itemView.addView(suggestion.remoteViews.apply(itemView.getContext(), itemView)); - } else { - holder.icon.setImageDrawable(mCache.getIcon(suggestion.icon)); - holder.title.setText(suggestion.title); - if (!TextUtils.isEmpty(suggestion.summary)) { - holder.summary.setText(suggestion.summary); - holder.summary.setVisibility(View.VISIBLE); - } else { - holder.summary.setVisibility(View.GONE); - } - } - final View divider = holder.itemView.findViewById(R.id.divider); - if (divider != null) { - divider.setVisibility(position < mSuggestions.size() - 1 ? View.VISIBLE : View.GONE); - } - View clickHandler = holder.itemView; - // If a view with @android:id/primary is defined, use that as the click handler - // instead. - final View primaryAction = holder.itemView.findViewById(android.R.id.primary); - if (primaryAction != null) { - clickHandler = primaryAction; - } - - clickHandler.setOnClickListener(v -> { - mMetricsFeatureProvider.action(mContext, - MetricsEvent.ACTION_SETTINGS_SUGGESTION, suggestionId, - mSuggestionFeatureProvider.getLoggingTaggedData(mContext)); - ((SettingsActivity) mContext).startSuggestion(suggestion.intent); - }); - } - @Override public long getItemId(int position) { - if (mSuggestions != null) { - return Objects.hash(mSuggestions.get(position).title); - } else { - return Objects.hash(mSuggestionsV2.get(position).getId()); - } + return Objects.hash(mSuggestions.get(position).getId()); } @Override public int getItemViewType(int position) { - if (mSuggestions != null) { - Tile suggestion = getSuggestion(position); - - return suggestion.remoteViews != null - ? R.layout.suggestion_tile_remote_container - : R.layout.suggestion_tile; + final Suggestion suggestion = getSuggestion(position); + if ((suggestion.getFlags() & Suggestion.FLAG_HAS_BUTTON) != 0) { + return R.layout.suggestion_tile_with_button; } else { - final Suggestion suggestion = getSuggestionsV2(position); - if ((suggestion.getFlags() & Suggestion.FLAG_HAS_BUTTON) != 0) { - return R.layout.suggestion_tile_with_button; - } else { - return R.layout.suggestion_tile; - } + return R.layout.suggestion_tile; } } @Override public int getItemCount() { - if (mSuggestions != null) { - return mSuggestions.size(); - } else { - return mSuggestionsV2.size(); - } + return mSuggestions.size(); } - public Tile getSuggestion(int position) { + public Suggestion getSuggestion(int position) { final long itemId = getItemId(position); if (mSuggestions == null) { return null; } - for (Tile tile : mSuggestions) { - if (Objects.hash(tile.title) == itemId) { - return tile; - } - } - return null; - } - - public Suggestion getSuggestionsV2(int position) { - final long itemId = getItemId(position); - if (mSuggestionsV2 == null) { - return null; - } - for (Suggestion suggestion : mSuggestionsV2) { + for (Suggestion suggestion : mSuggestions) { if (Objects.hash(suggestion.getId()) == itemId) { return suggestion; } @@ -232,13 +142,8 @@ public class SuggestionAdapter extends RecyclerView.Adapter return null; } - public void removeSuggestion(Tile suggestion) { + public void removeSuggestion(Suggestion suggestion) { mSuggestions.remove(suggestion); notifyDataSetChanged(); } - - public void removeSuggestion(Suggestion suggestion) { - mSuggestionsV2.remove(suggestion); - notifyDataSetChanged(); - } } diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionDismissController.java b/src/com/android/settings/dashboard/suggestions/SuggestionDismissController.java index f269f69eae4..de0c1299a1c 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionDismissController.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionDismissController.java @@ -23,27 +23,10 @@ import android.support.v7.widget.helper.ItemTouchHelper; import com.android.settings.R; import com.android.settings.overlay.FeatureFactory; -import com.android.settingslib.drawer.Tile; -import com.android.settingslib.suggestions.SuggestionParser; public class SuggestionDismissController extends ItemTouchHelper.SimpleCallback { public interface Callback { - - /** - * @deprecated in favor of {@link #getSuggestionAt(int)} - * Returns suggestion tile data from the callback - */ - @Deprecated - Tile getSuggestionForPosition(int position); - - /** - * @deprecated in favor of {@link #onSuggestionDismissed(Suggestion)} - * Called when a suggestion is dismissed. - */ - @Deprecated - void onSuggestionDismissed(Tile suggestion); - /** * Returns suggestion tile data from the callback */ @@ -58,20 +41,13 @@ 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. - */ - @Deprecated - private final SuggestionParser mSuggestionParser; private final Callback mCallback; public SuggestionDismissController(Context context, RecyclerView recyclerView, - SuggestionControllerMixin suggestionMixin, SuggestionParser parser, Callback callback) { + SuggestionControllerMixin suggestionMixin, Callback callback) { super(0, ItemTouchHelper.START | ItemTouchHelper.END); mSuggestionMixin = suggestionMixin; mContext = context; - mSuggestionParser = parser; mSuggestionFeatureProvider = FeatureFactory.getFactory(context) .getSuggestionFeatureProvider(context); mCallback = callback; @@ -103,13 +79,7 @@ public class SuggestionDismissController extends ItemTouchHelper.SimpleCallback } final int position = viewHolder.getAdapterPosition(); final Suggestion suggestionV2 = mCallback.getSuggestionAt(position); - if (suggestionV2 != null) { - mSuggestionFeatureProvider.dismissSuggestion(mContext, mSuggestionMixin, suggestionV2); - mCallback.onSuggestionDismissed(suggestionV2); - } else { - final Tile suggestion = mCallback.getSuggestionForPosition(position); - mSuggestionFeatureProvider.dismissSuggestion(mContext, mSuggestionParser, suggestion); - mCallback.onSuggestionDismissed(suggestion); - } + mSuggestionFeatureProvider.dismissSuggestion(mContext, mSuggestionMixin, suggestionV2); + mCallback.onSuggestionDismissed(suggestionV2); } } diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java index f9114011a0e..bdc29e71c43 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProvider.java @@ -24,7 +24,6 @@ import android.support.annotation.NonNull; import android.util.Pair; import com.android.settingslib.drawer.Tile; -import com.android.settingslib.suggestions.SuggestionParser; import java.util.List; @@ -33,14 +32,6 @@ public interface SuggestionFeatureProvider { /** * Whether or not the whole suggestion feature is enabled. - * - * @deprecated in favor of {@link #isSuggestionV2Enabled(Context)} - */ - @Deprecated - boolean isSuggestionEnabled(Context context); - - /** - * Whether or not the suggestion v2 feature is enabled. */ boolean isSuggestionV2Enabled(Context context); @@ -62,44 +53,17 @@ public interface SuggestionFeatureProvider { */ SharedPreferences getSharedPrefs(Context context); - /** - * Ranks the list of suggestions in place. - * - * @param suggestions List of suggestion Tiles - * @param suggestionIds List of suggestion ids corresponding to the suggestion tiles. - * @deprecated in favor of SettingsIntelligence - */ - @Deprecated - void rankSuggestions(final List suggestions, List suggestionIds); - /** * Only keep top few suggestions from exclusive suggestions. */ void filterExclusiveSuggestions(List suggestions); - /** - * Dismisses a suggestion. - * - * @deprecated in favor of {@link #dismissSuggestion(Context, SuggestionControllerMixin, - * Suggestion)} - */ - @Deprecated - void dismissSuggestion(Context context, SuggestionParser parser, Tile suggestion); - /** * Dismisses a suggestion. */ void dismissSuggestion(Context context, SuggestionControllerMixin suggestionMixin, Suggestion suggestion); - /** - * Returns an identifier for the suggestion - * - * @deprecated in favor or {@link Suggestion#getId()} - */ - @Deprecated - String getSuggestionIdentifier(Context context, Tile suggestion); - /** * Returns common tagged data for suggestion logging. */ diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java index 3fc2fb2953f..fe19b958c2d 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java @@ -16,19 +16,15 @@ package com.android.settings.dashboard.suggestions; -import static com.android.settings.core.FeatureFlags.SUGGESTIONS_V2; - import android.app.ActivityManager; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.SharedPreferences; -import android.content.pm.PackageManager; import android.provider.Settings.Secure; import android.service.settings.suggestions.Suggestion; import android.support.annotation.NonNull; import android.support.annotation.VisibleForTesting; -import android.util.FeatureFlagUtils; import android.util.Log; import android.util.Pair; @@ -54,7 +50,6 @@ import com.android.settings.support.NewDeviceIntroSuggestionActivity; import com.android.settings.wallpaper.WallpaperSuggestionActivity; import com.android.settings.wifi.WifiCallingSuggestionActivity; import com.android.settingslib.drawer.Tile; -import com.android.settingslib.suggestions.SuggestionParser; import java.util.List; @@ -65,23 +60,13 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider private static final String SHARED_PREF_FILENAME = "suggestions"; - private final SuggestionRanker mSuggestionRanker; private final MetricsFeatureProvider mMetricsFeatureProvider; - @Override - public boolean isSuggestionEnabled(Context context) { - final ActivityManager am = - (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); - boolean isLowRamDevice = am.isLowRamDevice(); - return !isLowRamDevice && !isV2Enabled(context); - } - @Override public boolean isSuggestionV2Enabled(Context context) { final ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); - boolean isLowRamDevice = am.isLowRamDevice(); - return !isLowRamDevice && isV2Enabled(context); + return !am.isLowRamDevice(); } @Override @@ -91,10 +76,6 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider "com.android.settings.intelligence.suggestions.SuggestionService"); } - private static boolean isV2Enabled(Context context) { - return FeatureFlagUtils.isEnabled(context, SUGGESTIONS_V2); - } - @Override public boolean isSmartSuggestionEnabled(Context context) { return false; @@ -143,17 +124,10 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider public SuggestionFeatureProviderImpl(Context context) { final Context appContext = context.getApplicationContext(); - mSuggestionRanker = new SuggestionRanker( - new SuggestionFeaturizer(new EventStore(appContext))); mMetricsFeatureProvider = FeatureFactory.getFactory(appContext) .getMetricsFeatureProvider(); } - @Override - public void rankSuggestions(final List suggestions, List suggestionIds) { - mSuggestionRanker.rankSuggestions(suggestions, suggestionIds); - } - @Override public void filterExclusiveSuggestions(List suggestions) { if (suggestions == null) { @@ -165,26 +139,6 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider } } - @Override - public void dismissSuggestion(Context context, SuggestionParser parser, Tile suggestion) { - if (parser == null || suggestion == null || context == null) { - return; - } - final Pair[] taggedData = getLoggingTaggedData(context); - - mMetricsFeatureProvider.action( - context, MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION, - getSuggestionIdentifier(context, suggestion), - taggedData); - if (!parser.dismissSuggestion(suggestion)) { - return; - } - context.getPackageManager().setComponentEnabledSetting( - suggestion.intent.getComponent(), - PackageManager.COMPONENT_ENABLED_STATE_DISABLED, - PackageManager.DONT_KILL_APP); - } - @Override public void dismissSuggestion(Context context, SuggestionControllerMixin mixin, Suggestion suggestion) { @@ -197,25 +151,10 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider mixin.dismissSuggestion(suggestion); } - @Override - public String getSuggestionIdentifier(Context context, Tile suggestion) { - if (suggestion.intent == null || suggestion.intent.getComponent() == null - || context == null) { - return "unknown_suggestion"; - } - String packageName = suggestion.intent.getComponent().getPackageName(); - if (packageName.equals(context.getPackageName())) { - // Since Settings provides several suggestions, fill in the class instead of the - // package for these. - packageName = suggestion.intent.getComponent().getClassName(); - } - return packageName; - } - @Override public Pair[] getLoggingTaggedData(Context context) { final boolean isSmartSuggestionEnabled = isSmartSuggestionEnabled(context); - return new Pair[]{Pair.create( + return new Pair[] {Pair.create( MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, isSmartSuggestionEnabled ? 1 : 0)}; } diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeaturizer.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeaturizer.java deleted file mode 100644 index 18ac50a7eff..00000000000 --- a/src/com/android/settings/dashboard/suggestions/SuggestionFeaturizer.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2017 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.dashboard.suggestions; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Creates a set of interaction features (i.e., metrics) to represent each setting suggestion. These - * features currently include normalized time from previous events (shown, dismissed and clicked) - * for any particular suggestion and also counts of these events. These features are used as signals - * to find the best ranking for suggestion items. - */ -public class SuggestionFeaturizer { - - // Key of the features used for ranking. - public static final String FEATURE_IS_SHOWN = "is_shown"; - public static final String FEATURE_IS_DISMISSED = "is_dismissed"; - public static final String FEATURE_IS_CLICKED = "is_clicked"; - public static final String FEATURE_TIME_FROM_LAST_SHOWN = "time_from_last_shown"; - public static final String FEATURE_TIME_FROM_LAST_DISMISSED = "time_from_last_dismissed"; - public static final String FEATURE_TIME_FROM_LAST_CLICKED = "time_from_last_clicked"; - public static final String FEATURE_SHOWN_COUNT = "shown_count"; - public static final String FEATURE_DISMISSED_COUNT = "dismissed_count"; - public static final String FEATURE_CLICKED_COUNT = "clicked_count"; - - // The following numbers are estimated from histograms. - public static final double TIME_NORMALIZATION_FACTOR = 2e10; - public static final double COUNT_NORMALIZATION_FACTOR = 500; - - private final EventStore mEventStore; - - /** - * Constructor - * - * @param eventStore An instance of {@code EventStore} which maintains the recorded suggestion - * events. - */ - public SuggestionFeaturizer(EventStore eventStore) { - mEventStore = eventStore; - } - - /** - * Extracts the features for each package name. - * - * @param pkgNames: List of package names for which features are queried. - * @return A Map containing the features, keyed by the package names. Each map value contains - * another map with key-value pairs of the features. - */ - public Map> featurize(List pkgNames) { - Map> features = new HashMap<>(); - Long curTimeMs = System.currentTimeMillis(); - for (String pkgName : pkgNames) { - Map featureMap = new HashMap<>(); - features.put(pkgName, featureMap); - Long lastShownTime = mEventStore - .readMetric(pkgName, EventStore.EVENT_SHOWN, EventStore.METRIC_LAST_EVENT_TIME); - Long lastDismissedTime = mEventStore.readMetric(pkgName, EventStore.EVENT_DISMISSED, - EventStore.METRIC_LAST_EVENT_TIME); - Long lastClickedTime = mEventStore.readMetric(pkgName, EventStore.EVENT_CLICKED, - EventStore.METRIC_LAST_EVENT_TIME); - featureMap.put(FEATURE_IS_SHOWN, booleanToDouble(lastShownTime > 0)); - featureMap.put(FEATURE_IS_DISMISSED, booleanToDouble(lastDismissedTime > 0)); - featureMap.put(FEATURE_IS_CLICKED, booleanToDouble(lastClickedTime > 0)); - featureMap.put(FEATURE_TIME_FROM_LAST_SHOWN, - normalizedTimeDiff(curTimeMs, lastShownTime)); - featureMap.put(FEATURE_TIME_FROM_LAST_DISMISSED, - normalizedTimeDiff(curTimeMs, lastDismissedTime)); - featureMap.put(FEATURE_TIME_FROM_LAST_CLICKED, - normalizedTimeDiff(curTimeMs, lastClickedTime)); - featureMap.put(FEATURE_SHOWN_COUNT, normalizedCount(mEventStore - .readMetric(pkgName, EventStore.EVENT_SHOWN, EventStore.METRIC_COUNT))); - featureMap.put(FEATURE_DISMISSED_COUNT, normalizedCount(mEventStore - .readMetric(pkgName, EventStore.EVENT_DISMISSED, EventStore.METRIC_COUNT))); - featureMap.put(FEATURE_CLICKED_COUNT, normalizedCount(mEventStore - .readMetric(pkgName, EventStore.EVENT_CLICKED, EventStore.METRIC_COUNT))); - } - return features; - } - - private static double booleanToDouble(boolean bool) { - return bool ? 1 : 0; - } - - private static double normalizedTimeDiff(long curTimeMs, long preTimeMs) { - return Math.min(1, (curTimeMs - preTimeMs) / TIME_NORMALIZATION_FACTOR); - } - - private static double normalizedCount(long count) { - return Math.min(1, count / COUNT_NORMALIZATION_FACTOR); - } -} diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionRanker.java b/src/com/android/settings/dashboard/suggestions/SuggestionRanker.java deleted file mode 100644 index 14c4b1548ee..00000000000 --- a/src/com/android/settings/dashboard/suggestions/SuggestionRanker.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2017 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.dashboard.suggestions; - -import com.android.settingslib.drawer.Tile; - -import android.support.annotation.VisibleForTesting; - -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class SuggestionRanker { - - private static final String TAG = "SuggestionRanker"; - - // The following coefficients form a linear model, which mixes the features to obtain a - // relevance metric for ranking the suggestion items. This model is learned with off-line data - // by training a binary classifier to detect the clicked items. The higher the obtained - // relevance metric, the higher chance of getting clicked. - private static final Map WEIGHTS = new HashMap() {{ - put(SuggestionFeaturizer.FEATURE_IS_SHOWN, 5.05140842519); - put(SuggestionFeaturizer.FEATURE_IS_DISMISSED, 2.29641455171); - put(SuggestionFeaturizer.FEATURE_IS_CLICKED, -2.98812233623); - put(SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_SHOWN, 5.02807250202); - put(SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_DISMISSED, 2.49589700842); - put(SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_CLICKED, -4.3377039948); - put(SuggestionFeaturizer.FEATURE_SHOWN_COUNT, -2.35993512546); - }}; - - private final SuggestionFeaturizer mSuggestionFeaturizer; - - private final Map relevanceMetrics; - - Comparator suggestionComparator = new Comparator() { - @Override - public int compare(Tile suggestion1, Tile suggestion2) { - return relevanceMetrics.get(suggestion1) < relevanceMetrics.get(suggestion2) ? 1 : -1; - } - }; - - public SuggestionRanker(SuggestionFeaturizer suggestionFeaturizer) { - mSuggestionFeaturizer = suggestionFeaturizer; - relevanceMetrics = new HashMap(); - } - - public void rankSuggestions(final List suggestions, List suggestionIds) { - relevanceMetrics.clear(); - Map> features = mSuggestionFeaturizer.featurize(suggestionIds); - for (int i = 0; i < suggestionIds.size(); i++) { - relevanceMetrics.put(suggestions.get(i), - getRelevanceMetric(features.get(suggestionIds.get(i)))); - } - Collections.sort(suggestions, suggestionComparator); - } - - @VisibleForTesting - double getRelevanceMetric(Map features) { - double sum = 0; - if (features == null) { - return sum; - } - for (String feature : WEIGHTS.keySet()) { - sum += WEIGHTS.get(feature) * features.get(feature); - } - return sum; - } -} diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java index e2359e354b1..f9ef424e335 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardAdapterTest.java @@ -28,13 +28,10 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.PendingIntent; -import android.content.ComponentName; import android.content.Context; -import android.content.Intent; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.drawable.Icon; -import android.os.Bundle; import android.service.settings.suggestions.Suggestion; import android.support.v7.widget.RecyclerView; import android.util.DisplayMetrics; @@ -46,7 +43,6 @@ import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.TestConfig; 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.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; @@ -94,12 +90,6 @@ public class DashboardAdapterTest { MockitoAnnotations.initMocks(this); mFactory = FakeFeatureFactory.setupForTest(); when(mFactory.dashboardFeatureProvider.shouldTintIcon()).thenReturn(true); - when(mFactory.suggestionsFeatureProvider - .getSuggestionIdentifier(any(Context.class), any(Tile.class))) - .thenAnswer(invocation -> { - final Object[] args = invocation.getArguments(); - return ((Tile) args[1]).intent.getComponent().getPackageName(); - }); when(mContext.getResources()).thenReturn(mResources); when(mResources.getQuantityString(any(int.class), any(int.class), any())) @@ -108,14 +98,14 @@ public class DashboardAdapterTest { mConditionList = new ArrayList<>(); mConditionList.add(mCondition); when(mCondition.shouldShow()).thenReturn(true); - mDashboardAdapter = new DashboardAdapter(mContext, null, mConditionList, null, null, null); + mDashboardAdapter = new DashboardAdapter(mContext, null, mConditionList, null, null); mSuggestionHeaderData = new DashboardData.SuggestionConditionHeaderData(mConditionList, 1); when(mView.getTag()).thenReturn(mCondition); } @Test public void testSuggestionsLogs_nullSuggestionsList_shouldNotCrash() { - setupSuggestions(makeSuggestions("pkg1", "pkg2", "pkg3", "pkg4", "pkg5")); + setupSuggestions(makeSuggestionsV2("pkg1", "pkg2", "pkg3", "pkg4", "pkg5")); mDashboardAdapter.onBindSuggestionConditionHeader(mSuggestionHolder, mSuggestionHeaderData); // set suggestions to null @@ -131,9 +121,9 @@ public class DashboardAdapterTest { @Test public void testSuggestionDismissed_notOnlySuggestion_updateSuggestionOnly() { final DashboardAdapter adapter = - spy(new DashboardAdapter(mContext, null, null, null, null, null)); - final List suggestions = makeSuggestions("pkg1", "pkg2", "pkg3"); - adapter.setCategoriesAndSuggestions(null /* category */, suggestions); + spy(new DashboardAdapter(mContext, null, null, null, null)); + final List suggestions = makeSuggestionsV2("pkg1", "pkg2", "pkg3"); + adapter.setSuggestions(suggestions); final RecyclerView data = mock(RecyclerView.class); when(data.getResources()).thenReturn(mResources); @@ -150,7 +140,7 @@ public class DashboardAdapterTest { final DashboardData dashboardData = adapter.mDashboardData; reset(adapter); // clear interactions tracking - final Tile suggestionToRemove = suggestions.get(1); + final Suggestion suggestionToRemove = suggestions.get(1); adapter.onSuggestionDismissed(suggestionToRemove); assertThat(adapter.mDashboardData).isEqualTo(dashboardData); @@ -166,12 +156,11 @@ public class DashboardAdapterTest { when(itemView.findViewById(R.id.data)).thenReturn(data); final DashboardAdapter.SuggestionAndConditionContainerHolder holder = new DashboardAdapter.SuggestionAndConditionContainerHolder(itemView); - final List suggestions = - makeSuggestions("pkg1", "pkg2", "pkg3", "pkg4"); + final List suggestions = makeSuggestionsV2("pkg1", "pkg2", "pkg3", "pkg4"); final DashboardAdapter adapter = spy(new DashboardAdapter(mContext, null /*savedInstance */, - null /* conditions */, null /* suggestionParser */, + null /* conditions */, null /* suggestionControllerMixin */, null /* callback */)); - adapter.setCategoriesAndSuggestions(null /* category */, suggestions); + adapter.setSuggestions(suggestions); adapter.onBindConditionAndSuggestion( holder, DashboardAdapter.SUGGESTION_CONDITION_HEADER_POSITION); // default mode, only displaying 2 suggestions @@ -180,16 +169,16 @@ public class DashboardAdapterTest { // verify operations that access the lists will not cause ConcurrentModificationException assertThat(holder.data.getAdapter().getItemCount()).isEqualTo(1); - adapter.setCategoriesAndSuggestions(null /* category */, suggestions); + adapter.setSuggestions(suggestions); // should not crash } @Test public void testSuggestionDismissed_onlySuggestion_updateDashboardData() { DashboardAdapter adapter = - spy(new DashboardAdapter(mContext, null, null, null, null, null)); - final List suggestions = makeSuggestions("pkg1"); - adapter.setCategoriesAndSuggestions(null /* category */, suggestions); + spy(new DashboardAdapter(mContext, null, null, null, null)); + final List suggestions = makeSuggestionsV2("pkg1"); + adapter.setSuggestions(suggestions); final DashboardData dashboardData = adapter.mDashboardData; reset(adapter); // clear interactions tracking @@ -199,22 +188,6 @@ public class DashboardAdapterTest { verify(adapter).notifyDashboardDataChanged(any()); } - @Test - public void testSetCategoriesAndSuggestions_iconTinted() { - TypedArray mockTypedArray = mock(TypedArray.class); - doReturn(mockTypedArray).when(mContext).obtainStyledAttributes(any(int[].class)); - doReturn(0x89000000).when(mockTypedArray).getColor(anyInt(), anyInt()); - - List packages = makeSuggestions("pkg1"); - Icon mockIcon = mock(Icon.class); - packages.get(0).isIconTintable = true; - packages.get(0).icon = mockIcon; - - mDashboardAdapter.setCategoriesAndSuggestions(null /* category */, packages); - - verify(mockIcon).setTint(eq(0x89000000)); - } - @Test public void testSetCategories_iconTinted() { TypedArray mockTypedArray = mock(TypedArray.class); @@ -233,49 +206,14 @@ public class DashboardAdapterTest { verify(mockIcon).setTint(eq(0x89000000)); } - @Test - public void testSetCategoriesAndSuggestions_limitSuggestionSize() { - List packages = - makeSuggestions("pkg1", "pkg2", "pkg3", "pkg4", "pkg5", "pkg6", "pkg7"); - mDashboardAdapter.setCategoriesAndSuggestions(null /* category */, packages); - - assertThat(mDashboardAdapter.mDashboardData.getSuggestions().size()) - .isEqualTo(DashboardAdapter.MAX_SUGGESTION_TO_SHOW); - } - - @Test - public void testBindConditionAndSuggestion_shouldSetSuggestionAdapterAndNoCrash() { - mDashboardAdapter = new DashboardAdapter(mContext, null, null, null, null, null); - final List suggestions = makeSuggestions("pkg1"); - final DashboardCategory category = new DashboardCategory(); - category.addTile(mock(Tile.class)); - - mDashboardAdapter.setCategoriesAndSuggestions(category, suggestions); - - final RecyclerView data = mock(RecyclerView.class); - when(data.getResources()).thenReturn(mResources); - when(data.getContext()).thenReturn(mContext); - when(mResources.getDisplayMetrics()).thenReturn(mock(DisplayMetrics.class)); - final View itemView = mock(View.class); - when(itemView.findViewById(R.id.data)).thenReturn(data); - final DashboardAdapter.SuggestionAndConditionContainerHolder holder = - new DashboardAdapter.SuggestionAndConditionContainerHolder(itemView); - - mDashboardAdapter.onBindConditionAndSuggestion( - holder, DashboardAdapter.SUGGESTION_CONDITION_HEADER_POSITION); - - verify(data).setAdapter(any(SuggestionAdapter.class)); - // should not crash - } - @Test public void testBindConditionAndSuggestion_v2_shouldSetSuggestionAdapterAndNoCrash() { - mDashboardAdapter = new DashboardAdapter(mContext, null, null, null, null, null); + mDashboardAdapter = new DashboardAdapter(mContext, null, null, null, null); final List suggestions = makeSuggestionsV2("pkg1"); final DashboardCategory category = new DashboardCategory(); category.addTile(mock(Tile.class)); - mDashboardAdapter.setSuggestionsV2(suggestions); + mDashboardAdapter.setSuggestions(suggestions); final RecyclerView data = mock(RecyclerView.class); when(data.getResources()).thenReturn(mResources); @@ -293,50 +231,6 @@ public class DashboardAdapterTest { // should not crash } - @Test - public void testBindConditionAndSuggestion_emptySuggestion_shouldSetConditionAdpater() { - final Bundle savedInstance = new Bundle(); - savedInstance.putInt(DashboardAdapter.STATE_SUGGESTION_CONDITION_MODE, - DashboardData.HEADER_MODE_FULLY_EXPANDED); - mDashboardAdapter = new DashboardAdapter(mContext, savedInstance, mConditionList, - null /* SuggestionParser */, null /* suggestionControllerMixin */, - null /* SuggestionDismissController.Callback */); - - final List suggestions = new ArrayList<>(); - final DashboardCategory category = new DashboardCategory(); - category.addTile(mock(Tile.class)); - mDashboardAdapter.setCategoriesAndSuggestions(category, suggestions); - - final RecyclerView data = mock(RecyclerView.class); - when(data.getResources()).thenReturn(mResources); - when(data.getContext()).thenReturn(mContext); - when(mResources.getDisplayMetrics()).thenReturn(mock(DisplayMetrics.class)); - final View itemView = mock(View.class); - when(itemView.findViewById(R.id.data)).thenReturn(data); - final DashboardAdapter.SuggestionAndConditionContainerHolder holder = - new DashboardAdapter.SuggestionAndConditionContainerHolder(itemView); - - mDashboardAdapter.onBindConditionAndSuggestion( - holder, DashboardAdapter.SUGGESTION_CONDITION_HEADER_POSITION); - - verify(data).setAdapter(any(ConditionAdapter.class)); - } - - /** - * @deprecated in favor of {@link #makeSuggestionsV2(String...)} - */ - @Deprecated - private List makeSuggestions(String... pkgNames) { - final List suggestions = new ArrayList<>(); - for (String pkgName : pkgNames) { - Tile suggestion = new Tile(); - suggestion.intent = new Intent("action"); - suggestion.intent.setComponent(new ComponentName(pkgName, "cls")); - suggestions.add(suggestion); - } - return suggestions; - } - private List makeSuggestionsV2(String... pkgNames) { final List suggestions = new ArrayList<>(); for (String pkgName : pkgNames) { @@ -348,13 +242,11 @@ public class DashboardAdapterTest { return suggestions; } - private void setupSuggestions(List suggestions) { - mDashboardAdapter.setCategoriesAndSuggestions(null /* category */, suggestions); + private void setupSuggestions(List suggestions) { final Context context = RuntimeEnvironment.application; + mDashboardAdapter.setSuggestions(suggestions); mSuggestionHolder = new DashboardAdapter.SuggestionAndConditionHeaderHolder( LayoutInflater.from(context).inflate( R.layout.suggestion_condition_header, new RelativeLayout(context), true)); } - - } diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java index 2e4ef719054..1116d7d8d47 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardDataTest.java @@ -23,10 +23,11 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import android.app.PendingIntent; +import android.service.settings.suggestions.Suggestion; import android.support.annotation.NonNull; import android.support.v7.util.DiffUtil; import android.support.v7.util.ListUpdateCallback; -import android.widget.RemoteViews; import com.android.settings.TestConfig; import com.android.settings.dashboard.conditional.AirplaneModeCondition; @@ -61,11 +62,10 @@ public class DashboardDataTest { @Mock private Tile mTestCategoryTile; @Mock - private Tile mTestSuggestion; - @Mock private Condition mTestCondition; @Mock private Condition mSecondCondition; // condition used to test insert in DiffUtil + private Suggestion mTestSuggestion; @Before public void SetUp() { @@ -74,8 +74,11 @@ public class DashboardDataTest { mDashboardCategory = new DashboardCategory(); // Build suggestions - final List suggestions = new ArrayList<>(); - mTestSuggestion.title = TEST_SUGGESTION_TITLE; + final List suggestions = new ArrayList<>(); + mTestSuggestion = new Suggestion.Builder("pkg") + .setTitle(TEST_SUGGESTION_TITLE) + .setPendingIntent(mock(PendingIntent.class)) + .build(); suggestions.add(mTestSuggestion); // Build oneItemConditions @@ -227,8 +230,7 @@ public class DashboardDataTest { final List oneItemConditions = new ArrayList<>(); when(mTestCondition.shouldShow()).thenReturn(true); oneItemConditions.add(mTestCondition); - final List suggestions = new ArrayList<>(); - mTestSuggestion.title = TEST_SUGGESTION_TITLE; + final List suggestions = new ArrayList<>(); suggestions.add(mTestSuggestion); final DashboardData oldData = new DashboardData.Builder() @@ -261,20 +263,16 @@ public class DashboardDataTest { public void testDiffUtil_typeSuggestedContainer_ResultDataNothingChanged() { //Build testResultData final List testResultData = new ArrayList<>(); - testResultData.add(new ListUpdateResult.ResultData( - ListUpdateResult.ResultData.TYPE_OPERATION_CHANGE, 0, 1)); - Tile tile = new Tile(); - tile.remoteViews = mock(RemoteViews.class); DashboardData prevData = new DashboardData.Builder() .setConditions(null) .setCategory(null) - .setSuggestions(Arrays.asList(tile)) + .setSuggestions(Arrays.asList(mTestSuggestion)) .build(); DashboardData currentData = new DashboardData.Builder() .setConditions(null) .setCategory(null) - .setSuggestions(Arrays.asList(tile)) + .setSuggestions(Arrays.asList(mTestSuggestion)) .build(); testDiffUtil(prevData, currentData, testResultData); } diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java index f3ed57c2fb1..59823ec45bf 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardSummaryTest.java @@ -16,25 +16,6 @@ package com.android.settings.dashboard; -import android.app.Activity; -import android.support.v7.widget.LinearLayoutManager; - -import com.android.settings.TestConfig; -import com.android.settings.dashboard.conditional.ConditionManager; -import com.android.settings.dashboard.conditional.FocusRecyclerView; -import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settingslib.drawer.CategoryKey; -import com.android.settingslib.drawer.DashboardCategory; -import com.android.settingslib.drawer.Tile; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.annotation.Config; -import org.robolectric.util.ReflectionHelpers; - import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doNothing; @@ -45,6 +26,27 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.Activity; +import android.content.Context; +import android.service.settings.suggestions.Suggestion; +import android.support.v7.widget.LinearLayoutManager; + +import com.android.settings.TestConfig; +import com.android.settings.dashboard.conditional.ConditionManager; +import com.android.settings.dashboard.conditional.FocusRecyclerView; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.drawer.CategoryKey; +import com.android.settingslib.drawer.DashboardCategory; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.util.ReflectionHelpers; + @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) @@ -63,11 +65,13 @@ public class DashboardSummaryTest { @Mock private SummaryLoader mSummaryLoader; + private Context mContext; private DashboardSummary mSummary; @Before public void setUp() { MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; mSummary = spy(new DashboardSummary()); ReflectionHelpers.setField(mSummary, "mAdapter", mAdapter); ReflectionHelpers.setField(mSummary, "mDashboardFeatureProvider", @@ -79,9 +83,10 @@ public class DashboardSummaryTest { } @Test - public void updateCategoryAndSuggestion_shouldGetCategoryFromFeatureProvider() { + public void updateCategory_shouldGetCategoryFromFeatureProvider() { doReturn(mock(Activity.class)).when(mSummary).getActivity(); - mSummary.updateCategoryAndSuggestion(null); + mSummary.onAttach(mContext); + mSummary.updateCategory(); verify(mSummaryLoader).updateSummaryToCache(nullable(DashboardCategory.class)); verify(mDashboardFeatureProvider).getTilesForCategory(CategoryKey.CATEGORY_HOMEPAGE); @@ -135,7 +140,7 @@ public class DashboardSummaryTest { @Test public void onSuggestionDismissed_shouldNotRebuildUI() { - mSummary.onSuggestionDismissed(mock(Tile.class)); + mSummary.onSuggestionDismissed(mock(Suggestion.class)); verify(mSummary, never()).rebuildUI(); } } \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/EventStoreTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/EventStoreTest.java deleted file mode 100644 index 114ee2b0cfb..00000000000 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/EventStoreTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2017 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.dashboard.suggestions; - -import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settings.TestConfig; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; - -import static com.google.common.truth.Truth.assertThat; - -import org.robolectric.RuntimeEnvironment; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class EventStoreTest { - - private EventStore mEventStore; - - @Before - public void setUp() { - mEventStore = new EventStore(RuntimeEnvironment.application); - } - - @Test - public void testWriteRead() { - mEventStore.writeEvent("pkg", EventStore.EVENT_SHOWN); - long timeMs = System.currentTimeMillis(); - assertThat(mEventStore.readMetric("pkg", EventStore.EVENT_SHOWN, EventStore.METRIC_COUNT)) - .isEqualTo(1); - assertThat(Math.abs(timeMs - mEventStore - .readMetric("pkg", EventStore.EVENT_SHOWN, EventStore.METRIC_LAST_EVENT_TIME)) < 10000) - .isTrue(); - } - - @Test - public void testWriteRead_shouldHaveLatestValues() { - mEventStore.writeEvent("pkg", EventStore.EVENT_DISMISSED); - mEventStore.writeEvent("pkg", EventStore.EVENT_DISMISSED); - assertThat( - mEventStore.readMetric("pkg", EventStore.EVENT_DISMISSED, EventStore.METRIC_COUNT)) - .isEqualTo(2); - } - - @Test - public void testWriteRead_shouldReturnDefaultIfNotAvailable() { - assertThat(mEventStore.readMetric("pkg", EventStore.EVENT_SHOWN, EventStore.METRIC_COUNT)) - .isEqualTo(0); - assertThat( - mEventStore - .readMetric("pkg", EventStore.EVENT_SHOWN, EventStore.METRIC_LAST_EVENT_TIME)) - .isEqualTo(0); - } - -} diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java index 030fb6d2b08..26940d6c24a 100644 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionAdapterTest.java @@ -16,28 +16,18 @@ package com.android.settings.dashboard.suggestions; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.app.PendingIntent; -import android.content.ComponentName; import android.content.Context; -import android.content.Intent; import android.graphics.drawable.Icon; import android.service.settings.suggestions.Suggestion; -import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; import android.widget.FrameLayout; import android.widget.LinearLayout; -import android.widget.RemoteViews; -import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; @@ -56,7 +46,6 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowApplication; import java.util.ArrayList; import java.util.List; @@ -111,37 +100,18 @@ public class SuggestionAdapterTest { @Test public void getItemCount_shouldReturnListSize() { mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin, - mOneSuggestion, null /* suggestionV2 */, new ArrayList<>()); + mOneSuggestionV2, new ArrayList<>()); assertThat(mSuggestionAdapter.getItemCount()).isEqualTo(1); mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin, - mTwoSuggestions, null /* suggestionV2 */, new ArrayList<>()); - assertThat(mSuggestionAdapter.getItemCount()).isEqualTo(2); - } - - @Test - public void getItemCount_v2_shouldReturnListSize() { - mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin, - null /* suggestions */, mOneSuggestionV2, new ArrayList<>()); - assertThat(mSuggestionAdapter.getItemCount()).isEqualTo(1); - - mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin, - null /* suggestions */, mTwoSuggestionsV2, new ArrayList<>()); + mTwoSuggestionsV2, new ArrayList<>()); assertThat(mSuggestionAdapter.getItemCount()).isEqualTo(2); } @Test public void getItemViewType_shouldReturnSuggestionTile() { mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin, - mOneSuggestion, null /* suggestionV2 */, new ArrayList<>()); - assertThat(mSuggestionAdapter.getItemViewType(0)) - .isEqualTo(R.layout.suggestion_tile); - } - - @Test - public void getItemViewType_v2_shouldReturnSuggestionTile() { - mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin, - null /* suggestions */, mOneSuggestionV2, new ArrayList<>()); + mOneSuggestionV2, new ArrayList<>()); assertThat(mSuggestionAdapter.getItemViewType(0)) .isEqualTo(R.layout.suggestion_tile); } @@ -155,32 +125,19 @@ public class SuggestionAdapterTest { .setSummary("456") .build()); mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin, - null /* suggestions */, suggestions, new ArrayList<>()); + suggestions, new ArrayList<>()); assertThat(mSuggestionAdapter.getItemViewType(0)) .isEqualTo(R.layout.suggestion_tile_with_button); } - @Test - public void onBindViewHolder_shouldSetListener() { - final View view = spy(LayoutInflater.from(mContext).inflate( - R.layout.suggestion_tile, new LinearLayout(mContext), true)); - mSuggestionHolder = new DashboardAdapter.DashboardItemHolder(view); - mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin, - mOneSuggestion, null /* suggestionV2 */, new ArrayList<>()); - - mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0); - - verify(view).setOnClickListener(any(View.OnClickListener.class)); - } - @Test public void onBindViewHolder_shouldLog() { final View view = spy(LayoutInflater.from(mContext).inflate( R.layout.suggestion_tile, new LinearLayout(mContext), true)); mSuggestionHolder = new DashboardAdapter.DashboardItemHolder(view); mSuggestionAdapter = new SuggestionAdapter(mContext, mSuggestionControllerMixin, - null /* suggestionV1*/, mOneSuggestionV2, new ArrayList<>()); + mOneSuggestionV2, new ArrayList<>()); // Bind twice mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0); @@ -193,53 +150,10 @@ public class SuggestionAdapterTest { } @Test - public void onBindViewHolder_shouldInflateRemoteView() { - List packages = makeSuggestions("pkg1"); - RemoteViews remoteViews = mock(RemoteViews.class); - TextView textView = new TextView(RuntimeEnvironment.application); - doReturn(textView).when(remoteViews).apply(any(Context.class), any(ViewGroup.class)); - packages.get(0).remoteViews = remoteViews; - setupSuggestions(mActivity, packages, null); - - mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0); - - assertThat(textView.getParent()).isSameAs(mSuggestionHolder.itemView); - mSuggestionHolder.itemView.performClick(); - - verify(mActivity).startSuggestion(any(Intent.class)); - } - - @Test - public void onBindViewHolder_primaryViewShouldHandleClick() { - Context context = - new ContextThemeWrapper(RuntimeEnvironment.application, R.style.Theme_Settings); - - List packages = makeSuggestions("pkg1"); - RemoteViews remoteViews = mock(RemoteViews.class); - FrameLayout layout = new FrameLayout(context); - Button primary = new Button(context); - primary.setId(android.R.id.primary); - layout.addView(primary); - doReturn(layout).when(remoteViews).apply(any(Context.class), any(ViewGroup.class)); - packages.get(0).remoteViews = remoteViews; - setupSuggestions(mActivity, packages, null /* suggestionV2 */); - - mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0); - mSuggestionHolder.itemView.performClick(); - - assertThat(ShadowApplication.getInstance().getNextStartedActivity()).isNull(); - verify(mActivity, never()).startSuggestion(any(Intent.class)); - - primary.performClick(); - - verify(mActivity).startSuggestion(any(Intent.class)); - } - - @Test - public void onBindViewHolder_v2_itemViewShouldHandleClick() + public void onBindViewHolder_itemViewShouldHandleClick() throws PendingIntent.CanceledException { final List suggestions = makeSuggestionsV2("pkg1"); - setupSuggestions(mActivity, null /* suggestionV1 */, suggestions); + setupSuggestions(mActivity, suggestions); mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0); mSuggestionHolder.itemView.performClick(); @@ -249,64 +163,21 @@ public class SuggestionAdapterTest { } @Test - public void onBindViewHolder_viewsShouldClearOnRebind() { - Context context = - new ContextThemeWrapper(RuntimeEnvironment.application, R.style.Theme_Settings); - - List packages = makeSuggestions("pkg1"); - RemoteViews remoteViews = mock(RemoteViews.class); - FrameLayout layout = new FrameLayout(context); - Button primary = new Button(context); - primary.setId(android.R.id.primary); - layout.addView(primary); - doReturn(layout).when(remoteViews).apply(any(Context.class), any(ViewGroup.class)); - packages.get(0).remoteViews = remoteViews; - setupSuggestions(mActivity, packages, null /* suggestionV2 */); - - mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0); - mSuggestionAdapter.onBindViewHolder(mSuggestionHolder, 0); - - ViewGroup itemView = (ViewGroup) mSuggestionHolder.itemView; - assertThat(itemView.getChildCount()).isEqualTo(1); - } - - @Test - public void getSuggestionsV2_shouldReturnSuggestionWhenMatch() { + public void getSuggestions_shouldReturnSuggestionWhenMatch() { final List suggestionsV2 = makeSuggestionsV2("pkg1"); - setupSuggestions(mActivity, null /* suggestionV1 */, suggestionsV2); + setupSuggestions(mActivity, suggestionsV2); - assertThat(mSuggestionAdapter.getSuggestion(0)).isNull(); - assertThat(mSuggestionAdapter.getSuggestionsV2(0)).isNotNull(); - - List suggestionsV1 = makeSuggestions("pkg1"); - setupSuggestions(mActivity, suggestionsV1, null /* suggestionV2 */); - - assertThat(mSuggestionAdapter.getSuggestionsV2(0)).isNull(); assertThat(mSuggestionAdapter.getSuggestion(0)).isNotNull(); - } - private void setupSuggestions(Context context, List suggestions, - List suggestionsV2) { + private void setupSuggestions(Context context, List suggestionsV2) { mSuggestionAdapter = new SuggestionAdapter(context, mSuggestionControllerMixin, - suggestions, suggestionsV2, new ArrayList<>()); + suggestionsV2, new ArrayList<>()); mSuggestionHolder = mSuggestionAdapter.onCreateViewHolder( new FrameLayout(RuntimeEnvironment.application), mSuggestionAdapter.getItemViewType(0)); } - private List makeSuggestions(String... pkgNames) { - final List suggestions = new ArrayList<>(); - for (String pkgName : pkgNames) { - Tile suggestion = new Tile(); - suggestion.intent = new Intent("action"); - suggestion.intent.setComponent(new ComponentName(pkgName, "cls")); - suggestions.add(suggestion); - suggestion.icon = mock(Icon.class); - } - return suggestions; - } - private List makeSuggestionsV2(String... pkgNames) { final List suggestions = new ArrayList<>(); for (String pkgName : pkgNames) { 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 329518addbd..a437cb49eb6 100644 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionDismissControllerTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionDismissControllerTest.java @@ -33,8 +33,6 @@ import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settingslib.drawer.Tile; -import com.android.settingslib.suggestions.SuggestionParser; import org.junit.Before; import org.junit.Test; @@ -53,8 +51,6 @@ public class SuggestionDismissControllerTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private RecyclerView mRecyclerView; @Mock - private SuggestionParser mSuggestionParser; - @Mock private SuggestionControllerMixin mSuggestionControllerMixin; @Mock private SuggestionDismissController.Callback mCallback; @@ -70,7 +66,7 @@ public class SuggestionDismissControllerTest { when(mRecyclerView.getResources().getDimension(anyInt())).thenReturn(50F); mController = new SuggestionDismissController(mContext, mRecyclerView, - mSuggestionControllerMixin, mSuggestionParser, mCallback); + mSuggestionControllerMixin, mCallback); } @Test @@ -108,17 +104,6 @@ public class SuggestionDismissControllerTest { @Test public void onSwiped_shouldTriggerDismissSuggestion() { final RecyclerView.ViewHolder vh = mock(RecyclerView.ViewHolder.class); - - mController.onSwiped(vh, ItemTouchHelper.START); - - verify(mFactory.suggestionsFeatureProvider).dismissSuggestion( - 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()); 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 49fbf889577..8ed885f0787 100644 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImplTest.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; 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; @@ -30,34 +29,27 @@ import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; -import android.content.Intent; 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; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.Settings.NightDisplaySuggestionActivity; import com.android.settings.TestConfig; -import com.android.settings.core.FeatureFlags; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResources; -import com.android.settings.testutils.shadow.SettingsShadowSystemProperties; import com.android.settings.testutils.shadow.ShadowSecureSettings; import com.android.settingslib.drawer.Tile; -import com.android.settingslib.suggestions.SuggestionParser; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; @@ -71,26 +63,21 @@ import java.util.List; @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, shadows = { ShadowSecureSettings.class, SettingsShadowResources.class, - SettingsShadowSystemProperties.class }) public class SuggestionFeatureProviderImplTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext; @Mock - private SuggestionParser mSuggestionParser; - @Mock private SuggestionControllerMixin mSuggestionControllerMixin; @Mock - private Tile mSuggestion; + private Suggestion mSuggestion; @Mock private ActivityManager mActivityManager; @Mock private PackageManager mPackageManager; @Mock private FingerprintManager mFingerprintManager; - @Captor - private ArgumentCaptor mTaggedDataCaptor = ArgumentCaptor.forClass(Pair.class); private FakeFeatureFactory mFactory; private SuggestionFeatureProviderImpl mProvider; @@ -103,20 +90,17 @@ public class SuggestionFeatureProviderImplTest { // Explicit casting to object due to MockitoCast bug when((Object) mContext.getSystemService(FingerprintManager.class)) .thenReturn(mFingerprintManager); + when(mSuggestion.getId()).thenReturn("test_id"); when(mContext.getApplicationContext()).thenReturn(RuntimeEnvironment.application); when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn(mActivityManager); when(mActivityManager.isLowRamDevice()).thenReturn(false); - mSuggestion.intent = new Intent().setClassName("pkg", "cls"); - mSuggestion.category = "category"; - mProvider = new SuggestionFeatureProviderImpl(mContext); } @After public void tearDown() { SettingsShadowResources.reset(); - SettingsShadowSystemProperties.clear(); } @Test @@ -129,29 +113,18 @@ public class SuggestionFeatureProviderImplTest { public void isSuggestionEnabled_isLowMemoryDevice_shouldReturnFalse() { when(mActivityManager.isLowRamDevice()).thenReturn(true); - assertThat(mProvider.isSuggestionEnabled(mContext)).isFalse(); + assertThat(mProvider.isSuggestionV2Enabled(mContext)).isFalse(); } @Test - public void isSuggestionV2Enabled_isNotLowMemoryDevice_sysPropOn_shouldReturnTrue() { + public void isSuggestionV2Enabled_isNotLowMemoryDevice_shouldReturnTrue() { when(mActivityManager.isLowRamDevice()).thenReturn(false); - SettingsShadowSystemProperties.set( - FeatureFlagUtils.FFLAG_PREFIX + FeatureFlags.SUGGESTIONS_V2, "true"); assertThat(mProvider.isSuggestionV2Enabled(mContext)).isTrue(); } - @Test - public void dismissSuggestion_noParserOrSuggestion_noop() { - 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, null, null); mProvider.dismissSuggestion(mContext, mSuggestionControllerMixin, null); mProvider.dismissSuggestion(mContext, null, new Suggestion.Builder("id").build()); @@ -159,82 +132,22 @@ public class SuggestionFeatureProviderImplTest { verifyZeroInteractions(mSuggestionControllerMixin); } - @Test - public void getSuggestionIdentifier_samePackage_returnClassName() { - final Tile suggestion = new Tile(); - suggestion.intent = new Intent() - .setClassName(RuntimeEnvironment.application.getPackageName(), "123"); - assertThat(mProvider.getSuggestionIdentifier(RuntimeEnvironment.application, suggestion)) - .isEqualTo("123"); - } - - @Test - public void getSuggestionIdentifier_differentPackage_returnPackageName() { - final Tile suggestion = new Tile(); - suggestion.intent = new Intent() - .setClassName(RuntimeEnvironment.application.getPackageName(), "123"); - assertThat(mProvider.getSuggestionIdentifier(mContext, suggestion)) - .isEqualTo(RuntimeEnvironment.application.getPackageName()); - } - - @Test - public void getSuggestionIdentifier_nullComponent_shouldNotCrash() { - final Tile suggestion = new Tile(); - suggestion.intent = new Intent(); - assertThat(mProvider.getSuggestionIdentifier(mContext, suggestion)) - .isNotEmpty(); - } - - @Test - public void getSuggestionIdentifier_nullContext_shouldNotCrash() { - final Tile suggestion = new Tile(); - suggestion.intent = new Intent() - .setClassName(RuntimeEnvironment.application.getPackageName(), "123"); - assertThat(mProvider.getSuggestionIdentifier(null, suggestion)) - .isNotEmpty(); - } - - @Test - public void dismissSuggestion_hasMoreDismissCount_shouldNotDisableComponent() { - when(mSuggestionParser.dismissSuggestion(any(Tile.class))) - .thenReturn(false); - mProvider.dismissSuggestion(mContext, mSuggestionParser, mSuggestion); - - verify(mFactory.metricsFeatureProvider).action( - eq(mContext), - eq(MetricsProto.MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION), - anyString(), - mTaggedDataCaptor.capture()); - assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( - Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); - verify(mContext, never()).getPackageManager(); - } - @Test public void dismissSuggestion_noContext_shouldDoNothing() { - mProvider.dismissSuggestion(null, mSuggestionParser, mSuggestion); + mProvider.dismissSuggestion(null, mSuggestionControllerMixin, mSuggestion); verifyZeroInteractions(mFactory.metricsFeatureProvider); } @Test - public void dismissSuggestion_hasNoMoreDismissCount_shouldDisableComponent() { - when(mSuggestionParser.dismissSuggestion(any(Tile.class))) - .thenReturn(true); - - mProvider.dismissSuggestion(mContext, mSuggestionParser, mSuggestion); + public void dismissSuggestion_shouldLogAndDismiss() { + mProvider.dismissSuggestion(mContext, mSuggestionControllerMixin, mSuggestion); verify(mFactory.metricsFeatureProvider).action( eq(mContext), eq(MetricsProto.MetricsEvent.ACTION_SETTINGS_DISMISS_SUGGESTION), - anyString(), - mTaggedDataCaptor.capture()); - assertThat(mTaggedDataCaptor.getAllValues()).containsExactly( - Pair.create(MetricsEvent.FIELD_SETTINGS_SMART_SUGGESTIONS_ENABLED, 0)); - verify(mContext.getPackageManager()) - .setComponentEnabledSetting(mSuggestion.intent.getComponent(), - PackageManager.COMPONENT_ENABLED_STATE_DISABLED, - PackageManager.DONT_KILL_APP); + anyString()); + verify(mSuggestionControllerMixin).dismissSuggestion(mSuggestion); } @Test diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeaturizerTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeaturizerTest.java deleted file mode 100644 index 4d6a7435310..00000000000 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionFeaturizerTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2017 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.dashboard.suggestions; - -import java.util.Arrays; -import java.util.Map; - -import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settings.TestConfig; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; - -import static com.google.common.truth.Truth.assertThat; - -import org.robolectric.RuntimeEnvironment; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class SuggestionFeaturizerTest { - - private EventStore mEventStore; - private SuggestionFeaturizer mSuggestionFeaturizer; - - @Before - public void setUp() { - mEventStore = new EventStore(RuntimeEnvironment.application); - mSuggestionFeaturizer = new SuggestionFeaturizer(mEventStore); - } - - @Test - public void testFeaturize_singlePackage() { - mEventStore.writeEvent("pkg", EventStore.EVENT_DISMISSED); - mEventStore.writeEvent("pkg", EventStore.EVENT_SHOWN); - mEventStore.writeEvent("pkg", EventStore.EVENT_SHOWN); - Map features = mSuggestionFeaturizer.featurize(Arrays.asList("pkg")) - .get("pkg"); - assertThat(features.get(SuggestionFeaturizer.FEATURE_IS_SHOWN)).isEqualTo(1.0); - assertThat(features.get(SuggestionFeaturizer.FEATURE_IS_DISMISSED)).isEqualTo(1.0); - assertThat(features.get(SuggestionFeaturizer.FEATURE_IS_CLICKED)).isEqualTo(0.0); - - assertThat(features.get(SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_SHOWN)).isLessThan(1.0); - assertThat(features.get(SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_DISMISSED)) - .isLessThan(1.0); - assertThat(features.get(SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_CLICKED)) - .isEqualTo(1.0); - assertThat(features.get(SuggestionFeaturizer.FEATURE_SHOWN_COUNT)) - .isEqualTo(2.0 / SuggestionFeaturizer.COUNT_NORMALIZATION_FACTOR); - assertThat(features.get(SuggestionFeaturizer.FEATURE_DISMISSED_COUNT)) - .isEqualTo(1.0 / SuggestionFeaturizer.COUNT_NORMALIZATION_FACTOR); - assertThat(features.get(SuggestionFeaturizer.FEATURE_CLICKED_COUNT)).isEqualTo(0.0); - } - - @Test - public void testFeaturize_multiplePackages() { - mEventStore.writeEvent("pkg1", EventStore.EVENT_DISMISSED); - mEventStore.writeEvent("pkg2", EventStore.EVENT_SHOWN); - mEventStore.writeEvent("pkg1", EventStore.EVENT_SHOWN); - Map> features = mSuggestionFeaturizer - .featurize(Arrays.asList("pkg1", "pkg2")); - Map features1 = features.get("pkg1"); - Map features2 = features.get("pkg2"); - - assertThat(features1.get(SuggestionFeaturizer.FEATURE_IS_SHOWN)).isEqualTo(1.0); - assertThat(features1.get(SuggestionFeaturizer.FEATURE_IS_DISMISSED)).isEqualTo(1.0); - assertThat(features1.get(SuggestionFeaturizer.FEATURE_IS_CLICKED)).isEqualTo(0.0); - assertThat(features1.get(SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_SHOWN)) - .isLessThan(1.0); - assertThat(features1.get(SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_DISMISSED)) - .isLessThan(1.0); - assertThat(features1.get(SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_CLICKED)) - .isEqualTo(1.0); - assertThat(features1.get(SuggestionFeaturizer.FEATURE_SHOWN_COUNT)) - .isEqualTo(1.0 / SuggestionFeaturizer.COUNT_NORMALIZATION_FACTOR); - assertThat(features1.get(SuggestionFeaturizer.FEATURE_DISMISSED_COUNT)) - .isEqualTo(1.0 / SuggestionFeaturizer.COUNT_NORMALIZATION_FACTOR); - assertThat(features1.get(SuggestionFeaturizer.FEATURE_CLICKED_COUNT)).isEqualTo(0.0); - - assertThat(features2.get(SuggestionFeaturizer.FEATURE_IS_SHOWN)).isEqualTo(1.0); - assertThat(features2.get(SuggestionFeaturizer.FEATURE_IS_DISMISSED)).isEqualTo(0.0); - assertThat(features2.get(SuggestionFeaturizer.FEATURE_IS_CLICKED)).isEqualTo(0.0); - assertThat(features2.get(SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_SHOWN)) - .isLessThan(1.0); - assertThat(features2.get(SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_DISMISSED)) - .isEqualTo(1.0); - assertThat(features2.get(SuggestionFeaturizer.FEATURE_TIME_FROM_LAST_CLICKED)) - .isEqualTo(1.0); - assertThat(features2.get(SuggestionFeaturizer.FEATURE_SHOWN_COUNT)) - .isEqualTo(1.0 / SuggestionFeaturizer.COUNT_NORMALIZATION_FACTOR); - assertThat(features2.get(SuggestionFeaturizer.FEATURE_DISMISSED_COUNT)).isEqualTo(0.0); - assertThat(features2.get(SuggestionFeaturizer.FEATURE_CLICKED_COUNT)).isEqualTo(0.0); - } -} diff --git a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionRankerTest.java b/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionRankerTest.java deleted file mode 100644 index 1f32531713f..00000000000 --- a/tests/robotests/src/com/android/settings/dashboard/suggestions/SuggestionRankerTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2017 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.dashboard.suggestions; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settings.TestConfig; -import com.android.settingslib.drawer.Tile; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.annotation.Config; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.same; -import static org.mockito.Mockito.spy; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class SuggestionRankerTest { - - @Mock - private SuggestionRanker mSuggestionRanker; - @Mock - private SuggestionFeaturizer mSuggestionFeaturizer; - private Map> mFeatures; - private List mPkgNames; - private List mSuggestions; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mPkgNames = Arrays.asList("pkg1", "pkg2", "pkg3"); - mFeatures = new HashMap>(); - mFeatures.put("pkg1", new HashMap()); - mFeatures.put("pkg2", new HashMap()); - mFeatures.put("pkg3", new HashMap()); - mSuggestions = new ArrayList() { - { - add(new Tile()); - add(new Tile()); - add(new Tile()); - } - }; - mSuggestionFeaturizer = mock(SuggestionFeaturizer.class); - mSuggestionRanker = new SuggestionRanker(mSuggestionFeaturizer); - when(mSuggestionFeaturizer.featurize(mPkgNames)).thenReturn(mFeatures); - mSuggestionRanker = spy(mSuggestionRanker); - when(mSuggestionRanker.getRelevanceMetric(same(mFeatures.get("pkg1")))).thenReturn(0.9); - when(mSuggestionRanker.getRelevanceMetric(same(mFeatures.get("pkg2")))).thenReturn(0.1); - when(mSuggestionRanker.getRelevanceMetric(same(mFeatures.get("pkg3")))).thenReturn(0.5); - } - - @Test - public void testRank() { - List expectedOrderdList = new ArrayList() { - { - add(mSuggestions.get(0)); // relevance = 0.9 - add(mSuggestions.get(2)); // relevance = 0.5 - add(mSuggestions.get(1)); // relevance = 0.1 - } - }; - mSuggestionRanker.rankSuggestions(mSuggestions, mPkgNames); - assertThat(mSuggestions).isEqualTo(expectedOrderdList); - } -} -