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 android.app.Activity; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.graphics.Bitmap; 24 import android.graphics.drawable.Icon; 25 import android.os.Bundle; 26 import android.os.UserHandle; 27 import android.os.UserManager; 28 import android.support.v7.preference.Preference; 29 30 import com.android.internal.logging.nano.MetricsProto; 31 import com.android.settings.R; 32 import com.android.settings.SettingsActivity; 33 import com.android.settings.SettingsRobolectricTestRunner; 34 import com.android.settings.TestConfig; 35 import com.android.settings.testutils.FakeFeatureFactory; 36 import com.android.settings.testutils.shadow.ShadowUserManager; 37 import com.android.settingslib.drawer.CategoryKey; 38 import com.android.settingslib.drawer.CategoryManager; 39 import com.android.settingslib.drawer.DashboardCategory; 40 import com.android.settingslib.drawer.Tile; 41 42 import org.junit.Before; 43 import org.junit.Test; 44 import org.junit.runner.RunWith; 45 import org.mockito.Answers; 46 import org.mockito.Mock; 47 import org.mockito.MockitoAnnotations; 48 import org.robolectric.Robolectric; 49 import org.robolectric.RuntimeEnvironment; 50 import org.robolectric.annotation.Config; 51 import org.robolectric.shadows.ShadowActivity; 52 import org.robolectric.shadows.ShadowApplication; 53 import org.robolectric.util.ReflectionHelpers; 54 55 import java.util.ArrayList; 56 57 import static com.google.common.truth.Truth.assertThat; 58 import static org.mockito.Matchers.any; 59 import static org.mockito.Matchers.anyInt; 60 import static org.mockito.Matchers.eq; 61 import static org.mockito.Mockito.mock; 62 import static org.mockito.Mockito.verify; 63 import static org.mockito.Mockito.when; 64 import static org.robolectric.Shadows.shadowOf; 65 66 @RunWith(SettingsRobolectricTestRunner.class) 67 @Config(manifest = TestConfig.MANIFEST_PATH, 68 sdk = TestConfig.SDK_VERSION, 69 shadows = ShadowUserManager.class) 70 public class DashboardFeatureProviderImplTest { 71 72 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 73 private Activity mActivity; 74 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 75 private UserManager mUserManager; 76 @Mock 77 private CategoryManager mCategoryManager; 78 private FakeFeatureFactory mFeatureFactory; 79 80 private DashboardFeatureProviderImpl mImpl; 81 82 @Before 83 public void setUp() { 84 MockitoAnnotations.initMocks(this); 85 FakeFeatureFactory.setupForTest(mActivity); 86 mFeatureFactory = (FakeFeatureFactory) FakeFeatureFactory.getFactory(mActivity); 87 mImpl = new DashboardFeatureProviderImpl(mActivity); 88 } 89 90 @Test 91 public void shouldHoldAppContext() { 92 assertThat(mImpl.mContext).isEqualTo(mActivity.getApplicationContext()); 93 } 94 95 @Test 96 public void bindPreference_shouldBindAllData() { 97 final Preference preference = new Preference( 98 ShadowApplication.getInstance().getApplicationContext()); 99 final Tile tile = new Tile(); 100 tile.title = "title"; 101 tile.summary = "summary"; 102 tile.icon = Icon.createWithBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565)); 103 tile.metaData = new Bundle(); 104 tile.metaData.putString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS, "HI"); 105 tile.priority = 10; 106 mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.SETTINGS_GESTURES, 107 preference, tile, "123", Preference.DEFAULT_ORDER); 108 109 assertThat(preference.getTitle()).isEqualTo(tile.title); 110 assertThat(preference.getSummary()).isEqualTo(tile.summary); 111 assertThat(preference.getIcon()).isNotNull(); 112 assertThat(preference.getFragment()) 113 .isEqualTo(tile.metaData.getString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS)); 114 assertThat(preference.getOrder()).isEqualTo(-tile.priority); 115 } 116 117 @Test 118 public void bindPreference_noFragmentMetadata_shouldBindIntent() { 119 final Preference preference = new Preference( 120 ShadowApplication.getInstance().getApplicationContext()); 121 final Tile tile = new Tile(); 122 tile.metaData = new Bundle(); 123 tile.priority = 10; 124 tile.intent = new Intent(); 125 tile.intent.setComponent(new ComponentName("pkg", "class")); 126 127 mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.SETTINGS_GESTURES, 128 preference, tile, "123", Preference.DEFAULT_ORDER); 129 130 assertThat(preference.getFragment()).isNull(); 131 assertThat(preference.getOnPreferenceClickListener()).isNotNull(); 132 assertThat(preference.getOrder()).isEqualTo(-tile.priority); 133 } 134 135 @Test 136 public void bindPreference_noFragmentMetadata_shouldBindToProfileSelector() { 137 final Preference preference = new Preference(RuntimeEnvironment.application); 138 final Tile tile = new Tile(); 139 tile.metaData = new Bundle(); 140 tile.userHandle = new ArrayList<>(); 141 tile.userHandle.add(mock(UserHandle.class)); 142 tile.userHandle.add(mock(UserHandle.class)); 143 tile.intent = new Intent(); 144 tile.intent.setComponent(new ComponentName("pkg", "class")); 145 146 when(mActivity.getApplicationContext().getSystemService(Context.USER_SERVICE)) 147 .thenReturn(mUserManager); 148 149 mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.SETTINGS_GESTURES, 150 preference, tile, "123", Preference.DEFAULT_ORDER); 151 preference.getOnPreferenceClickListener().onPreferenceClick(null); 152 153 verify(mActivity).getFragmentManager(); 154 } 155 156 @Test 157 public void bindPreference_noFragmentMetadataSingleUser_shouldBindToDirectLaunchIntent() { 158 final Preference preference = new Preference(RuntimeEnvironment.application); 159 final Tile tile = new Tile(); 160 tile.metaData = new Bundle(); 161 tile.userHandle = new ArrayList<>(); 162 tile.userHandle.add(mock(UserHandle.class)); 163 tile.intent = new Intent(); 164 tile.intent.setComponent(new ComponentName("pkg", "class")); 165 166 when(mActivity.getSystemService(Context.USER_SERVICE)) 167 .thenReturn(mUserManager); 168 169 mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.SETTINGS_GESTURES, 170 preference, tile, "123", Preference.DEFAULT_ORDER); 171 preference.getOnPreferenceClickListener().onPreferenceClick(null); 172 173 verify(mFeatureFactory.metricsFeatureProvider).logDashboardStartIntent( 174 any(Context.class), 175 any(Intent.class), 176 eq(MetricsProto.MetricsEvent.SETTINGS_GESTURES)); 177 verify(mActivity) 178 .startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class)); 179 } 180 181 @Test 182 public void bindPreference_toInternalSettingActivity_shouldBindToDirectLaunchIntentAndNotLog() { 183 final Preference preference = new Preference(RuntimeEnvironment.application); 184 final Tile tile = new Tile(); 185 tile.metaData = new Bundle(); 186 tile.userHandle = new ArrayList<>(); 187 tile.userHandle.add(mock(UserHandle.class)); 188 tile.intent = new Intent(); 189 tile.intent.setComponent( 190 new ComponentName(RuntimeEnvironment.application.getPackageName(), "class")); 191 192 when(mActivity.getSystemService(Context.USER_SERVICE)) 193 .thenReturn(mUserManager); 194 when(mActivity.getApplicationContext().getPackageName()) 195 .thenReturn(RuntimeEnvironment.application.getPackageName()); 196 197 mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.SETTINGS_GESTURES, 198 preference, tile, "123", Preference.DEFAULT_ORDER); 199 preference.getOnPreferenceClickListener().onPreferenceClick(null); 200 verify(mFeatureFactory.metricsFeatureProvider).logDashboardStartIntent( 201 any(Context.class), 202 any(Intent.class), 203 anyInt()); 204 verify(mActivity) 205 .startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class)); 206 } 207 208 @Test 209 public void bindPreference_withNullKeyNullPriority_shouldGenerateKeyAndPriority() { 210 final Preference preference = new Preference(RuntimeEnvironment.application); 211 final Tile tile = new Tile(); 212 tile.intent = new Intent(); 213 tile.intent.setComponent(new ComponentName("pkg", "class")); 214 mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN, 215 preference, tile, null /*key */, Preference.DEFAULT_ORDER); 216 217 assertThat(preference.getKey()).isNotNull(); 218 assertThat(preference.getOrder()).isEqualTo(Preference.DEFAULT_ORDER); 219 } 220 221 @Test 222 public void bindPreference_noSummary_shouldSetSummaryToPlaceholder() { 223 final Preference preference = new Preference(RuntimeEnvironment.application); 224 final Tile tile = new Tile(); 225 tile.intent = new Intent(); 226 tile.intent.setComponent(new ComponentName("pkg", "class")); 227 mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN, 228 preference, tile, null /*key */, Preference.DEFAULT_ORDER); 229 230 assertThat(preference.getSummary()) 231 .isEqualTo(RuntimeEnvironment.application.getString(R.string.summary_placeholder)); 232 } 233 234 @Test 235 public void bindPreference_hasSummary_shouldSetSummary() { 236 final Preference preference = new Preference(RuntimeEnvironment.application); 237 final Tile tile = new Tile(); 238 tile.summary = "test"; 239 tile.intent = new Intent(); 240 tile.intent.setComponent(new ComponentName("pkg", "class")); 241 mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN, 242 preference, tile, null /*key */, Preference.DEFAULT_ORDER); 243 244 assertThat(preference.getSummary()).isEqualTo(tile.summary); 245 } 246 247 @Test 248 public void bindPreference_withNullKeyTileKey_shouldUseTileKey() { 249 final Preference preference = new Preference(RuntimeEnvironment.application); 250 final Tile tile = new Tile(); 251 tile.key = "key"; 252 tile.intent = new Intent(); 253 tile.intent.setComponent(new ComponentName("pkg", "class")); 254 mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN, 255 preference, tile, null /* key */, Preference.DEFAULT_ORDER); 256 257 assertThat(preference.getKey()).isEqualTo(tile.key); 258 } 259 260 @Test 261 public void bindPreference_withBaseOrder_shouldOffsetPriority() { 262 final int baseOrder = 100; 263 final Preference preference = new Preference(RuntimeEnvironment.application); 264 final Tile tile = new Tile(); 265 tile.metaData = new Bundle(); 266 tile.priority = 10; 267 mImpl.bindPreferenceToTile(mActivity, MetricsProto.MetricsEvent.VIEW_UNKNOWN, 268 preference, tile, "123", baseOrder); 269 270 assertThat(preference.getOrder()).isEqualTo(-tile.priority + baseOrder); 271 } 272 273 @Test 274 public void bindPreference_withIntentActionMetatdata_shouldSetLaunchAction() { 275 Activity activity = Robolectric.buildActivity(Activity.class).get(); 276 final ShadowApplication application = ShadowApplication.getInstance(); 277 final Preference preference = new Preference(application.getApplicationContext()); 278 final Tile tile = new Tile(); 279 tile.key = "key"; 280 tile.intent = new Intent(); 281 tile.intent.setComponent(new ComponentName("pkg", "class")); 282 tile.metaData = new Bundle(); 283 tile.metaData.putString("com.android.settings.intent.action", "TestAction"); 284 tile.userHandle = null; 285 mImpl.bindPreferenceToTile(activity, MetricsProto.MetricsEvent.SETTINGS_GESTURES, 286 preference, tile, "123", Preference.DEFAULT_ORDER); 287 preference.performClick(); 288 ShadowActivity shadowActivity = shadowOf(activity); 289 290 final Intent launchIntent = shadowActivity.getNextStartedActivityForResult().intent; 291 assertThat(launchIntent.getAction()) 292 .isEqualTo("TestAction"); 293 assertThat(launchIntent.getIntExtra(SettingsActivity.EXTRA_SOURCE_METRICS_CATEGORY, 0)) 294 .isEqualTo(MetricsProto.MetricsEvent.SETTINGS_GESTURES); 295 } 296 297 @Test 298 public void clickPreference_withUnresolvableIntent_shouldNotLaunchAnything() { 299 ReflectionHelpers.setField( 300 mImpl, "mPackageManager", RuntimeEnvironment.getPackageManager()); 301 Activity activity = Robolectric.buildActivity(Activity.class).get(); 302 final ShadowApplication application = ShadowApplication.getInstance(); 303 final Preference preference = new Preference(application.getApplicationContext()); 304 final Tile tile = new Tile(); 305 tile.key = "key"; 306 tile.intent = new Intent(); 307 tile.intent.setComponent(new ComponentName("pkg", "class")); 308 tile.metaData = new Bundle(); 309 tile.metaData.putString("com.android.settings.intent.action", "TestAction"); 310 tile.userHandle = null; 311 312 mImpl.bindPreferenceToTile(activity, MetricsProto.MetricsEvent.SETTINGS_GESTURES, 313 preference, tile, "123", Preference.DEFAULT_ORDER); 314 preference.performClick(); 315 316 final ShadowActivity.IntentForResult launchIntent = 317 shadowOf(activity).getNextStartedActivityForResult(); 318 319 assertThat(launchIntent).isNull(); 320 } 321 322 @Test 323 public void getPreferences_noCategory_shouldReturnNull() { 324 mImpl = new DashboardFeatureProviderImpl(mActivity); 325 ReflectionHelpers.setField(mImpl, "mCategoryManager", mCategoryManager); 326 when(mCategoryManager.getTilesByCategory(mActivity, CategoryKey.CATEGORY_HOMEPAGE)) 327 .thenReturn(null); 328 329 assertThat(mImpl.getPreferencesForCategory(null, null, 330 MetricsProto.MetricsEvent.SETTINGS_GESTURES, CategoryKey.CATEGORY_HOMEPAGE)) 331 .isNull(); 332 } 333 334 @Test 335 public void getPreferences_noTileForCategory_shouldReturnNull() { 336 mImpl = new DashboardFeatureProviderImpl(mActivity); 337 ReflectionHelpers.setField(mImpl, "mCategoryManager", mCategoryManager); 338 when(mCategoryManager.getTilesByCategory(mActivity, CategoryKey.CATEGORY_HOMEPAGE)) 339 .thenReturn(new DashboardCategory()); 340 341 assertThat(mImpl.getPreferencesForCategory(null, null, 342 MetricsProto.MetricsEvent.SETTINGS_GESTURES, CategoryKey.CATEGORY_HOMEPAGE)) 343 .isNull(); 344 } 345 346 @Test 347 public void getPreferences_hasTileForCategory_shouldReturnPrefList() { 348 mImpl = new DashboardFeatureProviderImpl(mActivity); 349 ReflectionHelpers.setField(mImpl, "mCategoryManager", mCategoryManager); 350 final DashboardCategory category = new DashboardCategory(); 351 category.tiles.add(new Tile()); 352 when(mCategoryManager 353 .getTilesByCategory(any(Context.class), eq(CategoryKey.CATEGORY_HOMEPAGE))) 354 .thenReturn(category); 355 356 assertThat(mImpl.getPreferencesForCategory(mActivity, 357 ShadowApplication.getInstance().getApplicationContext(), 358 MetricsProto.MetricsEvent.SETTINGS_GESTURES, 359 CategoryKey.CATEGORY_HOMEPAGE).isEmpty()) 360 .isFalse(); 361 } 362 363 @Test 364 public void testGetExtraIntentAction_shouldReturnNull() { 365 assertThat(mImpl.getExtraIntentAction()).isNull(); 366 } 367 } 368