Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1c07761f authored by Maurice Lam's avatar Maurice Lam Committed by Android (Google) Code Review
Browse files

Merge "Add exclusive attribute to suggestion category"

parents a660c31f f74b9e52
Loading
Loading
Loading
Loading
+30 −10
Original line number Diff line number Diff line
@@ -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);
+2 −0
Original line number Diff line number Diff line
@@ -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"
+72 −37
Original line number Diff line number Diff line
@@ -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);
        }
    }
}
+20 −16
Original line number Diff line number Diff line
@@ -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);
    }