SuggestionParserTest.java revision f6631bf618477372bca3d4accae96553af2ae1d3
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.settingslib.suggestions;
18
19import static com.google.common.truth.Truth.assertThat;
20
21import static org.robolectric.RuntimeEnvironment.application;
22import static org.robolectric.shadow.api.Shadow.extract;
23
24import android.app.ApplicationPackageManager;
25import android.content.ComponentName;
26import android.content.Intent;
27import android.content.SharedPreferences;
28import android.content.pm.ResolveInfo;
29import android.os.Bundle;
30import android.preference.PreferenceManager;
31
32import com.android.settingslib.SettingsLibRobolectricTestRunner;
33import com.android.settingslib.TestConfig;
34import com.android.settingslib.drawer.Tile;
35import com.android.settingslib.drawer.TileUtilsTest;
36
37import org.junit.Before;
38import org.junit.Test;
39import org.junit.runner.RunWith;
40import org.robolectric.annotation.Config;
41import org.robolectric.annotation.Implementation;
42import org.robolectric.annotation.Implements;
43import org.robolectric.shadows.ShadowApplicationPackageManager;
44
45import java.util.ArrayList;
46import java.util.Arrays;
47import java.util.List;
48
49@RunWith(SettingsLibRobolectricTestRunner.class)
50@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
51        shadows = SuggestionParserTest.TestPackageManager.class)
52public class SuggestionParserTest {
53
54    private TestPackageManager mPackageManager;
55    private SuggestionParser mSuggestionParser;
56    private SuggestionCategory mMultipleCategory;
57    private SuggestionCategory mExclusiveCategory;
58    private SuggestionCategory mExpiredExclusiveCategory;
59    private List<Tile> mSuggestionsBeforeDismiss;
60    private List<Tile> mSuggestionsAfterDismiss;
61    private SharedPreferences mPrefs;
62    private Tile mSuggestion;
63
64    @Before
65    public void setUp() {
66        mPackageManager = extract(application.getPackageManager());
67        mPrefs = PreferenceManager.getDefaultSharedPreferences(application);
68        mSuggestion = new Tile();
69        mSuggestion.intent = new Intent("action");
70        mSuggestion.intent.setComponent(new ComponentName("pkg", "cls"));
71        mSuggestion.metaData = new Bundle();
72        mMultipleCategory = new SuggestionCategory();
73        mMultipleCategory.category = "category1";
74        mMultipleCategory.multiple = true;
75        mExclusiveCategory = new SuggestionCategory();
76        mExclusiveCategory.category = "category2";
77        mExclusiveCategory.exclusive = true;
78        mExpiredExclusiveCategory = new SuggestionCategory();
79        mExpiredExclusiveCategory.category = "category3";
80        mExpiredExclusiveCategory.exclusive = true;
81        mExpiredExclusiveCategory.exclusiveExpireDaysInMillis = 0;
82
83        mSuggestionParser = new SuggestionParser(application, mPrefs,
84                Arrays.asList(mMultipleCategory, mExclusiveCategory, mExpiredExclusiveCategory),
85                "0");
86
87        ResolveInfo info1 = TileUtilsTest.newInfo(true, null);
88        info1.activityInfo.packageName = "pkg";
89        ResolveInfo infoDupe1 = TileUtilsTest.newInfo(true, null);
90        infoDupe1.activityInfo.packageName = "pkg";
91
92        ResolveInfo info2 = TileUtilsTest.newInfo(true, null);
93        info2.activityInfo.packageName = "pkg2";
94        ResolveInfo info3 = TileUtilsTest.newInfo(true, null);
95        info3.activityInfo.packageName = "pkg3";
96        ResolveInfo info4 = TileUtilsTest.newInfo(true, null);
97        info4.activityInfo.packageName = "pkg4";
98
99        Intent intent1 = new Intent(Intent.ACTION_MAIN).addCategory("category1");
100        Intent intent2 = new Intent(Intent.ACTION_MAIN).addCategory("category2");
101        Intent intent3 = new Intent(Intent.ACTION_MAIN).addCategory("category3");
102
103        mPackageManager.addResolveInfoForIntent(intent1, info1);
104        mPackageManager.addResolveInfoForIntent(intent1, info2);
105        mPackageManager.addResolveInfoForIntent(intent1, infoDupe1);
106        mPackageManager.addResolveInfoForIntent(intent2, info3);
107        mPackageManager.addResolveInfoForIntent(intent3, info4);
108    }
109
110    @Test
111    public void dismissSuggestion_shouldDismiss() {
112        assertThat(mSuggestionParser.dismissSuggestion(mSuggestion)).isTrue();
113    }
114
115    @Test
116    public void testGetSuggestions_withoutSmartSuggestions_shouldDismiss() {
117        readAndDismissSuggestion(false);
118        mSuggestionParser.readSuggestions(mMultipleCategory, mSuggestionsAfterDismiss, false);
119        assertThat(mSuggestionsBeforeDismiss).hasSize(2);
120        assertThat(mSuggestionsAfterDismiss).hasSize(1);
121        assertThat(mSuggestionsBeforeDismiss.get(1)).isEqualTo(mSuggestionsAfterDismiss.get(0));
122    }
123
124    @Test
125    public void testGetSuggestions_withSmartSuggestions_shouldDismiss() {
126        readAndDismissSuggestion(true);
127        assertThat(mSuggestionsBeforeDismiss).hasSize(2);
128        assertThat(mSuggestionsAfterDismiss).hasSize(1);
129    }
130
131    @Test
132    public void testGetSuggestion_exclusiveNotAvailable_onlyRegularCategoryAndNoDupe() {
133        mPackageManager.removeResolveInfosForIntent(
134                new Intent(Intent.ACTION_MAIN).addCategory("category2"),
135                "pkg3");
136        mPackageManager.removeResolveInfosForIntent(
137                new Intent(Intent.ACTION_MAIN).addCategory("category3"),
138                "pkg4");
139
140        // If exclusive item is not available, the other categories should be shown
141        final SuggestionList sl =
142                mSuggestionParser.getSuggestions(false /* isSmartSuggestionEnabled */);
143        final List<Tile> suggestions = sl.getSuggestions();
144        assertThat(suggestions).hasSize(2);
145
146        assertThat(suggestions.get(0).intent.getComponent().getPackageName()).isEqualTo("pkg");
147        assertThat(suggestions.get(1).intent.getComponent().getPackageName()).isEqualTo("pkg2");
148    }
149
150    @Test
151    public void testGetSuggestion_exclusiveExpiredAvailable_shouldLoadWithRegularCategory() {
152        // First remove permanent exclusive
153        mPackageManager.removeResolveInfosForIntent(
154                new Intent(Intent.ACTION_MAIN).addCategory("category2"),
155                "pkg3");
156        // Set the other exclusive to be expired.
157        mPrefs.edit()
158                .putLong(mExpiredExclusiveCategory.category + "_setup_time",
159                        System.currentTimeMillis() - 1000)
160                .commit();
161
162        // If exclusive is expired, they should be shown together with the other categories
163        final SuggestionList sl =
164                mSuggestionParser.getSuggestions(true /* isSmartSuggestionEnabled */);
165        final List<Tile> suggestions = sl.getSuggestions();
166
167        assertThat(suggestions).hasSize(3);
168    }
169
170    @Test
171    public void testGetSuggestions_exclusive() {
172        final SuggestionList sl =
173                mSuggestionParser.getSuggestions(false /* isSmartSuggestionEnabled */);
174        final List<Tile> suggestions = sl.getSuggestions();
175
176        assertThat(suggestions).hasSize(1);
177    }
178
179    @Test
180    public void isSuggestionDismissed_dismissedSuggestion_shouldReturnTrue() {
181        final Tile suggestion = new Tile();
182        suggestion.metaData = new Bundle();
183        suggestion.metaData.putString(SuggestionParser.META_DATA_DISMISS_CONTROL, "1,2,3");
184        suggestion.intent = new Intent().setComponent(new ComponentName("pkg", "cls"));
185
186        // Dismiss suggestion when smart suggestion is not enabled.
187        mSuggestionParser.dismissSuggestion(suggestion);
188
189        assertThat(mSuggestionParser.isDismissed(suggestion, true /* isSmartSuggestionEnabled */))
190                .isTrue();
191    }
192
193    private void readAndDismissSuggestion(boolean isSmartSuggestionEnabled) {
194        mSuggestionsBeforeDismiss = new ArrayList<>();
195        mSuggestionsAfterDismiss = new ArrayList<>();
196        mSuggestionParser.readSuggestions(
197                mMultipleCategory, mSuggestionsBeforeDismiss, isSmartSuggestionEnabled);
198
199        final Tile suggestion = mSuggestionsBeforeDismiss.get(0);
200        if (mSuggestionParser.dismissSuggestion(suggestion)) {
201            mPackageManager.removeResolveInfosForIntent(
202                    new Intent(Intent.ACTION_MAIN).addCategory(mMultipleCategory.category),
203                    suggestion.intent.getComponent().getPackageName());
204        }
205        mSuggestionParser.readSuggestions(
206                mMultipleCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled);
207    }
208
209    @Implements(ApplicationPackageManager.class)
210    public static class TestPackageManager extends ShadowApplicationPackageManager {
211
212        @Implementation
213        public List<ResolveInfo> queryIntentActivitiesAsUser(Intent intent, int flags, int userId) {
214            return super.queryIntentActivities(intent, flags);
215        }
216    }
217}
218