blob: 3e90435b21d796bfd8a48b7ef6195a9400d24926 [file] [log] [blame]
Fan Zhangcdbe1d62016-11-22 15:47:05 -08001/*
2 * Copyright (C) 2016 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.drawer;
18
Maurice Lamb10c6ff2017-06-08 20:29:21 -070019import static com.google.common.truth.Truth.assertThat;
20
Tony Mantler8d167372017-07-14 15:37:17 -070021import static org.mockito.ArgumentMatchers.any;
22import static org.mockito.ArgumentMatchers.anyInt;
23import static org.mockito.ArgumentMatchers.anyString;
24import static org.mockito.ArgumentMatchers.argThat;
25import static org.mockito.ArgumentMatchers.eq;
26import static org.mockito.ArgumentMatchers.isNull;
Maurice Lamb10c6ff2017-06-08 20:29:21 -070027import static org.mockito.Mockito.atLeastOnce;
28import static org.mockito.Mockito.spy;
29import static org.mockito.Mockito.verify;
30import static org.mockito.Mockito.when;
31import static org.robolectric.RuntimeEnvironment.application;
32
Maurice Lamf74b9e52017-03-23 14:58:47 -070033import android.app.ActivityManager;
Shahriyar Amini676add42016-12-16 11:29:39 -080034import android.content.ContentResolver;
Fan Zhangcdbe1d62016-11-22 15:47:05 -080035import android.content.Context;
Maurice Lamf74b9e52017-03-23 14:58:47 -070036import android.content.IContentProvider;
Fan Zhangcdbe1d62016-11-22 15:47:05 -080037import android.content.Intent;
38import android.content.pm.ActivityInfo;
39import android.content.pm.ApplicationInfo;
40import android.content.pm.PackageManager;
Shahriyar Amini6b32ae32016-11-22 14:49:04 -080041import android.content.pm.PackageManager.NameNotFoundException;
Fan Zhangcdbe1d62016-11-22 15:47:05 -080042import android.content.pm.ResolveInfo;
Shahriyar Amini6b32ae32016-11-22 14:49:04 -080043import android.content.res.Resources;
Shahriyar Amini676add42016-12-16 11:29:39 -080044import android.net.Uri;
Fan Zhangcdbe1d62016-11-22 15:47:05 -080045import android.os.Bundle;
Shahriyar Amini676add42016-12-16 11:29:39 -080046import android.os.RemoteException;
Fan Zhangcdbe1d62016-11-22 15:47:05 -080047import android.os.UserHandle;
Doris Ling485df112016-12-19 10:45:47 -080048import android.os.UserManager;
49import android.provider.Settings.Global;
Ido Ofira560cd92017-01-24 13:27:36 -080050import android.text.TextUtils;
Fan Zhangcdbe1d62016-11-22 15:47:05 -080051import android.util.ArrayMap;
52import android.util.Pair;
Jaewoong Jung78c5e5d2017-06-15 18:02:44 -070053import android.widget.RemoteViews;
Fan Zhangcdbe1d62016-11-22 15:47:05 -080054
Maurice Lamd8ae77b2017-03-23 21:26:01 -070055import com.android.settingslib.R;
Fan Zhangcdbe1d62016-11-22 15:47:05 -080056import com.android.settingslib.TestConfig;
Fan Zhange138ef12017-05-11 15:29:56 -070057import com.android.settingslib.suggestions.SuggestionParser;
Fan Zhangcdbe1d62016-11-22 15:47:05 -080058
59import org.junit.Before;
60import org.junit.Test;
61import org.junit.runner.RunWith;
Maurice Lamf74b9e52017-03-23 14:58:47 -070062import org.mockito.ArgumentCaptor;
Fan Zhangcdbe1d62016-11-22 15:47:05 -080063import org.mockito.Mock;
64import org.mockito.MockitoAnnotations;
65import org.robolectric.RobolectricTestRunner;
66import org.robolectric.annotation.Config;
Maurice Lamb10c6ff2017-06-08 20:29:21 -070067import org.robolectric.annotation.Implementation;
68import org.robolectric.annotation.Implements;
Jaewoong Jung78c5e5d2017-06-15 18:02:44 -070069import org.robolectric.internal.ShadowExtractor;
Fan Zhangcdbe1d62016-11-22 15:47:05 -080070
71import java.util.ArrayList;
Maurice Lamf74b9e52017-03-23 14:58:47 -070072import java.util.Collections;
Fan Zhangcdbe1d62016-11-22 15:47:05 -080073import java.util.List;
74import java.util.Map;
75
Fan Zhangcdbe1d62016-11-22 15:47:05 -080076@RunWith(RobolectricTestRunner.class)
Jaewoong Jung78c5e5d2017-06-15 18:02:44 -070077@Config(manifest = TestConfig.MANIFEST_PATH,
78 sdk = TestConfig.SDK_VERSION,
79 shadows = {TileUtilsTest.TileUtilsShadowRemoteViews.class})
Fan Zhangcdbe1d62016-11-22 15:47:05 -080080public class TileUtilsTest {
81
82 @Mock
83 private Context mContext;
84 @Mock
85 private PackageManager mPackageManager;
Shahriyar Amini6b32ae32016-11-22 14:49:04 -080086 @Mock
87 private Resources mResources;
Doris Ling485df112016-12-19 10:45:47 -080088 @Mock
89 private UserManager mUserManager;
Shahriyar Amini676add42016-12-16 11:29:39 -080090 @Mock
91 private IContentProvider mIContentProvider;
92 @Mock
93 private ContentResolver mContentResolver;
94
95 private static final String URI_GET_SUMMARY = "content://authority/text/summary";
96 private static final String URI_GET_ICON = "content://authority/icon/my_icon";
Fan Zhangcdbe1d62016-11-22 15:47:05 -080097
98 @Before
Shahriyar Amini6b32ae32016-11-22 14:49:04 -080099 public void setUp() throws NameNotFoundException {
Fan Zhangcdbe1d62016-11-22 15:47:05 -0800100 MockitoAnnotations.initMocks(this);
101 when(mContext.getPackageManager()).thenReturn(mPackageManager);
Shahriyar Amini6b32ae32016-11-22 14:49:04 -0800102 when(mPackageManager.getResourcesForApplication(anyString())).thenReturn(mResources);
Tony Mantler8d167372017-07-14 15:37:17 -0700103 when(mPackageManager.getResourcesForApplication((String) isNull())).thenReturn(mResources);
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700104 when(mPackageManager.getApplicationInfo(eq("abc"), anyInt()))
105 .thenReturn(application.getApplicationInfo());
106 mContentResolver = spy(application.getContentResolver());
Shahriyar Amini676add42016-12-16 11:29:39 -0800107 when(mContext.getContentResolver()).thenReturn(mContentResolver);
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700108 when(mContext.getPackageName()).thenReturn("com.android.settings");
Fan Zhangcdbe1d62016-11-22 15:47:05 -0800109 }
110
111 @Test
112 public void getTilesForIntent_shouldParseCategory() {
113 final String testCategory = "category1";
114 Intent intent = new Intent();
115 Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
116 List<Tile> outTiles = new ArrayList<>();
117 List<ResolveInfo> info = new ArrayList<>();
118 info.add(newInfo(true, testCategory));
Fan Zhangcdbe1d62016-11-22 15:47:05 -0800119 when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
120 .thenReturn(info);
121
122 TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
123 null /* defaultCategory */, outTiles, false /* usePriority */,
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700124 false /* checkCategory */, true /* forceTintExternalIcon */);
Fan Zhangcdbe1d62016-11-22 15:47:05 -0800125
126 assertThat(outTiles.size()).isEqualTo(1);
127 assertThat(outTiles.get(0).category).isEqualTo(testCategory);
128 }
129
130 @Test
Shahriyar Amini6b32ae32016-11-22 14:49:04 -0800131 public void getTilesForIntent_shouldParseKeyHintForSystemApp() {
132 String keyHint = "key";
133 Intent intent = new Intent();
134 Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
135 List<Tile> outTiles = new ArrayList<>();
136 List<ResolveInfo> info = new ArrayList<>();
137 ResolveInfo resolveInfo = newInfo(true, null /* category */, keyHint);
138 info.add(resolveInfo);
139
140 when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
141 .thenReturn(info);
142
143 TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
144 null /* defaultCategory */, outTiles, false /* usePriority */,
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700145 false /* checkCategory */, true /* forceTintExternalIcon */);
Shahriyar Amini6b32ae32016-11-22 14:49:04 -0800146
147 assertThat(outTiles.size()).isEqualTo(1);
148 assertThat(outTiles.get(0).key).isEqualTo(keyHint);
149 }
150
151 @Test
Fan Zhangcdbe1d62016-11-22 15:47:05 -0800152 public void getTilesForIntent_shouldSkipNonSystemApp() {
153 final String testCategory = "category1";
154 Intent intent = new Intent();
155 Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
156 List<Tile> outTiles = new ArrayList<>();
157 List<ResolveInfo> info = new ArrayList<>();
158 info.add(newInfo(false, testCategory));
159
160 when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
161 .thenReturn(info);
162
163 TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
164 null /* defaultCategory */, outTiles, false /* usePriority */,
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700165 false /* checkCategory */, true /* forceTintExternalIcon */);
Fan Zhangcdbe1d62016-11-22 15:47:05 -0800166
167 assertThat(outTiles.isEmpty()).isTrue();
168 }
169
Doris Ling485df112016-12-19 10:45:47 -0800170 @Test
Ido Ofira560cd92017-01-24 13:27:36 -0800171 public void getTilesForIntent_shouldSkipFilteredApps() {
Ido Ofira560cd92017-01-24 13:27:36 -0800172 Intent intent = new Intent();
173 Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
174 List<Tile> outTiles = new ArrayList<>();
175 List<ResolveInfo> info = new ArrayList<>();
176 ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
177 URI_GET_SUMMARY);
178 addMetadataToInfo(resolveInfo, "com.android.settings.require_account", "com.google");
179 addMetadataToInfo(resolveInfo, "com.android.settings.require_connection", "true");
180 info.add(resolveInfo);
181
182 when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
183 .thenReturn(info);
184
185 TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
186 null /* defaultCategory */, outTiles, false /* usePriority */,
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700187 false /* checkCategory */, true /* forceTintExternalIcon */);
Ido Ofira560cd92017-01-24 13:27:36 -0800188
189 assertThat(outTiles.size()).isEqualTo(1);
Maurice Lamf74b9e52017-03-23 14:58:47 -0700190 SuggestionParser parser = new SuggestionParser(
191 mContext,
192 null,
193 Collections.emptyList(),
194 "0,10");
Soroosh Mariooryad56ce7662017-02-06 15:23:00 -0800195 parser.filterSuggestions(outTiles, 0, false);
Ido Ofira560cd92017-01-24 13:27:36 -0800196 assertThat(outTiles.size()).isEqualTo(0);
197 }
198
199 @Test
Doris Ling485df112016-12-19 10:45:47 -0800200 public void getCategories_shouldHandleExtraIntentAction() {
201 final String testCategory = "category1";
202 final String testAction = "action1";
203 Map<Pair<String, String>, Tile> cache = new ArrayMap<>();
204 List<ResolveInfo> info = new ArrayList<>();
205 info.add(newInfo(true, testCategory));
206 Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
207 when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
208 List<UserHandle> userHandleList = new ArrayList<>();
209 userHandleList.add(UserHandle.CURRENT);
210 when(mUserManager.getUserProfiles()).thenReturn(userHandleList);
211
Tony Mantler8d167372017-07-14 15:37:17 -0700212 when(mPackageManager.queryIntentActivitiesAsUser(argThat(
213 event -> testAction.equals(event.getAction())), anyInt(), anyInt()))
214 .thenReturn(info);
Doris Ling485df112016-12-19 10:45:47 -0800215
216 List<DashboardCategory> categoryList = TileUtils.getCategories(
Fan Zhange138ef12017-05-11 15:29:56 -0700217 mContext, cache, false /* categoryDefinedInManifest */, testAction,
218 TileUtils.SETTING_PKG);
Doris Ling485df112016-12-19 10:45:47 -0800219 assertThat(categoryList.get(0).tiles.get(0).category).isEqualTo(testCategory);
220 }
Shahriyar Amini6b32ae32016-11-22 14:49:04 -0800221
Shahriyar Amini676add42016-12-16 11:29:39 -0800222 @Test
roger xue8f06ab02016-12-08 14:09:50 -0800223 public void getCategories_withPackageName() throws Exception {
224 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
225 Map<Pair<String, String>, Tile> cache = new ArrayMap<>();
226 Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
227 when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
228 List<UserHandle> userHandleList = new ArrayList<>();
229
230 userHandleList.add(new UserHandle(ActivityManager.getCurrentUser()));
231 when(mUserManager.getUserProfiles()).thenReturn(userHandleList);
232
233 TileUtils.getCategories(
Fan Zhange138ef12017-05-11 15:29:56 -0700234 mContext, cache, false /* categoryDefinedInManifest */, null /* action */,
235 TileUtils.SETTING_PKG);
roger xue8f06ab02016-12-08 14:09:50 -0800236 verify(mPackageManager, atLeastOnce()).queryIntentActivitiesAsUser(
Fan Zhange138ef12017-05-11 15:29:56 -0700237 intentCaptor.capture(), anyInt(), anyInt());
roger xue8f06ab02016-12-08 14:09:50 -0800238
239 assertThat(intentCaptor.getAllValues().get(0).getPackage())
Fan Zhange138ef12017-05-11 15:29:56 -0700240 .isEqualTo(TileUtils.SETTING_PKG);
roger xue8f06ab02016-12-08 14:09:50 -0800241 }
242
243 @Test
William Luh4c978a32017-03-31 15:08:16 -0700244 public void getTilesForIntent_shouldReadMetadataTitleAsString() throws RemoteException {
245 Intent intent = new Intent();
246 Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
247 List<Tile> outTiles = new ArrayList<>();
248 List<ResolveInfo> info = new ArrayList<>();
249 ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
250 URI_GET_SUMMARY, "my title", 0);
251 info.add(resolveInfo);
252
253 when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
254 .thenReturn(info);
255
256 TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
257 null /* defaultCategory */, outTiles, false /* usePriority */,
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700258 false /* checkCategory */, true /* forceTintExternalIcon */);
William Luh4c978a32017-03-31 15:08:16 -0700259
260 assertThat(outTiles.size()).isEqualTo(1);
261 assertThat(outTiles.get(0).title).isEqualTo("my title");
262 }
263
264 @Test
265 public void getTilesForIntent_shouldReadMetadataTitleFromResource() throws RemoteException {
266 Intent intent = new Intent();
267 Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
268 List<Tile> outTiles = new ArrayList<>();
269 List<ResolveInfo> info = new ArrayList<>();
270 ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
271 URI_GET_SUMMARY, null, 123);
272 info.add(resolveInfo);
273
274 when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
275 .thenReturn(info);
276
277 when(mResources.getString(eq(123)))
278 .thenReturn("my localized title");
279
280 TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
281 null /* defaultCategory */, outTiles, false /* usePriority */,
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700282 false /* checkCategory */, true /* forceTintExternalIcon */);
William Luh4c978a32017-03-31 15:08:16 -0700283
284 assertThat(outTiles.size()).isEqualTo(1);
285 assertThat(outTiles.get(0).title).isEqualTo("my localized title");
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700286
287 // Icon should be tintable because the tile is not from settings package, and
288 // "forceTintExternalIcon" is set
289 assertThat(outTiles.get(0).isIconTintable).isTrue();
290 }
291
292 @Test
293 public void getTilesForIntent_shouldNotTintIconIfInSettingsPackage() {
294 Intent intent = new Intent();
295 Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
296 List<Tile> outTiles = new ArrayList<>();
297 List<ResolveInfo> info = new ArrayList<>();
298 ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
299 URI_GET_SUMMARY, null, 123);
300 resolveInfo.activityInfo.packageName = "com.android.settings";
301 resolveInfo.activityInfo.applicationInfo.packageName = "com.android.settings";
302 info.add(resolveInfo);
303
304 when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
305 .thenReturn(info);
306
307 TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
308 null /* defaultCategory */, outTiles, false /* usePriority */,
309 false /* checkCategory */, true /* forceTintExternalIcon */);
310
311 assertThat(outTiles.size()).isEqualTo(1);
312 assertThat(outTiles.get(0).isIconTintable).isFalse();
313 }
314
315 @Test
316 public void getTilesForIntent_shouldMarkIconTintableIfMetadataSet() {
317 Intent intent = new Intent();
318 Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
319 List<Tile> outTiles = new ArrayList<>();
320 List<ResolveInfo> info = new ArrayList<>();
321 ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
322 URI_GET_SUMMARY, null, 123);
323 resolveInfo.activityInfo.metaData
324 .putBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE, true);
325 info.add(resolveInfo);
326
327 when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
328 .thenReturn(info);
329
330 TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
331 null /* defaultCategory */, outTiles, false /* usePriority */,
332 false /* checkCategory */, false /* forceTintExternalIcon */);
333
334 assertThat(outTiles.size()).isEqualTo(1);
335 assertThat(outTiles.get(0).isIconTintable).isTrue();
William Luh4c978a32017-03-31 15:08:16 -0700336 }
337
338 @Test
Shahriyar Amini676add42016-12-16 11:29:39 -0800339 public void getTilesForIntent_shouldNotProcessInvalidUriContentSystemApp()
340 throws RemoteException {
341 Intent intent = new Intent();
342 Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
343 List<Tile> outTiles = new ArrayList<>();
344 List<ResolveInfo> info = new ArrayList<>();
345 ResolveInfo resolveInfo = newInfo(true, null /* category */, null, null, URI_GET_SUMMARY);
346 info.add(resolveInfo);
347
348 when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
349 .thenReturn(info);
350
351 // Case 1: No provider associated with the uri specified.
352 TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
353 null /* defaultCategory */, outTiles, false /* usePriority */,
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700354 false /* checkCategory */, true /* forceTintExternalIcon */);
Shahriyar Amini676add42016-12-16 11:29:39 -0800355
356 assertThat(outTiles.size()).isEqualTo(1);
357 assertThat(outTiles.get(0).icon.getResId()).isEqualTo(314159);
358 assertThat(outTiles.get(0).summary).isEqualTo("static-summary");
359
360 // Case 2: Empty bundle.
361 Bundle bundle = new Bundle();
362 when(mIContentProvider.call(anyString(),
363 eq(TileUtils.getMethodFromUri(Uri.parse(URI_GET_SUMMARY))), eq(URI_GET_SUMMARY),
364 any())).thenReturn(bundle);
William Luh5a0a0d82017-04-18 11:34:38 -0700365 when(mContentResolver.acquireUnstableProvider(anyString()))
366 .thenReturn(mIContentProvider);
367 when(mContentResolver.acquireUnstableProvider(any(Uri.class)))
368 .thenReturn(mIContentProvider);
Shahriyar Amini676add42016-12-16 11:29:39 -0800369
370 TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
371 null /* defaultCategory */, outTiles, false /* usePriority */,
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700372 false /* checkCategory */, true /* forceTintExternalIcon */);
Shahriyar Amini676add42016-12-16 11:29:39 -0800373
374 assertThat(outTiles.size()).isEqualTo(1);
375 assertThat(outTiles.get(0).icon.getResId()).isEqualTo(314159);
376 assertThat(outTiles.get(0).summary).isEqualTo("static-summary");
377 }
378
379 @Test
380 public void getTilesForIntent_shouldProcessUriContentForSystemApp() throws RemoteException {
381 Intent intent = new Intent();
382 Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
383 List<Tile> outTiles = new ArrayList<>();
384 List<ResolveInfo> info = new ArrayList<>();
385 ResolveInfo resolveInfo = newInfo(true, null /* category */, null, URI_GET_ICON,
386 URI_GET_SUMMARY);
387 info.add(resolveInfo);
388
389 when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
390 .thenReturn(info);
391
Shahriyar Amini676add42016-12-16 11:29:39 -0800392 TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
393 null /* defaultCategory */, outTiles, false /* usePriority */,
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700394 false /* checkCategory */, true /* forceTintExternalIcon */);
Shahriyar Amini676add42016-12-16 11:29:39 -0800395
396 assertThat(outTiles.size()).isEqualTo(1);
Shahriyar Amini676add42016-12-16 11:29:39 -0800397 }
398
Maurice Lamd8ae77b2017-03-23 21:26:01 -0700399 @Test
400 public void getTilesForIntent_shouldShowRemoteViewIfSpecified() {
401 Intent intent = new Intent();
402 Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
403 List<Tile> outTiles = new ArrayList<>();
404 List<ResolveInfo> info = new ArrayList<>();
405 ResolveInfo resolveInfo = newInfo(true, null /* category */);
406 resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
407 R.layout.user_preference);
408 info.add(resolveInfo);
409
410 when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
411 .thenReturn(info);
412
413 TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
414 null /* defaultCategory */, outTiles, false /* usePriority */,
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700415 false /* checkCategory */, true /* forceTintExternalIcon */);
Maurice Lamd8ae77b2017-03-23 21:26:01 -0700416
417 assertThat(outTiles.size()).isEqualTo(1);
418 Tile tile = outTiles.get(0);
419 assertThat(tile.remoteViews).isNotNull();
420 assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
421 }
422
Jaewoong Jung78c5e5d2017-06-15 18:02:44 -0700423 @Test
424 public void getTilesForIntent_summaryUriSpecified_shouldOverrideRemoteViewSummary()
425 throws RemoteException {
426 Intent intent = new Intent();
427 Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
428 List<Tile> outTiles = new ArrayList<>();
429 List<ResolveInfo> info = new ArrayList<>();
430 ResolveInfo resolveInfo = newInfo(true, null /* category */, null,
431 null, URI_GET_SUMMARY);
432 resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
433 R.layout.user_preference);
434 info.add(resolveInfo);
435
436 when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
437 .thenReturn(info);
438
439 // Mock the content provider interaction.
440 Bundle bundle = new Bundle();
441 bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, "new summary text");
442 when(mIContentProvider.call(anyString(),
443 eq(TileUtils.getMethodFromUri(Uri.parse(URI_GET_SUMMARY))), eq(URI_GET_SUMMARY),
444 any())).thenReturn(bundle);
445 when(mContentResolver.acquireUnstableProvider(anyString()))
446 .thenReturn(mIContentProvider);
447 when(mContentResolver.acquireUnstableProvider(any(Uri.class)))
448 .thenReturn(mIContentProvider);
449
450 TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
451 null /* defaultCategory */, outTiles, false /* usePriority */,
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700452 false /* checkCategory */, true /* forceTintExternalIcon */);
Jaewoong Jung78c5e5d2017-06-15 18:02:44 -0700453
454 assertThat(outTiles.size()).isEqualTo(1);
455 Tile tile = outTiles.get(0);
456 assertThat(tile.remoteViews).isNotNull();
457 assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
458 // Make sure the summary TextView got a new text string.
459 TileUtilsShadowRemoteViews shadowRemoteViews =
460 (TileUtilsShadowRemoteViews) ShadowExtractor.extract(tile.remoteViews);
461 assertThat(shadowRemoteViews.overrideViewId).isEqualTo(android.R.id.summary);
462 assertThat(shadowRemoteViews.overrideText).isEqualTo("new summary text");
463 }
464
465 @Test
466 public void getTilesForIntent_providerUnavailable_shouldNotOverrideRemoteViewSummary()
467 throws RemoteException {
468 Intent intent = new Intent();
469 Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
470 List<Tile> outTiles = new ArrayList<>();
471 List<ResolveInfo> info = new ArrayList<>();
472 ResolveInfo resolveInfo = newInfo(true, null /* category */, null,
473 null, URI_GET_SUMMARY);
474 resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
475 R.layout.user_preference);
476 info.add(resolveInfo);
477
478 when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
479 .thenReturn(info);
480
481 // Mock the content provider interaction.
482 Bundle bundle = new Bundle();
483 bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, "new summary text");
484 when(mIContentProvider.call(anyString(),
485 eq(TileUtils.getMethodFromUri(Uri.parse(URI_GET_SUMMARY))), eq(URI_GET_SUMMARY),
486 any())).thenReturn(bundle);
487
488 TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
489 null /* defaultCategory */, outTiles, false /* usePriority */,
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700490 false /* checkCategory */, true /* forceTintExternalIcon */);
Jaewoong Jung78c5e5d2017-06-15 18:02:44 -0700491
492 assertThat(outTiles.size()).isEqualTo(1);
493 Tile tile = outTiles.get(0);
494 assertThat(tile.remoteViews).isNotNull();
495 assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
496 // Make sure the summary TextView didn't get any text view updates.
497 TileUtilsShadowRemoteViews shadowRemoteViews =
498 (TileUtilsShadowRemoteViews) ShadowExtractor.extract(tile.remoteViews);
499 assertThat(shadowRemoteViews.overrideViewId).isNull();
500 assertThat(shadowRemoteViews.overrideText).isNull();
501 }
502
Soroosh Mariooryad56ce7662017-02-06 15:23:00 -0800503 public static ResolveInfo newInfo(boolean systemApp, String category) {
Shahriyar Amini6b32ae32016-11-22 14:49:04 -0800504 return newInfo(systemApp, category, null);
505 }
506
Soroosh Mariooryad56ce7662017-02-06 15:23:00 -0800507 private static ResolveInfo newInfo(boolean systemApp, String category, String keyHint) {
Shahriyar Amini676add42016-12-16 11:29:39 -0800508 return newInfo(systemApp, category, keyHint, null, null);
509 }
510
Soroosh Mariooryad56ce7662017-02-06 15:23:00 -0800511 private static ResolveInfo newInfo(boolean systemApp, String category, String keyHint,
William Luh4c978a32017-03-31 15:08:16 -0700512 String iconUri, String summaryUri) {
513 return newInfo(systemApp, category, keyHint, iconUri, summaryUri, null, 0);
514 }
515
516 private static ResolveInfo newInfo(boolean systemApp, String category, String keyHint,
517 String iconUri, String summaryUri, String title, int titleResId) {
518
Fan Zhangcdbe1d62016-11-22 15:47:05 -0800519 ResolveInfo info = new ResolveInfo();
520 info.system = systemApp;
521 info.activityInfo = new ActivityInfo();
522 info.activityInfo.packageName = "abc";
523 info.activityInfo.name = "123";
524 info.activityInfo.metaData = new Bundle();
525 info.activityInfo.metaData.putString("com.android.settings.category", category);
Shahriyar Amini676add42016-12-16 11:29:39 -0800526 info.activityInfo.metaData.putInt("com.android.settings.icon", 314159);
527 info.activityInfo.metaData.putString("com.android.settings.summary", "static-summary");
Shahriyar Amini6b32ae32016-11-22 14:49:04 -0800528 if (keyHint != null) {
529 info.activityInfo.metaData.putString("com.android.settings.keyhint", keyHint);
530 }
Shahriyar Amini676add42016-12-16 11:29:39 -0800531 if (iconUri != null) {
532 info.activityInfo.metaData.putString("com.android.settings.icon_uri", iconUri);
533 }
534 if (summaryUri != null) {
535 info.activityInfo.metaData.putString("com.android.settings.summary_uri", summaryUri);
536 }
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700537 if (titleResId != 0) {
Fan Zhangdadfd502017-07-26 11:00:51 -0700538 info.activityInfo.metaData.putInt(TileUtils.META_DATA_PREFERENCE_TITLE, titleResId);
Maurice Lamb10c6ff2017-06-08 20:29:21 -0700539 } else if (title != null) {
William Luh4c978a32017-03-31 15:08:16 -0700540 info.activityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE, title);
541 }
Fan Zhangcdbe1d62016-11-22 15:47:05 -0800542 info.activityInfo.applicationInfo = new ApplicationInfo();
Shahriyar Amini6b32ae32016-11-22 14:49:04 -0800543 if (systemApp) {
544 info.activityInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
545 }
Fan Zhangcdbe1d62016-11-22 15:47:05 -0800546 return info;
547 }
Ido Ofira560cd92017-01-24 13:27:36 -0800548
549 private void addMetadataToInfo(ResolveInfo info, String key, String value) {
550 if (!TextUtils.isEmpty(key)) {
551 if (info.activityInfo == null) {
552 info.activityInfo = new ActivityInfo();
553 }
554 if (info.activityInfo.metaData == null) {
555 info.activityInfo.metaData = new Bundle();
556 }
557 info.activityInfo.metaData.putString(key, value);
558 }
559 }
Jaewoong Jung78c5e5d2017-06-15 18:02:44 -0700560
561 @Implements(RemoteViews.class)
562 public static class TileUtilsShadowRemoteViews {
563
564 private Integer overrideViewId;
565 private CharSequence overrideText;
566
567 @Implementation
568 public void setTextViewText(int viewId, CharSequence text) {
569 overrideViewId = viewId;
570 overrideText = text;
571 }
572 }
Fan Zhangcdbe1d62016-11-22 15:47:05 -0800573}