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; 20import static org.robolectric.RuntimeEnvironment.application; 21import static org.robolectric.shadow.api.Shadow.extract; 22 23import android.content.ComponentName; 24import android.content.Intent; 25import android.content.SharedPreferences; 26import android.content.pm.ResolveInfo; 27import android.os.Bundle; 28import android.preference.PreferenceManager; 29 30import com.android.settingslib.SettingsLibRobolectricTestRunner; 31import com.android.settingslib.drawer.Tile; 32import com.android.settingslib.drawer.TileUtilsTest; 33 34import org.junit.Before; 35import org.junit.Test; 36import org.junit.runner.RunWith; 37import org.robolectric.shadows.ShadowPackageManager; 38 39import java.util.ArrayList; 40import java.util.Arrays; 41import java.util.List; 42 43@RunWith(SettingsLibRobolectricTestRunner.class) 44public class SuggestionParserTest { 45 46 private ShadowPackageManager mPackageManager; 47 private SuggestionParser mSuggestionParser; 48 private SuggestionCategory mMultipleCategory; 49 private SuggestionCategory mExclusiveCategory; 50 private SuggestionCategory mExpiredExclusiveCategory; 51 private List<Tile> mSuggestionsBeforeDismiss; 52 private List<Tile> mSuggestionsAfterDismiss; 53 private SharedPreferences mPrefs; 54 private Tile mSuggestion; 55 56 @Before 57 public void setUp() { 58 mPackageManager = extract(application.getPackageManager()); 59 mPrefs = PreferenceManager.getDefaultSharedPreferences(application); 60 mSuggestion = new Tile(); 61 mSuggestion.intent = new Intent("action"); 62 mSuggestion.intent.setComponent(new ComponentName("pkg", "cls")); 63 mSuggestion.metaData = new Bundle(); 64 mMultipleCategory = new SuggestionCategory(); 65 mMultipleCategory.category = "category1"; 66 mMultipleCategory.multiple = true; 67 mExclusiveCategory = new SuggestionCategory(); 68 mExclusiveCategory.category = "category2"; 69 mExclusiveCategory.exclusive = true; 70 mExpiredExclusiveCategory = new SuggestionCategory(); 71 mExpiredExclusiveCategory.category = "category3"; 72 mExpiredExclusiveCategory.exclusive = true; 73 mExpiredExclusiveCategory.exclusiveExpireDaysInMillis = 0; 74 75 mSuggestionParser = new SuggestionParser(application, mPrefs, 76 Arrays.asList(mMultipleCategory, mExclusiveCategory, mExpiredExclusiveCategory), 77 "0"); 78 79 ResolveInfo info1 = TileUtilsTest.newInfo(true, null); 80 info1.activityInfo.packageName = "pkg"; 81 ResolveInfo infoDupe1 = TileUtilsTest.newInfo(true, null); 82 infoDupe1.activityInfo.packageName = "pkg"; 83 84 ResolveInfo info2 = TileUtilsTest.newInfo(true, null); 85 info2.activityInfo.packageName = "pkg2"; 86 ResolveInfo info3 = TileUtilsTest.newInfo(true, null); 87 info3.activityInfo.packageName = "pkg3"; 88 ResolveInfo info4 = TileUtilsTest.newInfo(true, null); 89 info4.activityInfo.packageName = "pkg4"; 90 91 Intent intent1 = new Intent(Intent.ACTION_MAIN).addCategory("category1"); 92 Intent intent2 = new Intent(Intent.ACTION_MAIN).addCategory("category2"); 93 Intent intent3 = new Intent(Intent.ACTION_MAIN).addCategory("category3"); 94 95 mPackageManager.addResolveInfoForIntent(intent1, info1); 96 mPackageManager.addResolveInfoForIntent(intent1, info2); 97 mPackageManager.addResolveInfoForIntent(intent1, infoDupe1); 98 mPackageManager.addResolveInfoForIntent(intent2, info3); 99 mPackageManager.addResolveInfoForIntent(intent3, info4); 100 } 101 102 @Test 103 public void dismissSuggestion_shouldDismiss() { 104 assertThat(mSuggestionParser.dismissSuggestion(mSuggestion)).isTrue(); 105 } 106 107 @Test 108 public void testGetSuggestions_withoutSmartSuggestions_shouldDismiss() { 109 readAndDismissSuggestion(false); 110 mSuggestionParser.readSuggestions(mMultipleCategory, mSuggestionsAfterDismiss, false); 111 assertThat(mSuggestionsBeforeDismiss).hasSize(2); 112 assertThat(mSuggestionsAfterDismiss).hasSize(1); 113 assertThat(mSuggestionsBeforeDismiss.get(1)).isEqualTo(mSuggestionsAfterDismiss.get(0)); 114 } 115 116 @Test 117 public void testGetSuggestions_withSmartSuggestions_shouldDismiss() { 118 readAndDismissSuggestion(true); 119 assertThat(mSuggestionsBeforeDismiss).hasSize(2); 120 assertThat(mSuggestionsAfterDismiss).hasSize(1); 121 } 122 123 @Test 124 public void testGetSuggestion_exclusiveNotAvailable_onlyRegularCategoryAndNoDupe() { 125 mPackageManager.removeResolveInfosForIntent( 126 new Intent(Intent.ACTION_MAIN).addCategory("category2"), 127 "pkg3"); 128 mPackageManager.removeResolveInfosForIntent( 129 new Intent(Intent.ACTION_MAIN).addCategory("category3"), 130 "pkg4"); 131 132 // If exclusive item is not available, the other categories should be shown 133 final SuggestionList sl = 134 mSuggestionParser.getSuggestions(false /* isSmartSuggestionEnabled */); 135 final List<Tile> suggestions = sl.getSuggestions(); 136 assertThat(suggestions).hasSize(2); 137 138 assertThat(suggestions.get(0).intent.getComponent().getPackageName()).isEqualTo("pkg"); 139 assertThat(suggestions.get(1).intent.getComponent().getPackageName()).isEqualTo("pkg2"); 140 } 141 142 @Test 143 public void testGetSuggestion_exclusiveExpiredAvailable_shouldLoadWithRegularCategory() { 144 // First remove permanent exclusive 145 mPackageManager.removeResolveInfosForIntent( 146 new Intent(Intent.ACTION_MAIN).addCategory("category2"), 147 "pkg3"); 148 // Set the other exclusive to be expired. 149 mPrefs.edit() 150 .putLong(mExpiredExclusiveCategory.category + "_setup_time", 151 System.currentTimeMillis() - 1000) 152 .commit(); 153 154 // If exclusive is expired, they should be shown together with the other categories 155 final SuggestionList sl = 156 mSuggestionParser.getSuggestions(true /* isSmartSuggestionEnabled */); 157 final List<Tile> suggestions = sl.getSuggestions(); 158 159 assertThat(suggestions).hasSize(3); 160 } 161 162 @Test 163 public void testGetSuggestions_exclusive() { 164 final SuggestionList sl = 165 mSuggestionParser.getSuggestions(false /* isSmartSuggestionEnabled */); 166 final List<Tile> suggestions = sl.getSuggestions(); 167 168 assertThat(suggestions).hasSize(1); 169 } 170 171 @Test 172 public void isSuggestionDismissed_dismissedSuggestion_shouldReturnTrue() { 173 final Tile suggestion = new Tile(); 174 suggestion.metaData = new Bundle(); 175 suggestion.metaData.putString(SuggestionParser.META_DATA_DISMISS_CONTROL, "1,2,3"); 176 suggestion.intent = new Intent().setComponent(new ComponentName("pkg", "cls")); 177 178 // Dismiss suggestion when smart suggestion is not enabled. 179 mSuggestionParser.dismissSuggestion(suggestion); 180 181 assertThat(mSuggestionParser.isDismissed(suggestion, true /* isSmartSuggestionEnabled */)) 182 .isTrue(); 183 } 184 185 private void readAndDismissSuggestion(boolean isSmartSuggestionEnabled) { 186 mSuggestionsBeforeDismiss = new ArrayList<>(); 187 mSuggestionsAfterDismiss = new ArrayList<>(); 188 mSuggestionParser.readSuggestions( 189 mMultipleCategory, mSuggestionsBeforeDismiss, isSmartSuggestionEnabled); 190 191 final Tile suggestion = mSuggestionsBeforeDismiss.get(0); 192 if (mSuggestionParser.dismissSuggestion(suggestion)) { 193 mPackageManager.removeResolveInfosForIntent( 194 new Intent(Intent.ACTION_MAIN).addCategory(mMultipleCategory.category), 195 suggestion.intent.getComponent().getPackageName()); 196 } 197 mSuggestionParser.readSuggestions( 198 mMultipleCategory, mSuggestionsAfterDismiss, isSmartSuggestionEnabled); 199 } 200} 201