1 /* 2 * Copyright (C) 2018 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 */ 17 18 package com.android.settings.slices; 19 20 import static android.content.ContentResolver.SCHEME_CONTENT; 21 22 import static com.google.common.truth.Truth.assertThat; 23 24 import static org.mockito.Mockito.spy; 25 26 import android.app.ApplicationPackageManager; 27 import android.content.ComponentName; 28 import android.content.ContentResolver; 29 import android.content.Context; 30 import android.net.Uri; 31 import android.provider.SettingsSlicesContract; 32 import android.view.accessibility.AccessibilityManager; 33 34 import com.android.settings.search.SearchFeatureProvider; 35 import com.android.settings.search.SearchFeatureProviderImpl; 36 import com.android.settings.testutils.DatabaseTestUtils; 37 import com.android.settings.testutils.FakeFeatureFactory; 38 import com.android.settings.testutils.FakeIndexProvider; 39 import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; 40 import com.android.settings.testutils.shadow.ShadowLockPatternUtils; 41 import com.android.settings.testutils.shadow.ShadowUserManager; 42 import com.android.settings.testutils.shadow.ShadowUtils; 43 import com.android.settingslib.search.SearchIndexableData; 44 45 import org.junit.After; 46 import org.junit.Before; 47 import org.junit.Test; 48 import org.junit.runner.RunWith; 49 import org.robolectric.RobolectricTestRunner; 50 import org.robolectric.RuntimeEnvironment; 51 import org.robolectric.annotation.Config; 52 import org.robolectric.annotation.Implementation; 53 import org.robolectric.annotation.Implements; 54 import org.robolectric.shadow.api.Shadow; 55 import org.robolectric.shadows.ShadowAccessibilityManager; 56 57 import java.util.ArrayList; 58 import java.util.List; 59 import java.util.Locale; 60 61 @RunWith(RobolectricTestRunner.class) 62 @Config(shadows = {ShadowUserManager.class, ShadowUtils.class, 63 SlicesDatabaseAccessorTest.ShadowApplicationPackageManager.class, 64 ShadowBluetoothAdapter.class, ShadowLockPatternUtils.class}) 65 public class SlicesDatabaseAccessorTest { 66 67 68 private Context mContext; 69 private SlicesDatabaseAccessor mAccessor; 70 71 @Before setUp()72 public void setUp() { 73 mContext = RuntimeEnvironment.application; 74 ShadowUserManager.getShadow().setIsAdminUser(true); 75 mAccessor = spy(new SlicesDatabaseAccessor(mContext)); 76 SlicesDatabaseHelper.getInstance(mContext).setIndexedState(); 77 78 // Register the fake a11y Service 79 ShadowAccessibilityManager shadowAccessibilityManager = Shadow.extract( 80 RuntimeEnvironment.application.getSystemService(AccessibilityManager.class)); 81 shadowAccessibilityManager.setInstalledAccessibilityServiceList(new ArrayList<>()); 82 } 83 84 @After cleanUp()85 public void cleanUp() { 86 DatabaseTestUtils.clearDb(mContext); 87 } 88 89 @Test testGetSliceDataFromKey_validKey_validSliceReturned()90 public void testGetSliceDataFromKey_validKey_validSliceReturned() { 91 String key = "key"; 92 SliceTestUtils.insertSliceToDb(mContext, key); 93 94 SliceData data = mAccessor.getSliceDataFromKey(key); 95 96 assertThat(data.getKey()).isEqualTo(key); 97 assertThat(data.getTitle()).isEqualTo(SliceTestUtils.FAKE_TITLE); 98 assertThat(data.getSummary()).isEqualTo(SliceTestUtils.FAKE_SUMMARY); 99 assertThat(data.getScreenTitle()).isEqualTo(SliceTestUtils.FAKE_SCREEN_TITLE); 100 assertThat(data.getKeywords()).isEqualTo(SliceTestUtils.FAKE_KEYWORDS); 101 assertThat(data.getIconResource()).isEqualTo(SliceTestUtils.FAKE_ICON); 102 assertThat(data.getFragmentClassName()).isEqualTo(SliceTestUtils.FAKE_FRAGMENT_NAME); 103 assertThat(data.getUri()).isNull(); 104 assertThat(data.getPreferenceController()).isEqualTo(SliceTestUtils.FAKE_CONTROLLER_NAME); 105 assertThat(data.getHighlightMenuRes()).isEqualTo(SliceTestUtils.FAKE_HIGHLIGHT_MENU_RES); 106 assertThat(data.getUnavailableSliceSubtitle()).isNull(); 107 } 108 109 @Test testGetSliceDataFromKey_allowDynamicSummary_validSliceReturned()110 public void testGetSliceDataFromKey_allowDynamicSummary_validSliceReturned() { 111 String key = "key"; 112 SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */, 113 null /* customizedUnavailableSliceSubtitle */); 114 115 SliceData data = mAccessor.getSliceDataFromKey(key); 116 117 assertThat(data.getKey()).isEqualTo(key); 118 assertThat(data.getTitle()).isEqualTo(SliceTestUtils.FAKE_TITLE); 119 assertThat(data.getSummary()).isEqualTo(SliceTestUtils.FAKE_SUMMARY); 120 assertThat(data.getScreenTitle()).isEqualTo(SliceTestUtils.FAKE_SCREEN_TITLE); 121 assertThat(data.getKeywords()).isEqualTo(SliceTestUtils.FAKE_KEYWORDS); 122 assertThat(data.getIconResource()).isEqualTo(SliceTestUtils.FAKE_ICON); 123 assertThat(data.getFragmentClassName()).isEqualTo(SliceTestUtils.FAKE_FRAGMENT_NAME); 124 assertThat(data.getUri()).isNull(); 125 assertThat(data.getPreferenceController()).isEqualTo(SliceTestUtils.FAKE_CONTROLLER_NAME); 126 assertThat(data.getHighlightMenuRes()).isEqualTo(SliceTestUtils.FAKE_HIGHLIGHT_MENU_RES); 127 } 128 129 @Test(expected = IllegalStateException.class) testGetSliceDataFromKey_invalidKey_errorThrown()130 public void testGetSliceDataFromKey_invalidKey_errorThrown() { 131 String key = "key"; 132 133 mAccessor.getSliceDataFromKey(key); 134 } 135 136 @Test testGetSliceFromUri_validUri_validSliceReturned()137 public void testGetSliceFromUri_validUri_validSliceReturned() { 138 final String key = "key"; 139 SliceTestUtils.insertSliceToDb(mContext, key); 140 141 final Uri uri = new Uri.Builder() 142 .scheme(ContentResolver.SCHEME_CONTENT) 143 .authority(SettingsSliceProvider.SLICE_AUTHORITY) 144 .appendPath("action") 145 .appendPath(key) 146 .build(); 147 148 SliceData data = mAccessor.getSliceDataFromUri(uri); 149 150 assertThat(data.getKey()).isEqualTo(key); 151 assertThat(data.getTitle()).isEqualTo(SliceTestUtils.FAKE_TITLE); 152 assertThat(data.getSummary()).isEqualTo(SliceTestUtils.FAKE_SUMMARY); 153 assertThat(data.getScreenTitle()).isEqualTo(SliceTestUtils.FAKE_SCREEN_TITLE); 154 assertThat(data.getKeywords()).isEqualTo(SliceTestUtils.FAKE_KEYWORDS); 155 assertThat(data.getIconResource()).isEqualTo(SliceTestUtils.FAKE_ICON); 156 assertThat(data.getFragmentClassName()).isEqualTo(SliceTestUtils.FAKE_FRAGMENT_NAME); 157 assertThat(data.getUri()).isEqualTo(uri); 158 assertThat(data.getPreferenceController()).isEqualTo(SliceTestUtils.FAKE_CONTROLLER_NAME); 159 assertThat(data.getHighlightMenuRes()).isEqualTo(SliceTestUtils.FAKE_HIGHLIGHT_MENU_RES); 160 } 161 162 @Test(expected = IllegalStateException.class) testGetSliceFromUri_invalidUri_errorThrown()163 public void testGetSliceFromUri_invalidUri_errorThrown() { 164 final Uri uri = new Uri.Builder() 165 .scheme(ContentResolver.SCHEME_CONTENT) 166 .authority(SettingsSliceProvider.SLICE_AUTHORITY) 167 .appendPath("intent") 168 .appendPath("durr") 169 .build(); 170 mAccessor.getSliceDataFromUri(uri); 171 } 172 173 @Test getDescendantUris_platformSlice_doesNotReturnOEMSlice()174 public void getDescendantUris_platformSlice_doesNotReturnOEMSlice() { 175 final String key = "oem_key"; 176 SliceTestUtils.insertSliceToDb(mContext, key, false /* isPlatformSlice */, 177 null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */); 178 final List<Uri> keys = mAccessor.getSliceUris(SettingsSlicesContract.AUTHORITY, 179 true /* isPublicSlice */); 180 181 assertThat(keys).isEmpty(); 182 } 183 184 @Test getDescendantUris_oemSlice_doesNotReturnPlatformSlice()185 public void getDescendantUris_oemSlice_doesNotReturnPlatformSlice() { 186 final String key = "platform_key"; 187 SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */, 188 null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */); 189 final List<Uri> keys = mAccessor.getSliceUris(SettingsSliceProvider.SLICE_AUTHORITY, 190 true /* isPublicSlice */); 191 192 assertThat(keys).isEmpty(); 193 } 194 195 @Test getDescendantUris_oemSlice_returnsOEMUriDescendant()196 public void getDescendantUris_oemSlice_returnsOEMUriDescendant() { 197 final String key = "oem_key"; 198 SliceTestUtils.insertSliceToDb(mContext, key, false /* isPlatformSlice */, 199 null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */); 200 final List<Uri> keys = mAccessor.getSliceUris(SettingsSliceProvider.SLICE_AUTHORITY, 201 true /* isPublicSlice */); 202 203 assertThat(keys).containsExactly( 204 Uri.parse("content://com.android.settings.slices/action/oem_key")); 205 } 206 207 @Test getDescendantUris_platformSlice_returnsPlatformUriDescendant()208 public void getDescendantUris_platformSlice_returnsPlatformUriDescendant() { 209 final String key = "platform_key"; 210 SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */, 211 null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */); 212 final List<Uri> keys = mAccessor.getSliceUris(SettingsSlicesContract.AUTHORITY, 213 true /* isPublicSlice */); 214 215 assertThat(keys).containsExactly( 216 Uri.parse("content://android.settings.slices/action/platform_key")); 217 } 218 219 @Test getSliceUris_publicSlice_returnPublicUri()220 public void getSliceUris_publicSlice_returnPublicUri() { 221 SliceTestUtils.insertSliceToDb(mContext, "test_public", false /* isPlatformSlice */, 222 null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */); 223 SliceTestUtils.insertSliceToDb(mContext, "test_private", false /* isPlatformSlice */, 224 null /* customizedUnavailableSliceSubtitle */, false /* isPublicSlice */); 225 final Uri expectedUri = new Uri.Builder() 226 .scheme(SCHEME_CONTENT) 227 .authority(SettingsSliceProvider.SLICE_AUTHORITY) 228 .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) 229 .appendPath("test_public") 230 .build(); 231 232 final List<Uri> uri = mAccessor.getSliceUris(SettingsSliceProvider.SLICE_AUTHORITY, true); 233 234 assertThat(uri).containsExactly(expectedUri); 235 } 236 237 @Test getSliceUris_nonPublicSlice_returnNonPublicUri()238 public void getSliceUris_nonPublicSlice_returnNonPublicUri() { 239 SliceTestUtils.insertSliceToDb(mContext, "test_public", false /* isPlatformSlice */, 240 null /* customizedUnavailableSliceSubtitle */, true /* isPublicSlice */); 241 SliceTestUtils.insertSliceToDb(mContext, "test_private", false /* isPlatformSlice */, 242 null /* customizedUnavailableSliceSubtitle */, false /* isPublicSlice */); 243 final Uri expectedUri = new Uri.Builder() 244 .scheme(SCHEME_CONTENT) 245 .authority(SettingsSliceProvider.SLICE_AUTHORITY) 246 .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) 247 .appendPath("test_private") 248 .build(); 249 250 final List<Uri> uri = mAccessor.getSliceUris(SettingsSliceProvider.SLICE_AUTHORITY, false); 251 252 assertThat(uri).containsExactly(expectedUri); 253 } 254 255 @Test 256 @Config(qualifiers = "mcc999") getSliceKeys_indexesDatabase()257 public void getSliceKeys_indexesDatabase() { 258 // Force new indexing 259 Locale.setDefault(new Locale("ca")); 260 final SearchFeatureProvider provider = new SearchFeatureProviderImpl(); 261 final SlicesFeatureProvider sliceProvider = new SlicesFeatureProviderImpl(); 262 final FakeFeatureFactory factory = FakeFeatureFactory.setupForTest(); 263 factory.searchFeatureProvider = provider; 264 factory.slicesFeatureProvider = sliceProvider; 265 // Fake the indexable list. 266 provider.getSearchIndexableResources().getProviderValues().clear(); 267 provider.getSearchIndexableResources().getProviderValues().add( 268 new SearchIndexableData(FakeIndexProvider.class, 269 FakeIndexProvider.SEARCH_INDEX_DATA_PROVIDER)); 270 271 final SlicesDatabaseAccessor accessor = new SlicesDatabaseAccessor(mContext); 272 final List<Uri> keys = accessor.getSliceUris(SettingsSliceProvider.SLICE_AUTHORITY, 273 true /* isPublicSlice */); 274 275 assertThat(keys).isNotEmpty(); 276 } 277 278 @Test testGetSliceDataFromKey_defaultUnavailableSlice_validSliceReturned()279 public void testGetSliceDataFromKey_defaultUnavailableSlice_validSliceReturned() { 280 String key = "key"; 281 SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */, 282 null /* customizedUnavailableSliceSubtitle */); 283 284 SliceData data = mAccessor.getSliceDataFromKey(key); 285 286 assertThat(data.getKey()).isEqualTo(key); 287 assertThat(data.getTitle()).isEqualTo(SliceTestUtils.FAKE_TITLE); 288 assertThat(data.getSummary()).isEqualTo(SliceTestUtils.FAKE_SUMMARY); 289 assertThat(data.getScreenTitle()).isEqualTo(SliceTestUtils.FAKE_SCREEN_TITLE); 290 assertThat(data.getKeywords()).isEqualTo(SliceTestUtils.FAKE_KEYWORDS); 291 assertThat(data.getIconResource()).isEqualTo(SliceTestUtils.FAKE_ICON); 292 assertThat(data.getFragmentClassName()).isEqualTo(SliceTestUtils.FAKE_FRAGMENT_NAME); 293 assertThat(data.getUri()).isNull(); 294 assertThat(data.getPreferenceController()).isEqualTo(SliceTestUtils.FAKE_CONTROLLER_NAME); 295 assertThat(data.getHighlightMenuRes()).isEqualTo(SliceTestUtils.FAKE_HIGHLIGHT_MENU_RES); 296 assertThat(data.getUnavailableSliceSubtitle()).isNull(); 297 } 298 299 @Test testGetSliceDataFromKey_customizeSubtitleOfUnavailableSlice_validSliceReturned()300 public void testGetSliceDataFromKey_customizeSubtitleOfUnavailableSlice_validSliceReturned() { 301 String key = "key"; 302 String subtitle = "subtitle"; 303 SliceTestUtils.insertSliceToDb(mContext, key, true /* isPlatformSlice */, subtitle); 304 305 SliceData data = mAccessor.getSliceDataFromKey(key); 306 307 assertThat(data.getKey()).isEqualTo(key); 308 assertThat(data.getTitle()).isEqualTo(SliceTestUtils.FAKE_TITLE); 309 assertThat(data.getSummary()).isEqualTo(SliceTestUtils.FAKE_SUMMARY); 310 assertThat(data.getScreenTitle()).isEqualTo(SliceTestUtils.FAKE_SCREEN_TITLE); 311 assertThat(data.getKeywords()).isEqualTo(SliceTestUtils.FAKE_KEYWORDS); 312 assertThat(data.getIconResource()).isEqualTo(SliceTestUtils.FAKE_ICON); 313 assertThat(data.getFragmentClassName()).isEqualTo(SliceTestUtils.FAKE_FRAGMENT_NAME); 314 assertThat(data.getUri()).isNull(); 315 assertThat(data.getPreferenceController()).isEqualTo(SliceTestUtils.FAKE_CONTROLLER_NAME); 316 assertThat(data.getHighlightMenuRes()).isEqualTo(SliceTestUtils.FAKE_HIGHLIGHT_MENU_RES); 317 assertThat(data.getUnavailableSliceSubtitle()).isEqualTo(subtitle); 318 } 319 320 @Implements(ApplicationPackageManager.class) 321 public static class ShadowApplicationPackageManager extends 322 org.robolectric.shadows.ShadowApplicationPackageManager { 323 324 @Implementation getInstantAppResolverSettingsComponent()325 protected ComponentName getInstantAppResolverSettingsComponent() { 326 return null; 327 } 328 } 329 } 330