• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.settings.dashboard;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static org.mockito.Matchers.any;
21 import static org.mockito.Matchers.anyInt;
22 import static org.mockito.Matchers.eq;
23 import static org.mockito.Mockito.doReturn;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.spy;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.verifyZeroInteractions;
28 import static org.mockito.Mockito.when;
29 import static org.robolectric.Shadows.shadowOf;
30 
31 import android.app.Activity;
32 import android.content.ComponentName;
33 import android.content.Context;
34 import android.content.Intent;
35 import android.content.pm.PackageManager;
36 import android.content.pm.ResolveInfo;
37 import android.graphics.Bitmap;
38 import android.graphics.drawable.Icon;
39 import android.os.Bundle;
40 import android.os.UserHandle;
41 import android.os.UserManager;
42 import android.support.v7.preference.Preference;
43 
44 import com.android.internal.logging.nano.MetricsProto;
45 import com.android.settings.R;
46 import com.android.settings.SettingsActivity;
47 import com.android.settings.testutils.FakeFeatureFactory;
48 import com.android.settings.testutils.SettingsRobolectricTestRunner;
49 import com.android.settings.testutils.shadow.ShadowThreadUtils;
50 import com.android.settings.testutils.shadow.ShadowTileUtils;
51 import com.android.settings.testutils.shadow.ShadowUserManager;
52 import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin;
53 import com.android.settingslib.drawer.CategoryKey;
54 import com.android.settingslib.drawer.CategoryManager;
55 import com.android.settingslib.drawer.DashboardCategory;
56 import com.android.settingslib.drawer.Tile;
57 import com.android.settingslib.drawer.TileUtils;
58 
59 import org.junit.Before;
60 import org.junit.Test;
61 import org.junit.runner.RunWith;
62 import org.mockito.Answers;
63 import org.mockito.Mock;
64 import org.mockito.MockitoAnnotations;
65 import org.robolectric.Robolectric;
66 import org.robolectric.RuntimeEnvironment;
67 import org.robolectric.annotation.Config;
68 import org.robolectric.shadows.ShadowActivity;
69 import org.robolectric.shadows.ShadowApplication;
70 import org.robolectric.util.ReflectionHelpers;
71 
72 import java.util.ArrayList;
73 
74 @RunWith(SettingsRobolectricTestRunner.class)
75 @Config(shadows = ShadowUserManager.class)
76 public class DashboardFeatureProviderImplTest {
77 
78     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
79     private Activity mActivity;
80     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
81     private UserManager mUserManager;
82     @Mock
83     private CategoryManager mCategoryManager;
84     @Mock
85     private PackageManager mPackageManager;
86     private FakeFeatureFactory mFeatureFactory;
87 
88     private Context mContext;
89     private DashboardFeatureProviderImpl mImpl;
90 
91     @Before
setUp()92     public void setUp() {
93         MockitoAnnotations.initMocks(this);
94         mContext = spy(RuntimeEnvironment.application);
95         doReturn(mPackageManager).when(mContext).getPackageManager();
96         when(mPackageManager.resolveActivity(any(Intent.class), anyInt()))
97             .thenReturn(new ResolveInfo());
98         mFeatureFactory = FakeFeatureFactory.setupForTest();
99         mImpl = new DashboardFeatureProviderImpl(mContext);
100     }
101 
102     @Test
shouldHoldAppContext()103     public void shouldHoldAppContext() {
104         assertThat(mImpl.mContext).isEqualTo(mContext.getApplicationContext());
105     }
106 
107     @Test
bindPreference_shouldBindAllData()108     public void bindPreference_shouldBindAllData() {
109         final Preference preference = new Preference(RuntimeEnvironment.application);
110         final Tile tile = new Tile();
111         tile.title = "title";
112         tile.summary = "summary";
113         tile.icon = Icon.createWithBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565));
114         tile.metaData = new Bundle();
115         tile.metaData.putString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS, "HI");
116         tile.priority = 10;
117         mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.SETTINGS_GESTURES,
118                 preference, tile, "123", Preference.DEFAULT_ORDER);
119 
120         assertThat(preference.getTitle()).isEqualTo(tile.title);
121         assertThat(preference.getSummary()).isEqualTo(tile.summary);
122         assertThat(preference.getIcon()).isNotNull();
123         assertThat(preference.getFragment())
124                 .isEqualTo(tile.metaData.getString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS));
125         assertThat(preference.getOrder()).isEqualTo(-tile.priority);
126     }
127 
128     @Test
bindPreference_noFragmentMetadata_shouldBindIntent()129     public void bindPreference_noFragmentMetadata_shouldBindIntent() {
130         final Preference preference = new Preference(RuntimeEnvironment.application);
131         final Tile tile = new Tile();
132         tile.metaData = new Bundle();
133         tile.priority = 10;
134         tile.intent = new Intent();
135         tile.intent.setComponent(new ComponentName("pkg", "class"));
136 
137         mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.SETTINGS_GESTURES,
138                 preference, tile, "123", Preference.DEFAULT_ORDER);
139 
140         assertThat(preference.getFragment()).isNull();
141         assertThat(preference.getOnPreferenceClickListener()).isNotNull();
142         assertThat(preference.getOrder()).isEqualTo(-tile.priority);
143     }
144 
145     @Test
bindPreference_noFragmentMetadata_shouldBindToProfileSelector()146     public void bindPreference_noFragmentMetadata_shouldBindToProfileSelector() {
147         final Preference preference = new Preference(RuntimeEnvironment.application);
148         final Tile tile = new Tile();
149         tile.metaData = new Bundle();
150         tile.userHandle = new ArrayList<>();
151         tile.userHandle.add(mock(UserHandle.class));
152         tile.userHandle.add(mock(UserHandle.class));
153         tile.intent = new Intent();
154         tile.intent.setComponent(new ComponentName("pkg", "class"));
155 
156         when(mActivity.getApplicationContext().getSystemService(Context.USER_SERVICE))
157                 .thenReturn(mUserManager);
158 
159         mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.SETTINGS_GESTURES,
160                 preference, tile, "123", Preference.DEFAULT_ORDER);
161         preference.getOnPreferenceClickListener().onPreferenceClick(null);
162 
163         verify(mActivity).getFragmentManager();
164     }
165 
166     @Test
bindPreference_noFragmentMetadataSingleUser_shouldBindToDirectLaunchIntent()167     public void bindPreference_noFragmentMetadataSingleUser_shouldBindToDirectLaunchIntent() {
168         final Preference preference = new Preference(RuntimeEnvironment.application);
169         final Tile tile = new Tile();
170         tile.metaData = new Bundle();
171         tile.userHandle = new ArrayList<>();
172         tile.userHandle.add(mock(UserHandle.class));
173         tile.intent = new Intent();
174         tile.intent.setComponent(new ComponentName("pkg", "class"));
175 
176         when(mActivity.getSystemService(Context.USER_SERVICE))
177                 .thenReturn(mUserManager);
178 
179         mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.SETTINGS_GESTURES,
180                 preference, tile, "123", Preference.DEFAULT_ORDER);
181         preference.getOnPreferenceClickListener().onPreferenceClick(null);
182 
183         verify(mFeatureFactory.metricsFeatureProvider).logDashboardStartIntent(
184                 any(Context.class),
185                 any(Intent.class),
186                 eq(MetricsProto.MetricsEvent.SETTINGS_GESTURES));
187         verify(mActivity)
188                 .startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class));
189     }
190 
191     @Test
bindPreference_toInternalSettingActivity_shouldBindToDirectLaunchIntentAndNotLog()192     public void bindPreference_toInternalSettingActivity_shouldBindToDirectLaunchIntentAndNotLog() {
193         final Preference preference = new Preference(RuntimeEnvironment.application);
194         final Tile tile = new Tile();
195         tile.metaData = new Bundle();
196         tile.userHandle = new ArrayList<>();
197         tile.userHandle.add(mock(UserHandle.class));
198         tile.intent = new Intent();
199         tile.intent.setComponent(
200                 new ComponentName(RuntimeEnvironment.application.getPackageName(), "class"));
201 
202         when(mActivity.getSystemService(Context.USER_SERVICE))
203                 .thenReturn(mUserManager);
204         when(mActivity.getApplicationContext().getPackageName())
205                 .thenReturn(RuntimeEnvironment.application.getPackageName());
206 
207         mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.SETTINGS_GESTURES,
208                 preference, tile, "123", Preference.DEFAULT_ORDER);
209         preference.getOnPreferenceClickListener().onPreferenceClick(null);
210         verify(mFeatureFactory.metricsFeatureProvider).logDashboardStartIntent(
211                 any(Context.class),
212                 any(Intent.class),
213                 anyInt());
214         verify(mActivity)
215                 .startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class));
216     }
217 
218     @Test
bindPreference_nullPreference_shouldIgnore()219     public void bindPreference_nullPreference_shouldIgnore() {
220         final Tile tile = mock(Tile.class);
221         mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
222                 null, tile, "123", Preference.DEFAULT_ORDER);
223 
224         verifyZeroInteractions(tile);
225     }
226 
227     @Test
bindPreference_withNullKeyNullPriority_shouldGenerateKeyAndPriority()228     public void bindPreference_withNullKeyNullPriority_shouldGenerateKeyAndPriority() {
229         final Preference preference = new Preference(RuntimeEnvironment.application);
230         final Tile tile = new Tile();
231         tile.intent = new Intent();
232         tile.intent.setComponent(new ComponentName("pkg", "class"));
233         mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
234                 preference, tile, null /*key */, Preference.DEFAULT_ORDER);
235 
236         assertThat(preference.getKey()).isNotNull();
237         assertThat(preference.getOrder()).isEqualTo(Preference.DEFAULT_ORDER);
238     }
239 
240     @Test
bindPreference_noSummary_shouldSetSummaryToPlaceholder()241     public void bindPreference_noSummary_shouldSetSummaryToPlaceholder() {
242         final Preference preference = new Preference(RuntimeEnvironment.application);
243         final Tile tile = new Tile();
244         tile.intent = new Intent();
245         tile.intent.setComponent(new ComponentName("pkg", "class"));
246         mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
247                 preference, tile, null /*key */, Preference.DEFAULT_ORDER);
248 
249         assertThat(preference.getSummary())
250                 .isEqualTo(RuntimeEnvironment.application.getString(R.string.summary_placeholder));
251     }
252 
253     @Test
bindPreference_hasSummary_shouldSetSummary()254     public void bindPreference_hasSummary_shouldSetSummary() {
255         final Preference preference = new Preference(RuntimeEnvironment.application);
256         final Tile tile = new Tile();
257         tile.summary = "test";
258         tile.intent = new Intent();
259         tile.intent.setComponent(new ComponentName("pkg", "class"));
260         mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
261                 preference, tile, null /*key */, Preference.DEFAULT_ORDER);
262 
263         assertThat(preference.getSummary()).isEqualTo(tile.summary);
264     }
265 
266     @Test
267     @Config(shadows = {ShadowTileUtils.class, ShadowThreadUtils.class})
bindPreference_hasSummaryUri_shouldLoadSummaryFromContentProvider()268     public void bindPreference_hasSummaryUri_shouldLoadSummaryFromContentProvider() {
269         final Preference preference = new Preference(RuntimeEnvironment.application);
270         final Tile tile = new Tile();
271         tile.intent = new Intent();
272         tile.intent.setComponent(new ComponentName("pkg", "class"));
273         tile.metaData = new Bundle();
274         tile.metaData.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI,
275                 "content://com.android.settings/tile_summary");
276 
277         mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
278                 preference, tile, null /*key */, Preference.DEFAULT_ORDER);
279 
280         assertThat(preference.getSummary()).isEqualTo(ShadowTileUtils.MOCK_SUMMARY);
281     }
282 
283     @Test
bindPreference_withNullKeyTileKey_shouldUseTileKey()284     public void bindPreference_withNullKeyTileKey_shouldUseTileKey() {
285         final Preference preference = new Preference(RuntimeEnvironment.application);
286         final Tile tile = new Tile();
287         tile.key = "key";
288         tile.intent = new Intent();
289         tile.intent.setComponent(new ComponentName("pkg", "class"));
290         mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
291                 preference, tile, null /* key */, Preference.DEFAULT_ORDER);
292 
293         assertThat(preference.getKey()).isEqualTo(tile.key);
294     }
295 
296     @Test
297     @Config(shadows = {ShadowTileUtils.class, ShadowThreadUtils.class})
bindPreference_withIconUri_shouldLoadIconFromContentProvider()298     public void bindPreference_withIconUri_shouldLoadIconFromContentProvider() {
299         final Preference preference = new Preference(RuntimeEnvironment.application);
300         final Tile tile = new Tile();
301         tile.key = "key";
302         tile.intent = new Intent();
303         tile.intent.setComponent(
304                 new ComponentName(RuntimeEnvironment.application.getPackageName(), "class"));
305         tile.metaData = new Bundle();
306         tile.metaData.putString(TileUtils.META_DATA_PREFERENCE_ICON_URI,
307                 "content://com.android.settings/tile_icon");
308         mImpl.bindIcon(preference, tile);
309 
310         assertThat(preference.getIcon()).isNotNull();
311     }
312 
313     @Test
bindPreference_withBaseOrder_shouldOffsetPriority()314     public void bindPreference_withBaseOrder_shouldOffsetPriority() {
315         final int baseOrder = 100;
316         final Preference preference = new Preference(RuntimeEnvironment.application);
317         final Tile tile = new Tile();
318         tile.metaData = new Bundle();
319         tile.priority = 10;
320         mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
321                 preference, tile, "123", baseOrder);
322 
323         assertThat(preference.getOrder()).isEqualTo(-tile.priority + baseOrder);
324     }
325 
326     @Test
bindPreference_withOrderMetadata_shouldUseOrderInMetadata()327     public void bindPreference_withOrderMetadata_shouldUseOrderInMetadata() {
328         final Preference preference = new Preference(RuntimeEnvironment.application);
329         final int testOrder = -30;
330         final Tile tile = new Tile();
331         tile.metaData = new Bundle();
332         tile.metaData.putInt(mImpl.META_DATA_KEY_ORDER, testOrder);
333         tile.priority = 10;
334         mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
335                 preference, tile, "123", Preference.DEFAULT_ORDER);
336 
337         assertThat(preference.getOrder()).isEqualTo(testOrder);
338     }
339 
340     @Test
bindPreference_invalidOrderMetadata_shouldIgnore()341     public void bindPreference_invalidOrderMetadata_shouldIgnore() {
342         final Preference preference = new Preference(RuntimeEnvironment.application);
343         final Tile tile = new Tile();
344         tile.metaData = new Bundle();
345         tile.metaData.putString(mImpl.META_DATA_KEY_ORDER, "hello");
346         tile.priority = 10;
347         mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN,
348                 preference, tile, "123", Preference.DEFAULT_ORDER);
349 
350         assertThat(preference.getOrder()).isEqualTo(-tile.priority);
351     }
352 
353     @Test
bindPreference_withIntentActionMetadata_shouldSetLaunchAction()354     public void bindPreference_withIntentActionMetadata_shouldSetLaunchAction() {
355         Activity activity = Robolectric.buildActivity(Activity.class).get();
356         final Preference preference = new Preference(RuntimeEnvironment.application);
357         final Tile tile = new Tile();
358         tile.key = "key";
359         tile.intent = new Intent();
360         tile.intent.setComponent(new ComponentName("pkg", "class"));
361         tile.metaData = new Bundle();
362         tile.metaData.putString("com.android.settings.intent.action", "TestAction");
363         tile.userHandle = null;
364         mImpl.bindPreferenceToTile(activity, MetricsProto.MetricsEvent.SETTINGS_GESTURES,
365                 preference, tile, "123", Preference.DEFAULT_ORDER);
366         preference.performClick();
367         ShadowActivity shadowActivity = shadowOf(activity);
368 
369         final Intent launchIntent = shadowActivity.getNextStartedActivityForResult().intent;
370         assertThat(launchIntent.getAction())
371                 .isEqualTo("TestAction");
372         assertThat(launchIntent.getIntExtra(VisibilityLoggerMixin.EXTRA_SOURCE_METRICS_CATEGORY, 0))
373                 .isEqualTo(MetricsProto.MetricsEvent.SETTINGS_GESTURES);
374     }
375 
376     @Test
clickPreference_withUnresolvableIntent_shouldNotLaunchAnything()377     public void clickPreference_withUnresolvableIntent_shouldNotLaunchAnything() {
378         ReflectionHelpers.setField(
379                 mImpl, "mPackageManager", RuntimeEnvironment.application.getPackageManager());
380         Activity activity = Robolectric.buildActivity(Activity.class).get();
381         final ShadowApplication application = ShadowApplication.getInstance();
382         final Preference preference = new Preference(application.getApplicationContext());
383         final Tile tile = new Tile();
384         tile.key = "key";
385         tile.intent = new Intent();
386         tile.intent.setComponent(new ComponentName("pkg", "class"));
387         tile.metaData = new Bundle();
388         tile.metaData.putString("com.android.settings.intent.action", "TestAction");
389         tile.userHandle = null;
390 
391         mImpl.bindPreferenceToTile(activity, MetricsProto.MetricsEvent.SETTINGS_GESTURES,
392                 preference, tile, "123", Preference.DEFAULT_ORDER);
393         preference.performClick();
394 
395         final ShadowActivity.IntentForResult launchIntent =
396                 shadowOf(activity).getNextStartedActivityForResult();
397 
398         assertThat(launchIntent).isNull();
399     }
400 
401     @Test
getPreferences_noCategory_shouldReturnNull()402     public void getPreferences_noCategory_shouldReturnNull() {
403         mImpl = new DashboardFeatureProviderImpl(mActivity);
404         ReflectionHelpers.setField(mImpl, "mCategoryManager", mCategoryManager);
405         when(mCategoryManager.getTilesByCategory(mActivity, CategoryKey.CATEGORY_HOMEPAGE))
406                 .thenReturn(null);
407 
408         assertThat(mImpl.getPreferencesForCategory(null, null,
409                 MetricsProto.MetricsEvent.SETTINGS_GESTURES, CategoryKey.CATEGORY_HOMEPAGE))
410                 .isNull();
411     }
412 
413     @Test
getPreferences_noTileForCategory_shouldReturnNull()414     public void getPreferences_noTileForCategory_shouldReturnNull() {
415         mImpl = new DashboardFeatureProviderImpl(mActivity);
416         ReflectionHelpers.setField(mImpl, "mCategoryManager", mCategoryManager);
417         when(mCategoryManager.getTilesByCategory(mActivity, CategoryKey.CATEGORY_HOMEPAGE))
418                 .thenReturn(new DashboardCategory());
419 
420         assertThat(mImpl.getPreferencesForCategory(null, null,
421                 MetricsProto.MetricsEvent.SETTINGS_GESTURES, CategoryKey.CATEGORY_HOMEPAGE))
422                 .isNull();
423     }
424 
425     @Test
getPreferences_hasTileForCategory_shouldReturnPrefList()426     public void getPreferences_hasTileForCategory_shouldReturnPrefList() {
427         mImpl = new DashboardFeatureProviderImpl(mActivity);
428         ReflectionHelpers.setField(mImpl, "mCategoryManager", mCategoryManager);
429         final DashboardCategory category = new DashboardCategory();
430         category.addTile(new Tile());
431         when(mCategoryManager
432                 .getTilesByCategory(any(Context.class), eq(CategoryKey.CATEGORY_HOMEPAGE)))
433                 .thenReturn(category);
434 
435         assertThat(mImpl.getPreferencesForCategory(mActivity,
436                 ShadowApplication.getInstance().getApplicationContext(),
437                 MetricsProto.MetricsEvent.SETTINGS_GESTURES,
438                 CategoryKey.CATEGORY_HOMEPAGE).isEmpty())
439                 .isFalse();
440     }
441 
442     @Test
testGetExtraIntentAction_shouldReturnNull()443     public void testGetExtraIntentAction_shouldReturnNull() {
444         assertThat(mImpl.getExtraIntentAction()).isNull();
445     }
446 
447     @Test
testShouldTintIcon_enabledInResources_shouldBeTrue()448     public void testShouldTintIcon_enabledInResources_shouldBeTrue() {
449         assertThat(mImpl.shouldTintIcon()).isTrue();
450     }
451 
452     @Test
453     @Config(qualifiers = "mcc999")
testShouldTintIcon_disabledInResources_shouldBeFalse()454     public void testShouldTintIcon_disabledInResources_shouldBeFalse() {
455         assertThat(mImpl.shouldTintIcon()).isFalse();
456     }
457 }
458