Add exclusive attribute to suggestion category
Add exlusive attribute to suggestion category XML, which when true, will prevent all other categories from being shown in suggestions. If there are multiple suggestions in a single exclusive category, all of them will be shown. If there are mutliple exclusive categories with enabled suggestions, only the first will be shown. Test: cd tests/robotests && mma Bug: 35668836 Change-Id: I8b95cdcd021a2d67d460259b4a44ca37290ffd48
This commit is contained in:
@@ -106,11 +106,11 @@ public class SuggestionParser {
|
||||
|
||||
public SuggestionParser(
|
||||
Context context, SharedPreferences sharedPrefs, int orderXml, String smartDismissControl) {
|
||||
mContext = context;
|
||||
mSuggestionList = (List<SuggestionCategory>) new SuggestionOrderInflater(mContext)
|
||||
.parse(orderXml);
|
||||
mSharedPrefs = sharedPrefs;
|
||||
mSmartDismissControl = smartDismissControl;
|
||||
this(
|
||||
context,
|
||||
sharedPrefs,
|
||||
(List<SuggestionCategory>) new SuggestionOrderInflater(context).parse(orderXml),
|
||||
smartDismissControl);
|
||||
}
|
||||
|
||||
public SuggestionParser(Context context, SharedPreferences sharedPrefs, int orderXml) {
|
||||
@@ -118,12 +118,15 @@ public class SuggestionParser {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public SuggestionParser(Context context, SharedPreferences sharedPrefs) {
|
||||
public SuggestionParser(
|
||||
Context context,
|
||||
SharedPreferences sharedPrefs,
|
||||
List<SuggestionCategory> suggestionList,
|
||||
String smartDismissControl) {
|
||||
mContext = context;
|
||||
mSuggestionList = new ArrayList<SuggestionCategory>();
|
||||
mSuggestionList = suggestionList;
|
||||
mSharedPrefs = sharedPrefs;
|
||||
mSmartDismissControl = DEFAULT_SMART_DISMISS_CONTROL;
|
||||
Log.wtf(TAG, "Only use this constructor for testing");
|
||||
mSmartDismissControl = smartDismissControl;
|
||||
}
|
||||
|
||||
public List<Tile> getSuggestions() {
|
||||
@@ -134,7 +137,19 @@ public class SuggestionParser {
|
||||
List<Tile> suggestions = new ArrayList<>();
|
||||
final int N = mSuggestionList.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
readSuggestions(mSuggestionList.get(i), suggestions, isSmartSuggestionEnabled);
|
||||
final SuggestionCategory category = mSuggestionList.get(i);
|
||||
if (category.exclusive) {
|
||||
// If suggestions from an exclusive category are present, parsing is stopped
|
||||
// and only suggestions from that category are displayed. Note that subsequent
|
||||
// exclusive categories are also ignored.
|
||||
List<Tile> exclusiveSuggestions = new ArrayList<>();
|
||||
readSuggestions(category, exclusiveSuggestions, isSmartSuggestionEnabled);
|
||||
if (!exclusiveSuggestions.isEmpty()) {
|
||||
return exclusiveSuggestions;
|
||||
}
|
||||
} else {
|
||||
readSuggestions(category, suggestions, isSmartSuggestionEnabled);
|
||||
}
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
@@ -368,6 +383,7 @@ public class SuggestionParser {
|
||||
public String category;
|
||||
public String pkg;
|
||||
public boolean multiple;
|
||||
public boolean exclusive;
|
||||
}
|
||||
|
||||
private static class SuggestionOrderInflater {
|
||||
@@ -377,6 +393,7 @@ public class SuggestionParser {
|
||||
private static final String ATTR_CATEGORY = "category";
|
||||
private static final String ATTR_PACKAGE = "package";
|
||||
private static final String ATTR_MULTIPLE = "multiple";
|
||||
private static final String ATTR_EXCLUSIVE = "exclusive";
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
@@ -451,6 +468,9 @@ public class SuggestionParser {
|
||||
category.pkg = attrs.getAttributeValue(null, ATTR_PACKAGE);
|
||||
String multiple = attrs.getAttributeValue(null, ATTR_MULTIPLE);
|
||||
category.multiple = !TextUtils.isEmpty(multiple) && Boolean.parseBoolean(multiple);
|
||||
String exclusive = attrs.getAttributeValue(null, ATTR_EXCLUSIVE);
|
||||
category.exclusive =
|
||||
!TextUtils.isEmpty(exclusive) && Boolean.parseBoolean(exclusive);
|
||||
return category;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown item " + name);
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
-->
|
||||
|
||||
<optional-steps>
|
||||
<step category="com.android.settings.suggested.category.DEFERRED_SETUP"
|
||||
exclusive="true" />
|
||||
<step category="com.android.settings.suggested.category.LOCK_SCREEN" />
|
||||
<step category="com.android.settings.suggested.category.EMAIL" />
|
||||
<step category="com.android.settings.suggested.category.PARTNER_ACCOUNT"
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
|
||||
package com.android.settingslib;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
@@ -31,59 +32,59 @@ import com.android.settingslib.drawer.TileUtilsTest;
|
||||
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.res.ResourceLoader;
|
||||
import org.robolectric.res.builder.DefaultPackageManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(SettingLibRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
public class SuggestionParserTest {
|
||||
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
private Context mContext;
|
||||
private SuggestionParser mSuggestionParser;
|
||||
private SuggestionParser.SuggestionCategory mSuggestioCategory;
|
||||
private SuggestionParser.SuggestionCategory mMultipleCategory;
|
||||
private SuggestionParser.SuggestionCategory mExclusiveCategory;
|
||||
private List<Tile> mSuggestionsBeforeDismiss;
|
||||
private List<Tile> mSuggestionsAfterDismiss;
|
||||
private SharedPreferences mPrefs;
|
||||
private Tile mSuggestion;
|
||||
private List<ResolveInfo> mInfo;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||
RuntimeEnvironment.setRobolectricPackageManager(
|
||||
new TestPackageManager(RuntimeEnvironment.getAppResourceLoader()));
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
mSuggestion = new Tile();
|
||||
mSuggestion.intent = new Intent("action");
|
||||
mSuggestion.intent.setComponent(new ComponentName("pkg", "cls"));
|
||||
mSuggestion.metaData = new Bundle();
|
||||
mMultipleCategory = new SuggestionParser.SuggestionCategory();
|
||||
mMultipleCategory.category = "category1";
|
||||
mMultipleCategory.multiple = true;
|
||||
mExclusiveCategory = new SuggestionParser.SuggestionCategory();
|
||||
mExclusiveCategory.category = "category2";
|
||||
mExclusiveCategory.exclusive = true;
|
||||
mSuggestionParser = new SuggestionParser(
|
||||
mContext, mPrefs, R.xml.suggestion_ordering, "0,0");
|
||||
mSuggestioCategory = new SuggestionParser.SuggestionCategory();
|
||||
mSuggestioCategory.category = "category1";
|
||||
mSuggestioCategory.multiple = true;
|
||||
mInfo = new ArrayList<>();
|
||||
mContext, mPrefs, Arrays.asList(mMultipleCategory, mExclusiveCategory), "0,0");
|
||||
|
||||
ResolveInfo info1 = TileUtilsTest.newInfo(true, "category1");
|
||||
info1.activityInfo.packageName = "pkg";
|
||||
ResolveInfo info2 = TileUtilsTest.newInfo(true, "category1");
|
||||
info2.activityInfo.packageName = "pkg2";
|
||||
mInfo.add(info1);
|
||||
mInfo.add(info2);
|
||||
when(mPackageManager.queryIntentActivitiesAsUser(
|
||||
any(Intent.class), anyInt(), anyInt())).thenReturn(mInfo);
|
||||
ResolveInfo info3 = TileUtilsTest.newInfo(true, "category2");
|
||||
info3.activityInfo.packageName = "pkg3";
|
||||
|
||||
Intent intent1 = new Intent(Intent.ACTION_MAIN).addCategory("category1");
|
||||
Intent intent2 = new Intent(Intent.ACTION_MAIN).addCategory("category2");
|
||||
RuntimeEnvironment.getRobolectricPackageManager().addResolveInfoForIntent(intent1, info1);
|
||||
RuntimeEnvironment.getRobolectricPackageManager().addResolveInfoForIntent(intent1, info2);
|
||||
RuntimeEnvironment.getRobolectricPackageManager().addResolveInfoForIntent(intent2, info3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -99,30 +100,64 @@ public class SuggestionParserTest {
|
||||
@Test
|
||||
public void testGetSuggestions_withoutSmartSuggestions() {
|
||||
readAndDismissSuggestion(false);
|
||||
mSuggestionParser.readSuggestions(mSuggestioCategory, mSuggestionsAfterDismiss, false);
|
||||
assertThat(mSuggestionsBeforeDismiss.size()).isEqualTo(2);
|
||||
assertThat(mSuggestionsAfterDismiss.size()).isEqualTo(1);
|
||||
mSuggestionParser.readSuggestions(mMultipleCategory, mSuggestionsAfterDismiss, false);
|
||||
assertThat(mSuggestionsBeforeDismiss).hasSize(2);
|
||||
assertThat(mSuggestionsAfterDismiss).hasSize(1);
|
||||
assertThat(mSuggestionsBeforeDismiss.get(1)).isEqualTo(mSuggestionsAfterDismiss.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSuggestions_withSmartSuggestions() {
|
||||
readAndDismissSuggestion(true);
|
||||
assertThat(mSuggestionsBeforeDismiss.size()).isEqualTo(2);
|
||||
assertThat(mSuggestionsAfterDismiss.size()).isEqualTo(2);
|
||||
assertThat(mSuggestionsBeforeDismiss).hasSize(2);
|
||||
assertThat(mSuggestionsAfterDismiss).hasSize(2);
|
||||
assertThat(mSuggestionsBeforeDismiss).isEqualTo(mSuggestionsAfterDismiss);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSuggestion_exclusiveNotAvailable() {
|
||||
RuntimeEnvironment.getRobolectricPackageManager().removeResolveInfosForIntent(
|
||||
new Intent(Intent.ACTION_MAIN).addCategory("category2"),
|
||||
"pkg3");
|
||||
|
||||
// If exclusive item is not available, the other categories should be shown
|
||||
final List<Tile> suggestions = mSuggestionParser.getSuggestions();
|
||||
assertThat(suggestions).hasSize(2);
|
||||
assertThat(suggestions.get(0).category).isEqualTo("category1");
|
||||
assertThat(suggestions.get(1).category).isEqualTo("category1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSuggestions_exclusive() {
|
||||
final List<Tile> suggestions = mSuggestionParser.getSuggestions();
|
||||
assertThat(suggestions).hasSize(1);
|
||||
assertThat(suggestions.get(0).category).isEqualTo("category2");
|
||||
}
|
||||
|
||||
private void readAndDismissSuggestion(boolean isSmartSuggestionEnabled) {
|
||||
mSuggestionsBeforeDismiss = new ArrayList<Tile>();
|
||||
mSuggestionsAfterDismiss = new ArrayList<Tile>();
|
||||
mSuggestionsBeforeDismiss = new ArrayList<>();
|
||||
mSuggestionsAfterDismiss = new ArrayList<>();
|
||||
mSuggestionParser.readSuggestions(
|
||||
mSuggestioCategory, mSuggestionsBeforeDismiss, isSmartSuggestionEnabled);
|
||||
if (mSuggestionParser.dismissSuggestion(
|
||||
mSuggestionsBeforeDismiss.get(0), isSmartSuggestionEnabled)) {
|
||||
mInfo.remove(0);
|
||||
mMultipleCategory, mSuggestionsBeforeDismiss, isSmartSuggestionEnabled);
|
||||
final Tile suggestion = mSuggestionsBeforeDismiss.get(0);
|
||||
if (mSuggestionParser.dismissSuggestion(suggestion, isSmartSuggestionEnabled)) {
|
||||
RuntimeEnvironment.getRobolectricPackageManager().removeResolveInfosForIntent(
|
||||
new Intent(Intent.ACTION_MAIN).addCategory(suggestion.category),
|
||||
suggestion.intent.getComponent().getPackageName());
|
||||
}
|
||||
mSuggestionParser.readSuggestions(
|
||||
mSuggestioCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled);
|
||||
mMultipleCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled);
|
||||
}
|
||||
|
||||
private static class TestPackageManager extends DefaultPackageManager {
|
||||
|
||||
TestPackageManager(ResourceLoader appResourceLoader) {
|
||||
super(appResourceLoader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
|
||||
return super.queryIntentActivities(intent, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,22 @@
|
||||
|
||||
package com.android.settingslib.drawer;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import android.content.IContentProvider;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.IContentProvider;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
@@ -40,34 +51,23 @@ import android.util.Pair;
|
||||
|
||||
import com.android.settingslib.SuggestionParser;
|
||||
import com.android.settingslib.TestConfig;
|
||||
import com.android.settingslib.drawer.TileUtilsTest;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.ArgumentMatcher;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
@@ -179,7 +179,11 @@ public class TileUtilsTest {
|
||||
false /* checkCategory */);
|
||||
|
||||
assertThat(outTiles.size()).isEqualTo(1);
|
||||
SuggestionParser parser = new SuggestionParser(mContext, null);
|
||||
SuggestionParser parser = new SuggestionParser(
|
||||
mContext,
|
||||
null,
|
||||
Collections.emptyList(),
|
||||
"0,10");
|
||||
parser.filterSuggestions(outTiles, 0, false);
|
||||
assertThat(outTiles.size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user