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 android.content.Intent.EXTRA_USER; 20 21 import static com.android.settingslib.drawer.SwitchesProvider.EXTRA_SWITCH_SET_CHECKED_ERROR; 22 import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_ORDER; 23 import static com.android.settingslib.drawer.TileUtils.META_DATA_KEY_PROFILE; 24 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_KEYHINT; 25 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY; 26 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SWITCH_URI; 27 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE; 28 import static com.android.settingslib.drawer.TileUtils.PROFILE_ALL; 29 import static com.android.settingslib.drawer.TileUtils.PROFILE_PRIMARY; 30 31 import static com.google.common.truth.Truth.assertThat; 32 33 import static org.mockito.ArgumentMatchers.any; 34 import static org.mockito.ArgumentMatchers.anyInt; 35 import static org.mockito.ArgumentMatchers.eq; 36 import static org.mockito.Mockito.doReturn; 37 import static org.mockito.Mockito.mock; 38 import static org.mockito.Mockito.never; 39 import static org.mockito.Mockito.spy; 40 import static org.mockito.Mockito.verify; 41 import static org.mockito.Mockito.verifyZeroInteractions; 42 import static org.mockito.Mockito.when; 43 44 import android.content.Context; 45 import android.content.Intent; 46 import android.content.pm.ActivityInfo; 47 import android.content.pm.PackageManager; 48 import android.content.pm.ProviderInfo; 49 import android.content.pm.ResolveInfo; 50 import android.graphics.Bitmap; 51 import android.graphics.drawable.Icon; 52 import android.os.Bundle; 53 import android.os.UserHandle; 54 import android.os.UserManager; 55 56 import androidx.fragment.app.FragmentActivity; 57 import androidx.preference.Preference; 58 import androidx.preference.SwitchPreference; 59 60 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 61 import com.android.settings.R; 62 import com.android.settings.SettingsActivity; 63 import com.android.settings.testutils.FakeFeatureFactory; 64 import com.android.settings.testutils.shadow.ShadowTileUtils; 65 import com.android.settings.testutils.shadow.ShadowUserManager; 66 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; 67 import com.android.settingslib.drawer.ActivityTile; 68 import com.android.settingslib.drawer.CategoryKey; 69 import com.android.settingslib.drawer.ProviderTile; 70 import com.android.settingslib.drawer.Tile; 71 import com.android.settingslib.drawer.TileUtils; 72 73 import org.junit.Before; 74 import org.junit.Test; 75 import org.junit.runner.RunWith; 76 import org.mockito.Answers; 77 import org.mockito.ArgumentCaptor; 78 import org.mockito.Mock; 79 import org.mockito.MockitoAnnotations; 80 import org.robolectric.Robolectric; 81 import org.robolectric.RobolectricTestRunner; 82 import org.robolectric.RuntimeEnvironment; 83 import org.robolectric.Shadows; 84 import org.robolectric.annotation.Config; 85 import org.robolectric.shadows.ShadowActivity; 86 import org.robolectric.util.ReflectionHelpers; 87 88 import java.util.ArrayList; 89 import java.util.List; 90 91 @RunWith(RobolectricTestRunner.class) 92 @Config(shadows = ShadowUserManager.class) 93 public class DashboardFeatureProviderImplTest { 94 95 private static final String KEY = "key"; 96 private static final String SWITCH_URI = "content://com.android.settings/tile_switch"; 97 98 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 99 private FragmentActivity mActivity; 100 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 101 private UserManager mUserManager; 102 @Mock 103 private PackageManager mPackageManager; 104 private FakeFeatureFactory mFeatureFactory; 105 106 private Context mContext; 107 private ActivityInfo mActivityInfo; 108 private ProviderInfo mProviderInfo; 109 private Bundle mSwitchMetaData; 110 private DashboardFeatureProviderImpl mImpl; 111 private boolean mForceRoundedIcon; 112 113 @Before setUp()114 public void setUp() { 115 MockitoAnnotations.initMocks(this); 116 mContext = spy(RuntimeEnvironment.application); 117 doReturn(RuntimeEnvironment.application).when(mActivity).getApplicationContext(); 118 mForceRoundedIcon = false; 119 mActivityInfo = new ActivityInfo(); 120 mActivityInfo.packageName = mContext.getPackageName(); 121 mActivityInfo.name = "class"; 122 mActivityInfo.metaData = new Bundle(); 123 mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_TITLE, R.string.settings_label); 124 mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_SUMMARY, 125 R.string.about_settings_summary); 126 127 mProviderInfo = new ProviderInfo(); 128 mProviderInfo.packageName = mContext.getPackageName(); 129 mProviderInfo.name = "provider"; 130 mProviderInfo.authority = "com.android.settings"; 131 mSwitchMetaData = new Bundle(); 132 mSwitchMetaData.putInt(META_DATA_PREFERENCE_TITLE, R.string.settings_label); 133 mSwitchMetaData.putInt(META_DATA_PREFERENCE_SUMMARY, R.string.about_settings_summary); 134 mSwitchMetaData.putString(META_DATA_PREFERENCE_KEYHINT, KEY); 135 mSwitchMetaData.putString(META_DATA_PREFERENCE_SWITCH_URI, SWITCH_URI); 136 137 doReturn(mPackageManager).when(mContext).getPackageManager(); 138 when(mPackageManager.resolveActivity(any(Intent.class), anyInt())) 139 .thenReturn(new ResolveInfo()); 140 mFeatureFactory = FakeFeatureFactory.setupForTest(); 141 mImpl = new DashboardFeatureProviderImpl(mContext); 142 } 143 144 @Test shouldHoldAppContext()145 public void shouldHoldAppContext() { 146 assertThat(mImpl.mContext).isEqualTo(mContext.getApplicationContext()); 147 } 148 149 @Test bindPreference_shouldBindAllData()150 public void bindPreference_shouldBindAllData() { 151 final Preference preference = new Preference(RuntimeEnvironment.application); 152 final Tile tile = spy(new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); 153 mActivityInfo.metaData.putInt(META_DATA_KEY_ORDER, 10); 154 doReturn(Icon.createWithBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565))) 155 .when(tile).getIcon(any(Context.class)); 156 mActivityInfo.metaData.putString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS, "HI"); 157 mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon, 158 MetricsEvent.SETTINGS_GESTURES, preference, tile, "123", Preference.DEFAULT_ORDER); 159 160 assertThat(preference.getTitle()).isEqualTo(mContext.getText(R.string.settings_label)); 161 assertThat(preference.getSummary()) 162 .isEqualTo(mContext.getText(R.string.about_settings_summary)); 163 assertThat(preference.getIcon()).isNotNull(); 164 assertThat(preference.getFragment()).isEqualTo( 165 mActivityInfo.metaData.getString(SettingsActivity.META_DATA_KEY_FRAGMENT_CLASS)); 166 assertThat(preference.getOrder()).isEqualTo(tile.getOrder()); 167 } 168 169 @Test bindPreference_shouldBindAllSwitchData()170 public void bindPreference_shouldBindAllSwitchData() { 171 final Preference preference = new SwitchPreference(RuntimeEnvironment.application); 172 final Tile tile = spy(new ProviderTile(mProviderInfo, CategoryKey.CATEGORY_HOMEPAGE, 173 mSwitchMetaData)); 174 mSwitchMetaData.putInt(META_DATA_KEY_ORDER, 10); 175 doReturn(Icon.createWithBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565))) 176 .when(tile).getIcon(any(Context.class)); 177 final List<DynamicDataObserver> observers = mImpl.bindPreferenceToTileAndGetObservers( 178 mActivity, mForceRoundedIcon, MetricsEvent.SETTINGS_GESTURES, preference, tile, 179 null /* key*/, Preference.DEFAULT_ORDER); 180 181 assertThat(preference.getTitle()).isEqualTo(mContext.getText(R.string.settings_label)); 182 assertThat(preference.getSummary()) 183 .isEqualTo(mContext.getText(R.string.about_settings_summary)); 184 assertThat(preference.getKey()).isEqualTo(KEY); 185 assertThat(preference.getIcon()).isNotNull(); 186 assertThat(preference.getOrder()).isEqualTo(tile.getOrder()); 187 assertThat(observers.get(0).getUri().toString()).isEqualTo(SWITCH_URI); 188 } 189 190 @Test bindPreference_noFragmentMetadata_shouldBindIntent()191 public void bindPreference_noFragmentMetadata_shouldBindIntent() { 192 final Preference preference = new Preference(RuntimeEnvironment.application); 193 mActivityInfo.metaData.putInt(META_DATA_KEY_ORDER, 10); 194 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 195 196 mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon, 197 MetricsEvent.SETTINGS_GESTURES, preference, tile, "123", Preference.DEFAULT_ORDER); 198 199 assertThat(preference.getFragment()).isNull(); 200 assertThat(preference.getOnPreferenceClickListener()).isNotNull(); 201 assertThat(preference.getOrder()).isEqualTo(tile.getOrder()); 202 } 203 204 @Test bindPreference_noFragmentMetadata_shouldBindToProfileSelector()205 public void bindPreference_noFragmentMetadata_shouldBindToProfileSelector() { 206 final Preference preference = new Preference(RuntimeEnvironment.application); 207 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 208 tile.userHandle = new ArrayList<>(); 209 tile.userHandle.add(mock(UserHandle.class)); 210 tile.userHandle.add(mock(UserHandle.class)); 211 212 mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon, 213 MetricsEvent.SETTINGS_GESTURES, preference, tile, "123", Preference.DEFAULT_ORDER); 214 preference.getOnPreferenceClickListener().onPreferenceClick(null); 215 216 verify(mActivity).getSupportFragmentManager(); 217 } 218 219 @Test bindPreference_noFragmentMetadataSingleUser_shouldBindToDirectLaunchIntent()220 public void bindPreference_noFragmentMetadataSingleUser_shouldBindToDirectLaunchIntent() { 221 final Preference preference = new Preference(RuntimeEnvironment.application); 222 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 223 tile.userHandle = new ArrayList<>(); 224 tile.userHandle.add(mock(UserHandle.class)); 225 226 when(mActivity.getSystemService(Context.USER_SERVICE)) 227 .thenReturn(mUserManager); 228 229 mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon, 230 MetricsEvent.SETTINGS_GESTURES, preference, tile, "123", Preference.DEFAULT_ORDER); 231 preference.getOnPreferenceClickListener().onPreferenceClick(null); 232 233 verify(mFeatureFactory.metricsFeatureProvider).logStartedIntent( 234 any(Intent.class), 235 eq(MetricsEvent.SETTINGS_GESTURES)); 236 verify(mActivity) 237 .startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class)); 238 } 239 240 @Test bindPreference_toInternalSettingActivity_shouldBindToDirectLaunchIntentAndNotLog()241 public void bindPreference_toInternalSettingActivity_shouldBindToDirectLaunchIntentAndNotLog() { 242 final Preference preference = new Preference(RuntimeEnvironment.application); 243 mActivityInfo.packageName = RuntimeEnvironment.application.getPackageName(); 244 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 245 tile.userHandle = new ArrayList<>(); 246 tile.userHandle.add(mock(UserHandle.class)); 247 248 mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon, 249 MetricsEvent.SETTINGS_GESTURES, preference, tile, "123", Preference.DEFAULT_ORDER); 250 preference.getOnPreferenceClickListener().onPreferenceClick(null); 251 verify(mFeatureFactory.metricsFeatureProvider).logStartedIntent( 252 any(Intent.class), 253 anyInt()); 254 verify(mActivity) 255 .startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class)); 256 } 257 258 @Test bindPreference_nullPreference_shouldIgnore()259 public void bindPreference_nullPreference_shouldIgnore() { 260 final Tile tile = mock(Tile.class); 261 mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon, 262 MetricsEvent.VIEW_UNKNOWN, null, tile, "123", Preference.DEFAULT_ORDER); 263 264 verifyZeroInteractions(tile); 265 } 266 267 @Test bindPreference_withNullKeyNullPriority_shouldGenerateKeyAndPriority()268 public void bindPreference_withNullKeyNullPriority_shouldGenerateKeyAndPriority() { 269 final Preference preference = new Preference(RuntimeEnvironment.application); 270 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 271 mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon, 272 MetricsEvent.VIEW_UNKNOWN, preference, tile, null /*key */, 273 Preference.DEFAULT_ORDER); 274 275 assertThat(preference.getKey()).isNotNull(); 276 assertThat(preference.getOrder()).isEqualTo(Preference.DEFAULT_ORDER); 277 } 278 279 @Test bindPreference_noSummary_shouldSetSummaryToPlaceholder()280 public void bindPreference_noSummary_shouldSetSummaryToPlaceholder() { 281 final Preference preference = new Preference(RuntimeEnvironment.application); 282 mActivityInfo.metaData.remove(META_DATA_PREFERENCE_SUMMARY); 283 284 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 285 286 mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon, 287 MetricsEvent.VIEW_UNKNOWN, preference, tile, null /*key */, 288 Preference.DEFAULT_ORDER); 289 290 assertThat(preference.getSummary()) 291 .isEqualTo(RuntimeEnvironment.application.getString(R.string.summary_placeholder)); 292 } 293 294 @Test 295 @Config(shadows = {ShadowTileUtils.class}) bindPreference_hasSummaryUri_shouldLoadSummaryFromContentProviderAndHaveObserver()296 public void bindPreference_hasSummaryUri_shouldLoadSummaryFromContentProviderAndHaveObserver() { 297 final Preference preference = new Preference(RuntimeEnvironment.application); 298 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 299 final String uriString = "content://com.android.settings/tile_summary"; 300 mActivityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, uriString); 301 302 final List<DynamicDataObserver> observers = mImpl.bindPreferenceToTileAndGetObservers( 303 mActivity, mForceRoundedIcon, MetricsEvent.VIEW_UNKNOWN, preference, tile, 304 null /*key */, Preference.DEFAULT_ORDER); 305 306 assertThat(preference.getSummary()).isEqualTo(ShadowTileUtils.MOCK_SUMMARY); 307 assertThat(observers.get(0).getUri().toString()).isEqualTo(uriString); 308 } 309 310 @Test 311 @Config(shadows = {ShadowTileUtils.class}) bindPreference_hasTitleUri_shouldLoadFromContentProviderAndHaveObserver()312 public void bindPreference_hasTitleUri_shouldLoadFromContentProviderAndHaveObserver() { 313 final Preference preference = new Preference(RuntimeEnvironment.application); 314 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 315 final String uriString = "content://com.android.settings/tile_title"; 316 mActivityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_TITLE_URI, uriString); 317 318 final List<DynamicDataObserver> observers = mImpl.bindPreferenceToTileAndGetObservers( 319 mActivity, mForceRoundedIcon, MetricsEvent.VIEW_UNKNOWN, preference, tile, 320 null /*key */, Preference.DEFAULT_ORDER); 321 322 assertThat(preference.getTitle()).isEqualTo(ShadowTileUtils.MOCK_SUMMARY); 323 assertThat(observers.get(0).getUri().toString()).isEqualTo(uriString); 324 } 325 326 @Test 327 @Config(shadows = {ShadowTileUtils.class}) bindPreference_onCheckedChanged_shouldPutStateToContentProvider()328 public void bindPreference_onCheckedChanged_shouldPutStateToContentProvider() { 329 final SwitchPreference preference = new SwitchPreference(RuntimeEnvironment.application); 330 final Tile tile = new ProviderTile(mProviderInfo, CategoryKey.CATEGORY_HOMEPAGE, 331 mSwitchMetaData); 332 final Bundle bundle = new Bundle(); 333 bundle.putBoolean(EXTRA_SWITCH_SET_CHECKED_ERROR, false); 334 ShadowTileUtils.setResultBundle(bundle); 335 mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon, 336 MetricsEvent.VIEW_UNKNOWN, preference, tile, null /*key */, 337 Preference.DEFAULT_ORDER); 338 339 preference.callChangeListener(false); 340 341 assertThat(ShadowTileUtils.getProviderChecked()).isFalse(); 342 343 preference.callChangeListener(true); 344 345 assertThat(ShadowTileUtils.getProviderChecked()).isTrue(); 346 } 347 348 @Test 349 @Config(shadows = {ShadowTileUtils.class}) bindPreference_onCheckedChangedError_shouldRevertCheckedState()350 public void bindPreference_onCheckedChangedError_shouldRevertCheckedState() { 351 final SwitchPreference preference = new SwitchPreference(RuntimeEnvironment.application); 352 final Tile tile = new ProviderTile(mProviderInfo, CategoryKey.CATEGORY_HOMEPAGE, 353 mSwitchMetaData); 354 final Bundle bundle = new Bundle(); 355 bundle.putBoolean(EXTRA_SWITCH_SET_CHECKED_ERROR, true); 356 ShadowTileUtils.setResultBundle(bundle); 357 mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon, 358 MetricsEvent.VIEW_UNKNOWN, preference, tile, null /*key */, 359 Preference.DEFAULT_ORDER); 360 361 preference.callChangeListener(true); 362 363 assertThat(preference.isChecked()).isFalse(); 364 365 preference.callChangeListener(false); 366 367 assertThat(preference.isChecked()).isTrue(); 368 } 369 370 @Test 371 @Config(shadows = {ShadowTileUtils.class}) bindPreference_callbackOnChanged_shouldLoadFromContentProvider()372 public void bindPreference_callbackOnChanged_shouldLoadFromContentProvider() { 373 final SwitchPreference preference = new SwitchPreference(RuntimeEnvironment.application); 374 final Tile tile = new ProviderTile(mProviderInfo, CategoryKey.CATEGORY_HOMEPAGE, 375 mSwitchMetaData); 376 final List<DynamicDataObserver> observers = mImpl.bindPreferenceToTileAndGetObservers( 377 mActivity, mForceRoundedIcon, MetricsEvent.VIEW_UNKNOWN, preference, tile, 378 null /*key */, Preference.DEFAULT_ORDER); 379 380 ShadowTileUtils.setProviderChecked(false); 381 observers.get(0).onDataChanged(); 382 383 assertThat(preference.isChecked()).isFalse(); 384 385 ShadowTileUtils.setProviderChecked(true); 386 observers.get(0).onDataChanged(); 387 388 assertThat(preference.isChecked()).isTrue(); 389 } 390 391 @Test bindPreference_withNullKeyTileKey_shouldUseTileKey()392 public void bindPreference_withNullKeyTileKey_shouldUseTileKey() { 393 final Preference preference = new Preference(RuntimeEnvironment.application); 394 mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "key"); 395 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 396 mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon, 397 MetricsEvent.VIEW_UNKNOWN, preference, tile, null /* key */, 398 Preference.DEFAULT_ORDER); 399 400 assertThat(preference.getKey()).isEqualTo(tile.getKey(mContext)); 401 } 402 403 @Test 404 @Config(shadows = {ShadowTileUtils.class}) bindPreference_withIconUri_shouldLoadIconFromContentProvider()405 public void bindPreference_withIconUri_shouldLoadIconFromContentProvider() { 406 final Preference preference = new Preference(RuntimeEnvironment.application); 407 mActivityInfo.packageName = RuntimeEnvironment.application.getPackageName(); 408 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 409 mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "key"); 410 mActivityInfo.metaData.putString(TileUtils.META_DATA_PREFERENCE_ICON_URI, 411 "content://com.android.settings/tile_icon"); 412 mImpl.bindIcon(preference, tile, false /* forceRoundedIcon */); 413 414 assertThat(preference.getIcon()).isNotNull(); 415 } 416 417 @Test bindPreference_withBaseOrder_shouldOffsetOrder()418 public void bindPreference_withBaseOrder_shouldOffsetOrder() { 419 final int baseOrder = 100; 420 final Preference preference = new Preference(RuntimeEnvironment.application); 421 mActivityInfo.metaData.putInt(META_DATA_KEY_ORDER, 10); 422 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 423 424 mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon, 425 MetricsEvent.VIEW_UNKNOWN, preference, tile, "123", baseOrder); 426 427 assertThat(preference.getOrder()).isEqualTo(tile.getOrder() + baseOrder); 428 } 429 430 @Test bindPreference_withOrderMetadata_shouldUseOrderInMetadata()431 public void bindPreference_withOrderMetadata_shouldUseOrderInMetadata() { 432 final Preference preference = new Preference(RuntimeEnvironment.application); 433 final int testOrder = -30; 434 mActivityInfo.metaData.putInt(META_DATA_KEY_ORDER, 10); 435 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 436 mActivityInfo.metaData.putInt(META_DATA_KEY_ORDER, testOrder); 437 mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon, 438 MetricsEvent.VIEW_UNKNOWN, preference, tile, "123", Preference.DEFAULT_ORDER); 439 440 assertThat(preference.getOrder()).isEqualTo(testOrder); 441 } 442 443 @Test bindPreference_invalidOrderMetadata_shouldIgnore()444 public void bindPreference_invalidOrderMetadata_shouldIgnore() { 445 final Preference preference = new Preference(RuntimeEnvironment.application); 446 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 447 mActivityInfo.metaData.putString(META_DATA_KEY_ORDER, "hello"); 448 449 mImpl.bindPreferenceToTileAndGetObservers(mActivity, mForceRoundedIcon, 450 MetricsEvent.VIEW_UNKNOWN, preference, tile, "123", Preference.DEFAULT_ORDER); 451 452 assertThat(preference.getOrder()).isEqualTo(Preference.DEFAULT_ORDER); 453 } 454 455 @Test bindPreference_withIntentActionMetadata_shouldSetLaunchAction()456 public void bindPreference_withIntentActionMetadata_shouldSetLaunchAction() { 457 FragmentActivity activity = Robolectric.buildActivity(FragmentActivity.class).get(); 458 final Preference preference = new Preference(RuntimeEnvironment.application); 459 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 460 mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "key"); 461 mActivityInfo.metaData.putString("com.android.settings.intent.action", "TestAction"); 462 tile.userHandle = null; 463 mImpl.bindPreferenceToTileAndGetObservers(activity, mForceRoundedIcon, 464 MetricsEvent.SETTINGS_GESTURES, preference, tile, "123", Preference.DEFAULT_ORDER); 465 preference.performClick(); 466 ShadowActivity shadowActivity = Shadows.shadowOf(activity); 467 468 final Intent launchIntent = shadowActivity.getNextStartedActivityForResult().intent; 469 assertThat(launchIntent.getAction()) 470 .isEqualTo("TestAction"); 471 assertThat( 472 launchIntent.getIntExtra(MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY, 0)) 473 .isEqualTo(MetricsEvent.SETTINGS_GESTURES); 474 } 475 476 @Test clickPreference_withUnresolvableIntent_shouldNotLaunchAnything()477 public void clickPreference_withUnresolvableIntent_shouldNotLaunchAnything() { 478 ReflectionHelpers.setField( 479 mImpl, "mPackageManager", RuntimeEnvironment.application.getPackageManager()); 480 FragmentActivity activity = Robolectric.buildActivity(FragmentActivity.class).get(); 481 final Preference preference = new Preference(RuntimeEnvironment.application); 482 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 483 mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "key"); 484 mActivityInfo.metaData.putString("com.android.settings.intent.action", "TestAction"); 485 tile.userHandle = null; 486 487 mImpl.bindPreferenceToTileAndGetObservers(activity, mForceRoundedIcon, 488 MetricsEvent.SETTINGS_GESTURES, preference, tile, "123", Preference.DEFAULT_ORDER); 489 preference.performClick(); 490 491 final ShadowActivity.IntentForResult launchIntent = 492 Shadows.shadowOf(activity).getNextStartedActivityForResult(); 493 494 assertThat(launchIntent).isNull(); 495 } 496 497 @Test openTileIntent_profileSelectionDialog_shouldShow()498 public void openTileIntent_profileSelectionDialog_shouldShow() { 499 ShadowUserManager.getShadow().addUser(10, "Someone", 0); 500 501 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 502 final ArrayList<UserHandle> handles = new ArrayList<>(); 503 handles.add(new UserHandle(0)); 504 handles.add(new UserHandle(10)); 505 tile.userHandle = handles; 506 mImpl.openTileIntent(mActivity, tile); 507 508 verify(mActivity, never()) 509 .startActivityForResult(any(Intent.class), eq(0)); 510 verify(mActivity).getSupportFragmentManager(); 511 } 512 513 @Test openTileIntent_profileSelectionDialog_explicitMetadataShouldShow()514 public void openTileIntent_profileSelectionDialog_explicitMetadataShouldShow() { 515 ShadowUserManager.getShadow().addUser(10, "Someone", 0); 516 517 mActivityInfo.metaData.putString(META_DATA_KEY_PROFILE, PROFILE_ALL); 518 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 519 final ArrayList<UserHandle> handles = new ArrayList<>(); 520 handles.add(new UserHandle(0)); 521 handles.add(new UserHandle(10)); 522 tile.userHandle = handles; 523 mImpl.openTileIntent(mActivity, tile); 524 525 verify(mActivity, never()) 526 .startActivityForResult(any(Intent.class), eq(0)); 527 verify(mActivity).getSupportFragmentManager(); 528 } 529 530 @Test openTileIntent_profileSelectionDialog_shouldNotShow()531 public void openTileIntent_profileSelectionDialog_shouldNotShow() { 532 ShadowUserManager.getShadow().addUser(10, "Someone", 0); 533 534 mActivityInfo.metaData.putString(META_DATA_KEY_PROFILE, PROFILE_PRIMARY); 535 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 536 final ArrayList<UserHandle> handles = new ArrayList<>(); 537 handles.add(new UserHandle(0)); 538 handles.add(new UserHandle(10)); 539 tile.userHandle = handles; 540 mImpl.openTileIntent(mActivity, tile); 541 542 verify(mActivity) 543 .startActivityForResult(any(Intent.class), eq(0)); 544 verify(mActivity, never()).getSupportFragmentManager(); 545 } 546 547 @Test openTileIntent_profileSelectionDialog_validUserHandleShouldNotShow()548 public void openTileIntent_profileSelectionDialog_validUserHandleShouldNotShow() { 549 final int userId = 10; 550 ShadowUserManager.getShadow().addUser(userId, "Someone", 0); 551 552 final UserHandle userHandle = new UserHandle(userId); 553 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 554 tile.getIntent().putExtra(EXTRA_USER, userHandle); 555 final ArrayList<UserHandle> handles = new ArrayList<>(); 556 handles.add(new UserHandle(0)); 557 handles.add(userHandle); 558 tile.userHandle = handles; 559 560 mImpl.openTileIntent(mActivity, tile); 561 562 final ArgumentCaptor<UserHandle> argument = ArgumentCaptor.forClass(UserHandle.class); 563 verify(mActivity) 564 .startActivityForResultAsUser(any(Intent.class), anyInt(), argument.capture()); 565 assertThat(argument.getValue().getIdentifier()).isEqualTo(userId); 566 verify(mActivity, never()).getSupportFragmentManager(); 567 } 568 569 @Test openTileIntent_profileSelectionDialog_invalidUserHandleShouldShow()570 public void openTileIntent_profileSelectionDialog_invalidUserHandleShouldShow() { 571 ShadowUserManager.getShadow().addUser(10, "Someone", 0); 572 573 final Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); 574 tile.getIntent().putExtra(EXTRA_USER, new UserHandle(30)); 575 final ArrayList<UserHandle> handles = new ArrayList<>(); 576 handles.add(new UserHandle(0)); 577 handles.add(new UserHandle(10)); 578 tile.userHandle = handles; 579 580 mImpl.openTileIntent(mActivity, tile); 581 582 verify(mActivity, never()) 583 .startActivityForResultAsUser(any(Intent.class), anyInt(), any(UserHandle.class)); 584 verify(mActivity).getSupportFragmentManager(); 585 } 586 } 587