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