diff --git a/Android.mk b/Android.mk index e385b340514..906cfc77432 100644 --- a/Android.mk +++ b/Android.mk @@ -47,6 +47,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \ guava \ jsr305 \ settings-contextual-card-protos-lite \ + settings-log-bridge-protos-lite \ contextualcards \ settings-logtags \ zxing-core-1.7 diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 4166d6f0624..c13068fb29c 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -196,6 +196,19 @@ android:value="true" /> + + + + + + + + + + android:label="@string/assist_and_voice_input_title"> @@ -782,7 +794,8 @@ + android:icon="@drawable/ic_wallpaper" + android:exported="true"> @@ -1381,7 +1394,7 @@ + android:theme="@style/GlifV3Theme.Light"> @@ -2441,6 +2454,18 @@ android:value="true" /> + + + + + + + + - + @@ -3042,9 +3067,8 @@ diff --git a/protos/Android.bp b/protos/Android.bp index 533dbca6564..5184218df63 100644 --- a/protos/Android.bp +++ b/protos/Android.bp @@ -5,4 +5,13 @@ java_library_static { type: "lite", }, srcs: ["contextual_card_list.proto"], +} + +java_library_static { + name: "settings-log-bridge-protos-lite", + host_supported: true, + proto: { + type: "lite", + }, + srcs: ["settings_log_bridge.proto"], } \ No newline at end of file diff --git a/protos/settings_log_bridge.proto b/protos/settings_log_bridge.proto new file mode 100644 index 00000000000..7b28e0d0d0a --- /dev/null +++ b/protos/settings_log_bridge.proto @@ -0,0 +1,37 @@ +syntax = "proto2"; + +package com.android.settings.intelligence; +option java_outer_classname = "LogProto"; + +message SettingsLog { + /** + * Where this SettingsUIChange event comes from. For example, if + * it's a PAGE_VISIBLE event, where the page is opened from. + */ + optional int32 attribution = 1; + + /** + * What the UI action is. + */ + optional int32 action = 2; + + /** + * Where the action is happening + */ + optional int32 page_id = 3; + + /** + * What preference changed in this event. + */ + optional string changed_preference_key = 4; + + /** + * The new value of the changed preference. + */ + optional int32 changed_preference_int_value = 5; + + /** + * The timestamp of a log event + */ + optional string timestamp = 6; +} diff --git a/res/drawable-hdpi/ic_sim_sd.png b/res/drawable-hdpi/ic_sim_sd.png deleted file mode 100644 index 50a16dbbbb8..00000000000 Binary files a/res/drawable-hdpi/ic_sim_sd.png and /dev/null differ diff --git a/res/drawable-mdpi/ic_sim_sd.png b/res/drawable-mdpi/ic_sim_sd.png deleted file mode 100644 index 19266089bcc..00000000000 Binary files a/res/drawable-mdpi/ic_sim_sd.png and /dev/null differ diff --git a/res/drawable-xhdpi/ic_sim_sd.png b/res/drawable-xhdpi/ic_sim_sd.png deleted file mode 100644 index 1a0842b68f1..00000000000 Binary files a/res/drawable-xhdpi/ic_sim_sd.png and /dev/null differ diff --git a/res/drawable-xxhdpi/ic_sim_sd.png b/res/drawable-xxhdpi/ic_sim_sd.png deleted file mode 100644 index e05e7adc254..00000000000 Binary files a/res/drawable-xxhdpi/ic_sim_sd.png and /dev/null differ diff --git a/res/drawable-xxxhdpi/ic_sim_sd.png b/res/drawable-xxxhdpi/ic_sim_sd.png deleted file mode 100644 index b12e34efdfb..00000000000 Binary files a/res/drawable-xxxhdpi/ic_sim_sd.png and /dev/null differ diff --git a/res/drawable/ic_cellular_1_bar.xml b/res/drawable/ic_cellular_1_bar.xml new file mode 100644 index 00000000000..b3d2624fa27 --- /dev/null +++ b/res/drawable/ic_cellular_1_bar.xml @@ -0,0 +1,29 @@ + + + + + diff --git a/res/drawable/ic_color_inversion.xml b/res/drawable/ic_color_inversion.xml index aa59f5a0c4d..5d20d0544b7 100644 --- a/res/drawable/ic_color_inversion.xml +++ b/res/drawable/ic_color_inversion.xml @@ -13,8 +13,8 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - diff --git a/res/drawable/ic_homepage_accessibility.xml b/res/drawable/ic_homepage_accessibility.xml index 39f241b02db..85d4be34873 100644 --- a/res/drawable/ic_homepage_accessibility.xml +++ b/res/drawable/ic_homepage_accessibility.xml @@ -18,7 +18,7 @@ - diff --git a/res/drawable/ic_homepage_accounts.xml b/res/drawable/ic_homepage_accounts.xml index 17408ed936e..3f4f3aba864 100644 --- a/res/drawable/ic_homepage_accounts.xml +++ b/res/drawable/ic_homepage_accounts.xml @@ -18,7 +18,7 @@ - diff --git a/res/drawable/ic_homepage_apps.xml b/res/drawable/ic_homepage_apps.xml index 2a6789c6d80..24a580c3429 100644 --- a/res/drawable/ic_homepage_apps.xml +++ b/res/drawable/ic_homepage_apps.xml @@ -18,7 +18,7 @@ - diff --git a/res/drawable/ic_homepage_battery.xml b/res/drawable/ic_homepage_battery.xml index 87bb5be25f2..0a1f77ae9fb 100644 --- a/res/drawable/ic_homepage_battery.xml +++ b/res/drawable/ic_homepage_battery.xml @@ -18,7 +18,7 @@ - diff --git a/res/drawable/ic_homepage_connected_device.xml b/res/drawable/ic_homepage_connected_device.xml index f3ce1861ca9..a648c449fa3 100644 --- a/res/drawable/ic_homepage_connected_device.xml +++ b/res/drawable/ic_homepage_connected_device.xml @@ -18,7 +18,7 @@ - diff --git a/res/drawable/ic_homepage_display.xml b/res/drawable/ic_homepage_display.xml index fba71491fe7..72db231516a 100644 --- a/res/drawable/ic_homepage_display.xml +++ b/res/drawable/ic_homepage_display.xml @@ -18,7 +18,7 @@ - diff --git a/res/drawable/ic_homepage_location.xml b/res/drawable/ic_homepage_location.xml index c5d6e8970ff..db6a791f1f3 100644 --- a/res/drawable/ic_homepage_location.xml +++ b/res/drawable/ic_homepage_location.xml @@ -18,7 +18,7 @@ - diff --git a/res/drawable/ic_homepage_network.xml b/res/drawable/ic_homepage_network.xml index 1457ab9f7cb..085a6885190 100644 --- a/res/drawable/ic_homepage_network.xml +++ b/res/drawable/ic_homepage_network.xml @@ -18,7 +18,7 @@ - diff --git a/res/drawable/ic_homepage_privacy.xml b/res/drawable/ic_homepage_privacy.xml index a10290517c9..ebf8beb657d 100644 --- a/res/drawable/ic_homepage_privacy.xml +++ b/res/drawable/ic_homepage_privacy.xml @@ -18,7 +18,7 @@ - diff --git a/res/drawable/ic_homepage_security.xml b/res/drawable/ic_homepage_security.xml index 0b6a1fd9734..8a0673c5f7a 100644 --- a/res/drawable/ic_homepage_security.xml +++ b/res/drawable/ic_homepage_security.xml @@ -18,7 +18,7 @@ - diff --git a/res/drawable/ic_homepage_sound.xml b/res/drawable/ic_homepage_sound.xml index 21995c5c8ff..a15f4c634e5 100644 --- a/res/drawable/ic_homepage_sound.xml +++ b/res/drawable/ic_homepage_sound.xml @@ -18,7 +18,7 @@ - diff --git a/res/drawable/ic_homepage_storage.xml b/res/drawable/ic_homepage_storage.xml index 5e5c3ab54d7..11032fa61ed 100644 --- a/res/drawable/ic_homepage_storage.xml +++ b/res/drawable/ic_homepage_storage.xml @@ -18,7 +18,7 @@ - diff --git a/res/drawable/ic_homepage_support.xml b/res/drawable/ic_homepage_support.xml index 906dd6c4779..2e35e4f7d4a 100644 --- a/res/drawable/ic_homepage_support.xml +++ b/res/drawable/ic_homepage_support.xml @@ -18,7 +18,7 @@ - diff --git a/res/drawable/ic_homepage_system_dashboard.xml b/res/drawable/ic_homepage_system_dashboard.xml index 5e9f372504f..add12120ca2 100644 --- a/res/drawable/ic_homepage_system_dashboard.xml +++ b/res/drawable/ic_homepage_system_dashboard.xml @@ -18,7 +18,7 @@ - diff --git a/res/drawable/ic_settings_aod.xml b/res/drawable/ic_settings_aod.xml index 8d9134947ee..b238e3a3201 100644 --- a/res/drawable/ic_settings_aod.xml +++ b/res/drawable/ic_settings_aod.xml @@ -18,7 +18,8 @@ android:width="24dp" android:height="24dp" android:viewportWidth="24" - android:viewportHeight="24"> + android:viewportHeight="24" + android:tint="?android:attr/colorControlNormal"> + android:autoMirrored="true" + android:tint="?android:attr/colorControlNormal"> + + + + diff --git a/res/drawable/ic_settings_enable.xml b/res/drawable/ic_settings_enable.xml new file mode 100644 index 00000000000..560daef774a --- /dev/null +++ b/res/drawable/ic_settings_enable.xml @@ -0,0 +1,25 @@ + + + + + diff --git a/res/drawable/ic_settings_phone_idle.xml b/res/drawable/ic_settings_phone_idle.xml new file mode 100644 index 00000000000..7bb6c3192be --- /dev/null +++ b/res/drawable/ic_settings_phone_idle.xml @@ -0,0 +1,25 @@ + + + + diff --git a/res/drawable/ic_settings_voice_calls.xml b/res/drawable/ic_settings_voice_calls.xml new file mode 100644 index 00000000000..b455f0ab3d8 --- /dev/null +++ b/res/drawable/ic_settings_voice_calls.xml @@ -0,0 +1,25 @@ + + + + diff --git a/res/drawable/ic_sim_sd.xml b/res/drawable/ic_sim_sd.xml new file mode 100644 index 00000000000..d7e31a24809 --- /dev/null +++ b/res/drawable/ic_sim_sd.xml @@ -0,0 +1,27 @@ + + + + + \ No newline at end of file diff --git a/res/layout-land/choose_lock_pattern.xml b/res/layout-land/choose_lock_pattern.xml index 1cc435249c4..5b06f0d8faa 100644 --- a/res/layout-land/choose_lock_pattern.xml +++ b/res/layout-land/choose_lock_pattern.xml @@ -44,7 +44,7 @@ android:orientation="vertical"> - - + diff --git a/res/layout/face_enroll_enrolling.xml b/res/layout/face_enroll_enrolling.xml index e7af493a42e..7e1863b8b6a 100644 --- a/res/layout/face_enroll_enrolling.xml +++ b/res/layout/face_enroll_enrolling.xml @@ -17,7 +17,6 @@ + android:layoutAnimation="@anim/layout_animation_fade_in" + android:importantForAccessibility="no"/> diff --git a/res/layout/storage_wizard_generic.xml b/res/layout/storage_wizard_generic.xml index 2b96101ef0a..e7881d3be87 100644 --- a/res/layout/storage_wizard_generic.xml +++ b/res/layout/storage_wizard_generic.xml @@ -16,7 +16,6 @@ diff --git a/res/layout/storage_wizard_init.xml b/res/layout/storage_wizard_init.xml index d02e871d09f..8d9870f1cec 100644 --- a/res/layout/storage_wizard_init.xml +++ b/res/layout/storage_wizard_init.xml @@ -16,7 +16,6 @@ diff --git a/res/layout/storage_wizard_progress.xml b/res/layout/storage_wizard_progress.xml index cf5bc437ac1..577ec3cbfc8 100644 --- a/res/layout/storage_wizard_progress.xml +++ b/res/layout/storage_wizard_progress.xml @@ -16,7 +16,6 @@ diff --git a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml index 9bd742af0d0..68ba2771ad3 100644 --- a/res/layout/wifi_dpp_qrcode_scanner_fragment.xml +++ b/res/layout/wifi_dpp_qrcode_scanner_fragment.xml @@ -43,18 +43,21 @@ android:layout_marginBottom="8dp" style="?android:attr/progressBarStyleHorizontal"/> - + + android:layout_height="0dp" + app:layout_constraintDimensionRatio="1:1"/> - + android:layout_height="0dp" + app:layout_constraintDimensionRatio="1:1"/> + @android:color/black - #dadce0 #82000000 @android:color/black #783BE5 diff --git a/res/values-night/themes.xml b/res/values-night/themes.xml index 8deae1cb359..2227b889bb3 100644 --- a/res/values-night/themes.xml +++ b/res/values-night/themes.xml @@ -29,9 +29,7 @@ ?android:attr/colorAccent - + + + diff --git a/res/values/themes.xml b/res/values/themes.xml index a8ae50638ee..59b2b9eec1c 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -94,7 +94,7 @@ @@ -103,6 +103,7 @@ @color/switchbar_switch_track_tint @color/switchbar_switch_thumb_tint @dimen/min_tap_target_size + @dimen/min_tap_target_size diff --git a/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java b/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java index f718a67412c..b965d788338 100644 --- a/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java +++ b/tests/robotests/src/com/android/settings/SetupWizardUtilsTest.java @@ -31,24 +31,27 @@ import org.robolectric.RobolectricTestRunner; @RunWith(RobolectricTestRunner.class) public class SetupWizardUtilsTest { + private static final String EXTRA_IS_SETUP_FLOW = "isSetupFlow"; + private static final String EXTRA_IS_FIRST_RUN = "firstRun"; + @Test public void testCopySetupExtras() { Intent fromIntent = new Intent(); final String theme = "TEST_THEME"; fromIntent.putExtra(WizardManagerHelper.EXTRA_THEME, theme); - fromIntent.putExtra(WizardManagerHelper.EXTRA_USE_IMMERSIVE_MODE, true); + fromIntent.putExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, true); Intent toIntent = new Intent(); SetupWizardUtils.copySetupExtras(fromIntent, toIntent); assertThat(theme).isEqualTo(toIntent.getStringExtra(WizardManagerHelper.EXTRA_THEME)); - assertThat(toIntent.getBooleanExtra(WizardManagerHelper.EXTRA_USE_IMMERSIVE_MODE, false)) + assertThat(toIntent.getBooleanExtra(WizardManagerHelper.EXTRA_IS_SETUP_FLOW, false)) .isTrue(); } @Test public void testGetTheme_withIntentExtra_shouldReturnExtraTheme() { SetupWizardProperties.theme(ThemeHelper.THEME_GLIF); - Intent intent = new Intent(); + Intent intent = createSetupWizardIntent(); intent.putExtra(WizardManagerHelper.EXTRA_THEME, ThemeHelper.THEME_GLIF_V2); assertThat(SetupWizardUtils.getTheme(intent)).isEqualTo(R.style.GlifV2Theme); @@ -57,7 +60,7 @@ public class SetupWizardUtilsTest { @Test public void testGetTheme_withEmptyIntent_shouldReturnSystemProperty() { SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V2_LIGHT); - Intent intent = new Intent(); + Intent intent = createSetupWizardIntent(); assertThat(SetupWizardUtils.getTheme(intent)).isEqualTo(R.style.GlifV2Theme_Light); } @@ -65,10 +68,26 @@ public class SetupWizardUtilsTest { @Test public void testGetTheme_glifV3Light_shouldReturnThemeResource() { SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V3_LIGHT); - Intent intent = new Intent(); + Intent intent = createSetupWizardIntent(); assertThat(SetupWizardUtils.getTheme(intent)).isEqualTo(R.style.GlifV3Theme_Light); assertThat(SetupWizardUtils.getTransparentTheme(intent)) .isEqualTo(R.style.GlifV3Theme_Light_Transparent); } + + @Test + public void testGetTheme_nonSuw_shouldReturnDayNightTheme() { + SetupWizardProperties.theme(ThemeHelper.THEME_GLIF_V3_LIGHT); + Intent intent = new Intent(); + + assertThat(SetupWizardUtils.getTheme(intent)).isEqualTo(R.style.GlifV3Theme); + assertThat(SetupWizardUtils.getTransparentTheme(intent)) + .isEqualTo(R.style.GlifV3Theme_Transparent); + } + + private Intent createSetupWizardIntent() { + return new Intent() + .putExtra(EXTRA_IS_SETUP_FLOW, true) + .putExtra(EXTRA_IS_FIRST_RUN, true); + } } diff --git a/tests/robotests/src/com/android/settings/widget/AdaptiveOutlineDrawableTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivityTest.java similarity index 50% rename from tests/robotests/src/com/android/settings/widget/AdaptiveOutlineDrawableTest.java rename to tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivityTest.java index f21fc34e2a8..a0a9de9c88a 100644 --- a/tests/robotests/src/com/android/settings/widget/AdaptiveOutlineDrawableTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivityTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,34 +11,34 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and - * limitations under the License. + * limitations under the License */ -package com.android.settings.widget; +package com.android.settings.accessibility; import static com.google.common.truth.Truth.assertThat; -import android.content.res.Resources; -import android.graphics.Paint; +import android.content.Intent; + +import androidx.test.filters.SmallTest; import com.android.settings.R; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) -public class AdaptiveOutlineDrawableTest { +@SmallTest +public class AccessibilitySettingsForSetupWizardActivityTest { - @Test - public void constructor_initPaint() { - final Resources resources = RuntimeEnvironment.application.getResources(); - final AdaptiveOutlineDrawable drawable = new AdaptiveOutlineDrawable(resources, null); - - assertThat(drawable.mOutlinePaint.getStyle()).isEqualTo(Paint.Style.STROKE); - assertThat(drawable.mOutlinePaint.getStrokeWidth()).isWithin(0.01f).of( - resources.getDimension(R.dimen.adaptive_outline_stroke)); - } + @Test + public void createSetupAccessibilityActivity_shouldBeSUWTheme() { + final Intent intent = new Intent(); + AccessibilitySettingsForSetupWizardActivity activity = + Robolectric.buildActivity(AccessibilitySettingsForSetupWizardActivity.class, intent).get(); + assertThat(activity.getThemeResId()).isEqualTo(R.style.GlifV3Theme_Light); + } } diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java index 8c53019eebb..0cc9dc43375 100644 --- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java @@ -156,7 +156,7 @@ public class AccessibilitySettingsTest { @Test public void testDarkUIModePreferenceSummary_shouldUpdateSummary() { - final ListPreference darkUIModePreference = new ListPreference(mContext); + final Preference darkUIModePreference = new Preference(mContext); final DarkUIPreferenceController mController; doReturn(darkUIModePreference).when(mSettings).findPreference( DARK_UI_MODE_PREFERENCE); diff --git a/tests/robotests/src/com/android/settings/accessibility/LiveCaptionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/LiveCaptionPreferenceControllerTest.java new file mode 100644 index 00000000000..9e0ce9c53bd --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/LiveCaptionPreferenceControllerTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.accessibility; + +import static com.android.settings.core.BasePreferenceController.AVAILABLE; +import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.pm.ResolveInfo; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.Shadows; +import org.robolectric.shadows.ShadowPackageManager; + +import java.util.Collections; + +@RunWith(RobolectricTestRunner.class) +public class LiveCaptionPreferenceControllerTest { + + private LiveCaptionPreferenceController mController; + + @Before + public void setUp() { + mController = new LiveCaptionPreferenceController(RuntimeEnvironment.application, + "test_key"); + } + + @Test + public void getAvailabilityStatus_canResolveIntent_shouldReturnAvailable() { + final ShadowPackageManager pm = Shadows.shadowOf( + RuntimeEnvironment.application.getPackageManager()); + pm.addResolveInfoForIntent(LiveCaptionPreferenceController.LIVE_CAPTION_INTENT, + new ResolveInfo()); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + } + + @Test + public void getAvailabilityStatus_noResolveIntent_shouldReturnUnavailable() { + final ShadowPackageManager pm = Shadows.shadowOf( + RuntimeEnvironment.application.getPackageManager()); + pm.setResolveInfosForIntent(LiveCaptionPreferenceController.LIVE_CAPTION_INTENT, + Collections.emptyList()); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); + } +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java index ebbf5e0269f..fcb7518c270 100644 --- a/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java @@ -265,14 +265,12 @@ public final class ApplicationFeatureProviderImplTest { final String testSms = "com.android.test.defaultsms"; final String testLocationHistory = "com.android.test.location.history"; - final String settingsIntelligence = RuntimeEnvironment.application.getString( - R.string.config_settingsintelligence_package_name); ShadowSmsApplication.setDefaultSmsApplication(new ComponentName(testSms, "receiver")); ShadowDefaultDialerManager.setDefaultDialerApplication(testDialer); // Spy the real context to mock LocationManager. Context spyContext = spy(RuntimeEnvironment.application); - when(mLocationManager.getLocationControllerExtraPackage()).thenReturn(testLocationHistory); + when(mLocationManager.getExtraLocationControllerPackage()).thenReturn(testLocationHistory); when(spyContext.getSystemService(Context.LOCATION_SERVICE)).thenReturn(mLocationManager); ReflectionHelpers.setField(mProvider, "mContext", spyContext); @@ -280,8 +278,52 @@ public final class ApplicationFeatureProviderImplTest { final Set keepEnabledPackages = mProvider.getKeepEnabledPackages(); final List expectedPackages = Arrays.asList(testDialer, testSms, - settingsIntelligence, testLocationHistory); - assertThat(keepEnabledPackages).containsExactlyElementsIn(expectedPackages); + testLocationHistory); + assertThat(keepEnabledPackages).containsAllIn(expectedPackages); + } + + @Test + @Config(shadows = {ShadowSmsApplication.class, ShadowDefaultDialerManager.class}) + public void getKeepEnabledPackages_shouldContainSettingsIntelligence() { + final String testDialer = "com.android.test.defaultdialer"; + final String testSms = "com.android.test.defaultsms"; + final String testLocationHistory = "com.android.test.location.history"; + + ShadowSmsApplication.setDefaultSmsApplication(new ComponentName(testSms, "receiver")); + ShadowDefaultDialerManager.setDefaultDialerApplication(testDialer); + + // Spy the real context to mock LocationManager. + Context spyContext = spy(RuntimeEnvironment.application); + when(mLocationManager.getExtraLocationControllerPackage()).thenReturn(testLocationHistory); + when(spyContext.getSystemService(Context.LOCATION_SERVICE)).thenReturn(mLocationManager); + + ReflectionHelpers.setField(mProvider, "mContext", spyContext); + + final Set whitelist = mProvider.getKeepEnabledPackages(); + + assertThat(whitelist).contains("com.android.settings.intelligence"); + } + + @Test + @Config(shadows = {ShadowSmsApplication.class, ShadowDefaultDialerManager.class}) + public void getKeepEnabledPackages_shouldContainPackageInstaller() { + final String testDialer = "com.android.test.defaultdialer"; + final String testSms = "com.android.test.defaultsms"; + final String testLocationHistory = "com.android.test.location.history"; + + ShadowSmsApplication.setDefaultSmsApplication(new ComponentName(testSms, "receiver")); + ShadowDefaultDialerManager.setDefaultDialerApplication(testDialer); + + // Spy the real context to mock LocationManager. + Context spyContext = spy(RuntimeEnvironment.application); + when(mLocationManager.getExtraLocationControllerPackage()).thenReturn(testLocationHistory); + when(spyContext.getSystemService(Context.LOCATION_SERVICE)).thenReturn(mLocationManager); + + ReflectionHelpers.setField(mProvider, "mContext", spyContext); + + final Set whitelist = mProvider.getKeepEnabledPackages(); + + assertThat(whitelist).contains("com.android.packageinstaller"); } private void setUpUsersAndInstalledApps() { diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java index f3d85d3993a..ff33d26ea21 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppButtonsPreferenceControllerTest.java @@ -39,9 +39,12 @@ import android.app.admin.DevicePolicyManager; import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; +import android.content.om.OverlayManager; +import android.content.om.OverlayInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.os.RemoteException; import android.os.UserManager; import android.view.View; @@ -70,11 +73,15 @@ import org.robolectric.util.ReflectionHelpers; public class AppButtonsPreferenceControllerTest { private static final String PACKAGE_NAME = "com.android.settings"; + private static final String RRO_PACKAGE_NAME = "com.android.settings.overlay"; private static final String RESOURCE_STRING = "string"; private static final boolean ALL_USERS = false; private static final boolean DISABLE_AFTER_INSTALL = true; private static final int REQUEST_UNINSTALL = 0; private static final int REQUEST_REMOVE_DEVICE_ADMIN = 1; + private static final OverlayInfo OVERLAY_DISABLED = createFakeOverlay("overlay", false, 1); + private static final OverlayInfo OVERLAY_ENABLED = createFakeOverlay("overlay", true, 1); + @Mock(answer = Answers.RETURNS_DEEP_STUBS) private SettingsActivity mSettingsActivity; @Mock @@ -88,6 +95,8 @@ public class AppButtonsPreferenceControllerTest { @Mock private ApplicationInfo mAppInfo; @Mock + private OverlayManager mOverlayManager; + @Mock private PackageManager mPackageManger; @Mock private DevicePolicyManager mDpm; @@ -113,13 +122,14 @@ public class AppButtonsPreferenceControllerTest { doReturn(mUserManager).when(mSettingsActivity).getSystemService(Context.USER_SERVICE); doReturn(mPackageManger).when(mSettingsActivity).getPackageManager(); doReturn(mAm).when(mSettingsActivity).getSystemService(Context.ACTIVITY_SERVICE); + doReturn(mOverlayManager).when(mSettingsActivity). + getSystemService(OverlayManager.class); doReturn(mAppEntry).when(mState).getEntry(anyString(), anyInt()); when(mSettingsActivity.getApplication()).thenReturn(mApplication); when(mSettingsActivity.getResources().getString(anyInt())).thenReturn(RESOURCE_STRING); mController = spy(new AppButtonsPreferenceController(mSettingsActivity, mFragment, mLifecycle, PACKAGE_NAME, mState, REQUEST_UNINSTALL, REQUEST_REMOVE_DEVICE_ADMIN)); - doReturn(false).when(mController).isFallbackPackage(anyString()); mAppEntry.info = mAppInfo; mAppInfo.packageName = PACKAGE_NAME; @@ -277,6 +287,41 @@ public class AppButtonsPreferenceControllerTest { verify(mButtonPrefs).setButton2Enabled(false); } + @Test + public void updateUninstallButton_isSystemRro_setButtonDisable() { + mAppInfo.flags |= ApplicationInfo.FLAG_SYSTEM; + + when(mAppInfo.isResourceOverlay()).thenReturn(true); + + mController.updateUninstallButton(); + + verify(mButtonPrefs).setButton2Enabled(false); + } + + @Test + public void updateUninstallButton_isNonSystemRro_setButtonDisable() + throws RemoteException { + when(mAppInfo.isResourceOverlay()).thenReturn(true); + when(mOverlayManager.getOverlayInfo(anyString(), any())) + .thenReturn(OVERLAY_ENABLED); + + mController.updateUninstallButton(); + + verify(mButtonPrefs).setButton2Enabled(false); + } + + @Test + public void updateUninstallButton_isNonSystemRro_setButtonEnable() + throws RemoteException { + when(mAppInfo.isResourceOverlay()).thenReturn(true); + when(mOverlayManager.getOverlayInfo(anyString(), any())) + .thenReturn(OVERLAY_DISABLED); + + mController.updateUninstallButton(); + + verify(mButtonPrefs).setButton2Enabled(true); + } + @Test public void updateForceStopButton_HasActiveAdmins_setButtonDisable() { doReturn(true).when(mDpm).packageHasActiveAdmins(anyString()); @@ -324,7 +369,7 @@ public class AppButtonsPreferenceControllerTest { final boolean controllable = mController.handleDisableable(); - verify(mButtonPrefs).setButton2Text(R.string.uninstall_text); + verify(mButtonPrefs).setButton2Text(R.string.disable_text); assertThat(controllable).isFalse(); } @@ -336,7 +381,7 @@ public class AppButtonsPreferenceControllerTest { final boolean controllable = mController.handleDisableable(); - verify(mButtonPrefs).setButton2Text(R.string.uninstall_text); + verify(mButtonPrefs).setButton2Text(R.string.disable_text); assertThat(controllable).isTrue(); } @@ -348,7 +393,7 @@ public class AppButtonsPreferenceControllerTest { final boolean controllable = mController.handleDisableable(); - verify(mButtonPrefs).setButton2Text(R.string.install_text); + verify(mButtonPrefs).setButton2Text(R.string.enable_text); assertThat(controllable).isTrue(); } @@ -419,4 +464,17 @@ public class AppButtonsPreferenceControllerTest { return pref; } + + private static OverlayInfo createFakeOverlay(String pkg, boolean enabled, int priority) { + final int state = (enabled) ? OverlayInfo.STATE_ENABLED : OverlayInfo.STATE_DISABLED; + return new OverlayInfo(pkg /* packageName */, + "target.package" /* targetPackageName */, + "theme" /* targetOverlayableName */, + "category", /* category */ + "package", /* baseCodePath */ + state, + 0 /* userId */, + priority, + false /* isStatic */); + } } diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java index 9e44c955ed9..56e59f7bd0e 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppInfoDashboardFragmentTest.java @@ -17,8 +17,7 @@ package com.android.settings.applications.appinfo; import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.ARG_PACKAGE_NAME; -import static com.android.settings.applications.appinfo.AppInfoDashboardFragment - .UNINSTALL_ALL_USERS_MENU; +import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.UNINSTALL_ALL_USERS_MENU; import static com.android.settings.applications.appinfo.AppInfoDashboardFragment.UNINSTALL_UPDATES; import static com.google.common.truth.Truth.assertThat; @@ -43,6 +42,7 @@ import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.os.Bundle; import android.os.UserManager; +import android.util.ArraySet; import android.view.Menu; import android.view.MenuItem; @@ -53,6 +53,7 @@ import com.android.settingslib.applications.ApplicationsState.AppEntry; import com.android.settingslib.applications.instantapps.InstantAppDataProvider; import com.android.settingslib.core.lifecycle.Lifecycle; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -63,10 +64,14 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; +import org.robolectric.annotation.Resetter; import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; import java.util.List; +import java.util.Set; @RunWith(RobolectricTestRunner.class) public final class AppInfoDashboardFragmentTest { @@ -101,6 +106,11 @@ public final class AppInfoDashboardFragmentTest { (InstantAppDataProvider) (i -> false)); } + @After + public void tearDown() { + ShadowAppUtils.reset(); + } + @Test public void shouldShowUninstallForAll_installForOneOtherUserOnly_shouldReturnTrue() { when(mDevicePolicyManager.packageHasActiveAdmins(nullable(String.class))).thenReturn(false); @@ -186,6 +196,24 @@ public final class AppInfoDashboardFragmentTest { verify(mActivity, never()).finishAndRemoveTask(); } + @Test + @Config(shadows = ShadowAppUtils.class) + public void ensureDisplayableModule_hiddenModule_shouldReturnFalse() { + ShadowAppUtils.addHiddenModule(PACKAGE_NAME); + ReflectionHelpers.setField(mFragment, "mPackageName", PACKAGE_NAME); + + + assertThat(mFragment.ensureDisplayableModule(mActivity)).isFalse(); + } + + @Test + @Config(shadows = ShadowAppUtils.class) + public void ensureDisplayableModule_regularApp_shouldReturnTrue() { + ReflectionHelpers.setField(mFragment, "mPackageName", PACKAGE_NAME); + + assertThat(mFragment.ensureDisplayableModule(mActivity)).isTrue(); + } + @Test public void createPreference_hasNoPackageInfo_shouldSkip() { ReflectionHelpers.setField(mFragment, "mPackageInfo", null); @@ -240,7 +268,8 @@ public final class AppInfoDashboardFragmentTest { doReturn(true).when(mFragment).refreshUi(); mFragment - .onActivityResult(AppInfoDashboardFragment.REQUEST_UNINSTALL, 0, mock(Intent.class)); + .onActivityResult(AppInfoDashboardFragment.REQUEST_UNINSTALL, 0, + mock(Intent.class)); verify(mActivity).invalidateOptionsMenu(); } @@ -347,4 +376,24 @@ public final class AppInfoDashboardFragmentTest { .containsKey(ARG_PACKAGE_NAME)) .isTrue(); } + + @Implements(AppUtils.class) + public static class ShadowAppUtils { + + public static Set sHiddenModules = new ArraySet<>(); + + @Resetter + public static void reset() { + sHiddenModules.clear(); + } + + public static void addHiddenModule(String pkg) { + sHiddenModules.add(pkg); + } + + @Implementation + protected static boolean isHiddenSystemModule(Context context, String packageName) { + return sHiddenModules.contains(packageName); + } + } } diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/DrawOverlayDetailsTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/DrawOverlayDetailsTest.java index ca993612ac0..fdbf8b93319 100644 --- a/tests/robotests/src/com/android/settings/applications/appinfo/DrawOverlayDetailsTest.java +++ b/tests/robotests/src/com/android/settings/applications/appinfo/DrawOverlayDetailsTest.java @@ -16,43 +16,26 @@ package com.android.settings.applications.appinfo; -import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; - -import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.settings.SettingsEnums; -import android.view.Window; import android.view.WindowManager.LayoutParams; -import androidx.fragment.app.FragmentActivity; - import com.android.internal.logging.nano.MetricsProto; import com.android.settings.testutils.FakeFeatureFactory; -import com.android.settings.testutils.shadow.ShadowAppInfoBase; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.Spy; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; @RunWith(RobolectricTestRunner.class) public class DrawOverlayDetailsTest { - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private FragmentActivity mActivity; - - @Mock - private Window mWindow; - private LayoutParams layoutParams; private FakeFeatureFactory mFeatureFactory; @@ -82,23 +65,4 @@ public class DrawOverlayDetailsTest { MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_APPDRAW_DENY, mFragment.getMetricsCategory(), "app", 0); } - - @Test - @Config(shadows = {ShadowAppInfoBase.class}) - public void hideNonSystemOverlaysWhenResumed() { - when(mFragment.getActivity()).thenReturn(mActivity); - when(mActivity.getWindow()).thenReturn(mWindow); - when(mWindow.getAttributes()).thenReturn(layoutParams); - - mFragment.onResume(); - verify(mWindow).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); - - mFragment.onPause(); - - // There's no Window.clearPrivateFlags() method, so the Window.attributes are updated. - ArgumentCaptor paramCaptor = ArgumentCaptor.forClass(LayoutParams.class); - verify(mWindow).setAttributes(paramCaptor.capture()); - assertEquals(0, - paramCaptor.getValue().privateFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); - } } diff --git a/tests/robotests/src/com/android/settings/applications/managedomainurls/DomainAppPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/managedomainurls/DomainAppPreferenceControllerTest.java index 5f2a51478cb..5e5239d6a88 100644 --- a/tests/robotests/src/com/android/settings/applications/managedomainurls/DomainAppPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/managedomainurls/DomainAppPreferenceControllerTest.java @@ -18,17 +18,9 @@ package com.android.settings.applications.managedomainurls; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - import android.content.Context; import android.content.pm.ApplicationInfo; import android.util.IconDrawableFactory; -import android.view.View; -import android.widget.ProgressBar; - -import androidx.preference.PreferenceViewHolder; import com.android.settings.R; import com.android.settingslib.applications.ApplicationsState; @@ -64,21 +56,6 @@ public class DomainAppPreferenceControllerTest { assertThat(pref.getLayoutResource()).isEqualTo(R.layout.preference_app); } - @Test - public void onBindViewHolder_shouldSetAppendixViewToGone() { - final DomainAppPreference pref = new DomainAppPreference( - mContext, mIconDrawableFactory, mAppEntry); - final View holderView = mock(View.class); - final View appendixView = mock(View.class); - when(holderView.findViewById(R.id.summary_container)).thenReturn(mock(View.class)); - when(holderView.findViewById(android.R.id.progress)).thenReturn(mock(ProgressBar.class)); - when(holderView.findViewById(R.id.appendix)).thenReturn(appendixView); - - pref.onBindViewHolder(PreferenceViewHolder.createInstanceForTests(holderView)); - - verify(appendixView).setVisibility(View.GONE); - } - private ApplicationInfo createApplicationInfo(String packageName) { ApplicationInfo appInfo = new ApplicationInfo(); appInfo.sourceDir = "foo"; diff --git a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java index 55381556eee..b9616697099 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/AdvancedBluetoothDetailsHeaderControllerTest.java @@ -18,6 +18,7 @@ package com.android.settings.bluetooth; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -78,6 +79,7 @@ public class AdvancedBluetoothDetailsHeaderControllerTest{ mContext = RuntimeEnvironment.application; mController = new AdvancedBluetoothDetailsHeaderController(mContext, "pref_Key"); + when(mCachedDevice.getDevice()).thenReturn(mBluetoothDevice); mController.init(mCachedDevice); mLayoutPreference = new LayoutPreference(mContext, LayoutInflater.from(mContext).inflate(R.layout.advanced_bt_entity_header, null)); @@ -166,7 +168,10 @@ public class AdvancedBluetoothDetailsHeaderControllerTest{ } @Test - public void onStart_registerCallback() { + public void onStart_isAvailable_registerCallback() { + when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET)) + .thenReturn("true"); + mController.onStart(); verify(mBluetoothAdapter).registerMetadataListener(mBluetoothDevice, @@ -174,12 +179,36 @@ public class AdvancedBluetoothDetailsHeaderControllerTest{ } @Test - public void onStop_unregisterCallback() { + public void onStop_isAvailable_unregisterCallback() { + when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET)) + .thenReturn("true"); + mController.onStop(); verify(mBluetoothAdapter).unregisterMetadataListener(mBluetoothDevice); } + @Test + public void onStart_notAvailable_registerCallback() { + when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET)) + .thenReturn("false"); + + mController.onStart(); + + verify(mBluetoothAdapter, never()).registerMetadataListener(mBluetoothDevice, + mController.mMetadataListener, mController.mHandler); + } + + @Test + public void onStop_notAvailable_unregisterCallback() { + when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET)) + .thenReturn("false"); + + mController.onStop(); + + verify(mBluetoothAdapter, never()).unregisterMetadataListener(mBluetoothDevice); + } + private void assertBatteryLevel(LinearLayout linearLayout, int batteryLevel) { final TextView textView = linearLayout.findViewById(R.id.bt_battery_summary); assertThat(textView.getText().toString()).isEqualTo( diff --git a/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java b/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java index a956518e898..ee79d612ea7 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/UtilsTest.java @@ -29,8 +29,6 @@ import android.content.Context; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.testutils.FakeFeatureFactory; -import com.android.settings.widget.AdaptiveIcon; -import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; @@ -41,7 +39,6 @@ import org.mockito.Answers; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) public class UtilsTest { @@ -54,8 +51,6 @@ public class UtilsTest { private Context mContext; @Mock private BluetoothDevice mBluetoothDevice; - @Mock - private CachedBluetoothDevice mCachedBluetoothDevice; private MetricsFeatureProvider mMetricsFeatureProvider; @@ -111,17 +106,4 @@ public class UtilsTest { assertThat(Utils.getBooleanMetaData(mBluetoothDevice, BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET)).isEqualTo(true); } - - @Test - public void getBtRainbowDrawableWithDescription_normalHeadset_returnAdaptiveIcon() { - when(mBluetoothDevice.getMetadata( - BluetoothDevice.METADATA_IS_UNTHETHERED_HEADSET)).thenReturn("false"); - when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice); - when(mCachedBluetoothDevice.getAddress()).thenReturn("1f:aa:bb"); - - assertThat(Utils.getBtRainbowDrawableWithDescription(RuntimeEnvironment.application, - mCachedBluetoothDevice).first).isInstanceOf( - AdaptiveIcon.class); - } - } diff --git a/tests/robotests/src/com/android/settings/core/BasePreferenceControllerSignatureInspector.java b/tests/robotests/src/com/android/settings/core/BasePreferenceControllerSignatureInspector.java index 28e394f94cb..2d1dc5c65ea 100644 --- a/tests/robotests/src/com/android/settings/core/BasePreferenceControllerSignatureInspector.java +++ b/tests/robotests/src/com/android/settings/core/BasePreferenceControllerSignatureInspector.java @@ -58,12 +58,17 @@ public class BasePreferenceControllerSignatureInspector extends CodeInspector { if (constructors == null || constructors.length == 0) { badClasses.append(c.getName()).append(","); } + + boolean hasValidConstructor = false; for (Constructor constructor : constructors) { - if (!hasValidConstructorSignature(constructor)) { - badClasses.append(className).append(","); - continue; + if (hasValidConstructorSignature(constructor)) { + hasValidConstructor = true; + break; } } + if (!hasValidConstructor) { + badClasses.append(className).append(","); + } } assertWithMessage("All BasePreferenceController (and subclasses) constructor must either" diff --git a/tests/robotests/src/com/android/settings/core/HideNonSystemOverlayMixinTest.java b/tests/robotests/src/com/android/settings/core/HideNonSystemOverlayMixinTest.java index 579cba09c14..d4f43e2f5fa 100644 --- a/tests/robotests/src/com/android/settings/core/HideNonSystemOverlayMixinTest.java +++ b/tests/robotests/src/com/android/settings/core/HideNonSystemOverlayMixinTest.java @@ -20,6 +20,7 @@ import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTE import static com.google.common.truth.Truth.assertThat; +import android.os.Build; import android.os.Bundle; import android.view.WindowManager; @@ -33,8 +34,8 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.android.controller.ActivityController; +import org.robolectric.util.ReflectionHelpers; @RunWith(RobolectricTestRunner.class) public class HideNonSystemOverlayMixinTest { @@ -43,7 +44,6 @@ public class HideNonSystemOverlayMixinTest { @Before public void setUp() { - RuntimeEnvironment.application.setTheme(R.style.Theme_AppCompat); mActivityController = Robolectric.buildActivity(TestActivity.class); } @@ -68,10 +68,25 @@ public class HideNonSystemOverlayMixinTest { .isEqualTo(0); } + @Test + public void isEnabled_debug_false() { + ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true); + + assertThat(new HideNonSystemOverlayMixin(null).isEnabled()).isFalse(); + } + + @Test + public void isEnabled_user_true() { + ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false); + + assertThat(new HideNonSystemOverlayMixin(null).isEnabled()).isTrue(); + } + public static class TestActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setTheme(R.style.Theme_AppCompat); getLifecycle().addObserver(new HideNonSystemOverlayMixin(this)); } } diff --git a/tests/robotests/src/com/android/settings/core/instrumentation/SettingsIntelligenceLogWriterTest.java b/tests/robotests/src/com/android/settings/core/instrumentation/SettingsIntelligenceLogWriterTest.java new file mode 100644 index 00000000000..30a25945d2f --- /dev/null +++ b/tests/robotests/src/com/android/settings/core/instrumentation/SettingsIntelligenceLogWriterTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.core.instrumentation; + +import static com.google.common.truth.Truth.assertThat; + +import android.app.settings.SettingsEnums; +import android.content.Context; + +import com.android.settings.intelligence.LogProto.SettingsLog; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class SettingsIntelligenceLogWriterTest { + private Context mContext; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + } + + @Test + public void serialize_hasSizeOne_returnCorrectData() throws IOException { + final SettingsLog event = SettingsLog.newBuilder() + .setAttribution(SettingsEnums.DASHBOARD_SUMMARY) + .setAction(SettingsEnums.ACTION_SET_NEW_PASSWORD) + .setPageId(SettingsEnums.SET_NEW_PASSWORD_ACTIVITY) + .setChangedPreferenceKey("package") + .setChangedPreferenceIntValue(100) + .build(); + List events = new ArrayList<>(); + events.add(event); + + // execute + final byte[] data = SettingsIntelligenceLogWriter.serialize(events); + + // parse data + final ByteArrayInputStream bin = new ByteArrayInputStream(data); + final DataInputStream inputStream = new DataInputStream(bin); + final int size = inputStream.readInt(); + final byte[] change = new byte[inputStream.readInt()]; + inputStream.read(change); + inputStream.close(); + final SettingsLog settingsLog = SettingsLog.parseFrom(change); + + // assert + assertThat(events.size()).isEqualTo(size); + assertThat(settingsLog.getAttribution()).isEqualTo(SettingsEnums.DASHBOARD_SUMMARY); + assertThat(settingsLog.getAction()).isEqualTo(SettingsEnums.ACTION_SET_NEW_PASSWORD); + assertThat(settingsLog.getPageId()).isEqualTo(SettingsEnums.SET_NEW_PASSWORD_ACTIVITY); + assertThat(settingsLog.getChangedPreferenceKey()).isEqualTo("package"); + assertThat(settingsLog.getChangedPreferenceIntValue()).isEqualTo(100); + } +} diff --git a/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPreferenceControllerTest.java index 2e15967d835..cf97544514a 100644 --- a/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPreferenceControllerTest.java @@ -17,6 +17,7 @@ package com.android.settings.development.featureflags; import static com.android.settings.core.BasePreferenceController.AVAILABLE; +import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE; import static com.google.common.truth.Truth.assertThat; @@ -26,6 +27,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; +import android.os.Build; +import android.os.SystemProperties; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceScreen; @@ -37,6 +40,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.util.ReflectionHelpers; @RunWith(RobolectricTestRunner.class) public class FeatureFlagPreferenceControllerTest { @@ -59,10 +63,18 @@ public class FeatureFlagPreferenceControllerTest { } @Test - public void getAvailability_available() { + public void getAvailability_debug_available() { + ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", true); assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); } + + @Test + public void getAvailability_user_unavailable() { + ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false); + assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); + } + @Test public void onStart_shouldRefreshFeatureFlags() { mController.onStart(); diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceControllerTest.java index 2761b2fb42a..f391aac64a3 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/MainlineModuleVersionPreferenceControllerTest.java @@ -18,6 +18,7 @@ package com.android.settings.deviceinfo.firmwareversion; import static com.android.settings.core.BasePreferenceController.AVAILABLE; import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE; +import static com.android.settings.deviceinfo.firmwareversion.MainlineModuleVersionPreferenceController.MODULE_UPDATE_INTENT; import static com.google.common.truth.Truth.assertThat; @@ -29,8 +30,11 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.util.FeatureFlagUtils; +import androidx.preference.Preference; + import com.android.settings.core.FeatureFlags; import org.junit.Before; @@ -48,11 +52,13 @@ public class MainlineModuleVersionPreferenceControllerTest { private PackageManager mPackageManager; private Context mContext; + private Preference mPreference; @Before public void setup() { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); + mPreference = new Preference(mContext); when(mContext.getPackageManager()).thenReturn(mPackageManager); FeatureFlagUtils.setEnabled(mContext, FeatureFlags.MAINLINE_MODULE, true); @@ -82,7 +88,6 @@ public class MainlineModuleVersionPreferenceControllerTest { @Test public void getAvailabilityStatus_noMainlineModulePackageInfo_unavailable() throws Exception { - final String provider = "test.provider"; when(mContext.getString( com.android.internal.R.string.config_defaultModuleMetadataProvider)) @@ -98,6 +103,43 @@ public class MainlineModuleVersionPreferenceControllerTest { @Test public void getAvailabilityStatus_hasMainlineModulePackageInfo_available() throws Exception { + setupModulePackage(); + + final MainlineModuleVersionPreferenceController controller = + new MainlineModuleVersionPreferenceController(mContext, "key"); + + assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE); + } + + @Test + public void updateStates_canHandleIntent_setIntentToPreference() throws Exception { + setupModulePackage(); + when(mPackageManager.resolveActivity(MODULE_UPDATE_INTENT, 0)) + .thenReturn(new ResolveInfo()); + + final MainlineModuleVersionPreferenceController controller = + new MainlineModuleVersionPreferenceController(mContext, "key"); + + controller.updateState(mPreference); + + assertThat(mPreference.getIntent()).isEqualTo(MODULE_UPDATE_INTENT); + } + + @Test + public void updateStates_cannotHandleIntent_setNullToPreference() throws Exception { + setupModulePackage(); + when(mPackageManager.resolveActivity(MODULE_UPDATE_INTENT, 0)) + .thenReturn(null); + + final MainlineModuleVersionPreferenceController controller = + new MainlineModuleVersionPreferenceController(mContext, "key"); + + controller.updateState(mPreference); + + assertThat(mPreference.getIntent()).isNull(); + } + + private void setupModulePackage() throws Exception { final String provider = "test.provider"; final String version = "test version 123"; final PackageInfo info = new PackageInfo(); @@ -106,11 +148,5 @@ public class MainlineModuleVersionPreferenceControllerTest { com.android.internal.R.string.config_defaultModuleMetadataProvider)) .thenReturn(provider); when(mPackageManager.getPackageInfo(eq(provider), anyInt())).thenReturn(info); - - final MainlineModuleVersionPreferenceController controller = - new MainlineModuleVersionPreferenceController(mContext, "key"); - - assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE); } - } diff --git a/tests/robotests/src/com/android/settings/display/DarkUIPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/DarkUIPreferenceControllerTest.java deleted file mode 100644 index c8f847b8872..00000000000 --- a/tests/robotests/src/com/android/settings/display/DarkUIPreferenceControllerTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.settings.display; - -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.UiModeManager; -import android.content.Context; - -import androidx.preference.ListPreference; -import androidx.preference.PreferenceScreen; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class DarkUIPreferenceControllerTest { - - private Context mContext; - @Mock - private ListPreference mPreference; - @Mock - private PreferenceScreen mPreferenceScreen; - @Mock - private UiModeManager mUiModeManager; - private DarkUIPreferenceController mController; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; - mController = new DarkUIPreferenceController(mContext, "dark_ui_mode"); - mController.setUiModeManager(mUiModeManager); - when(mPreferenceScreen.findPreference(mController.getPreferenceKey())) - .thenReturn(mPreference); - mController.displayPreference(mPreferenceScreen); - } - - @Test - public void onPreferenceChanged_setAuto() { - // Auto was deprecated, it should default to NO. - mController.onPreferenceChange(mPreference, "auto"); - verify(mUiModeManager).setNightMode(eq(UiModeManager.MODE_NIGHT_NO)); - } - - @Test - public void onPreferenceChanged_setNightMode() { - mController.onPreferenceChange(mPreference, "yes"); - verify(mUiModeManager).setNightMode(eq(UiModeManager.MODE_NIGHT_YES)); - } - - @Test - public void onPreferenceChanged_setDayMode() { - mController.onPreferenceChange(mPreference, "no"); - verify(mUiModeManager).setNightMode(eq(UiModeManager.MODE_NIGHT_NO)); - } - - public int getCurrentMode() { - final UiModeManager uiModeManager = mContext.getSystemService(UiModeManager.class); - return uiModeManager.getNightMode(); - } -} diff --git a/tests/robotests/src/com/android/settings/display/DarkUISettingsRadioButtonsControllerTest.java b/tests/robotests/src/com/android/settings/display/DarkUISettingsRadioButtonsControllerTest.java new file mode 100644 index 00000000000..76142a42e60 --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/DarkUISettingsRadioButtonsControllerTest.java @@ -0,0 +1,52 @@ +package com.android.settings.display; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; + +import android.app.UiModeManager; +import android.content.Context; +import androidx.preference.Preference; +import com.android.settings.R; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class DarkUISettingsRadioButtonsControllerTest { + + @Mock + private UiModeManager mUiModeManager; + @Mock + private Preference mFooter; + private Context mContext; + private DarkUISettingsRadioButtonsController mController; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mController = new DarkUISettingsRadioButtonsController(mContext, mFooter); + mController.mManager = mUiModeManager; + } + + @Test + public void footerUpdatesCorrectly() { + doReturn(UiModeManager.MODE_NIGHT_YES).when(mUiModeManager).getNightMode(); + mController.updateFooter(); + verify(mFooter).setSummary(eq(R.string.dark_ui_settings_dark_summary)); + + doReturn(UiModeManager.MODE_NIGHT_NO).when(mUiModeManager).getNightMode(); + mController.updateFooter(); + verify(mFooter).setSummary(eq(R.string.dark_ui_settings_light_summary)); + } + + public int getCurrentMode() { + final UiModeManager uiModeManager = mContext.getSystemService(UiModeManager.class); + return uiModeManager.getNightMode(); + } +} diff --git a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java index c01ef3fa56e..ff3a36f2574 100644 --- a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java +++ b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java @@ -20,6 +20,11 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import android.app.Activity; import android.app.admin.DevicePolicyManager; @@ -33,6 +38,8 @@ import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.TextView; +import androidx.appcompat.app.AlertDialog; + import com.android.settings.R; import com.android.settings.Settings; import com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminAdd; @@ -179,5 +186,28 @@ public class ActionDisabledByAdminDialogHelperTest { mHelper.setAdminSupportDetails(mActivity, null, admin); assertNull(admin.component); } -} + @Test + public void testMaybeSetLearnMoreButton() { + final UserManager userManager = RuntimeEnvironment.application.getSystemService( + UserManager.class); + final ShadowUserManager userManagerShadow = Shadow.extract(userManager); + final ComponentName component = new ComponentName("some.package.name", + "some.package.name.SomeClass"); + mHelper.mEnforcedAdmin = new EnforcedAdmin(component, UserHandle.of(123)); + + // Set up for shadow call. + userManagerShadow.getSameProfileGroupIds().put(123, 0); + + // Test that the button is shown when user IDs are in the same profile group + AlertDialog.Builder builder = mock(AlertDialog.Builder.class); + mHelper.maybeSetLearnMoreButton(builder); + verify(builder).setNeutralButton(anyInt(), any()); + + // Test that the button is not shown when user IDs are not in the same profile group + userManagerShadow.getSameProfileGroupIds().clear(); + builder = mock(AlertDialog.Builder.class); + mHelper.maybeSetLearnMoreButton(builder); + verify(builder, never()).setNeutralButton(anyInt(), any()); + } +} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java index 6012dbb4dc8..8654a4e5a7b 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java @@ -7,6 +7,7 @@ import android.content.Context; import android.os.PowerManager; import android.provider.Settings; import android.provider.Settings.Global; +import android.provider.Settings.Secure; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -54,4 +55,13 @@ public class BatterySaverScheduleRadioButtonsControllerTest { assertThat(mController.getDefaultKey()) .isEqualTo(BatterySaverScheduleRadioButtonsController.KEY_NO_SCHEDULE); } + + @Test + public void setDefaultKey_any_defaultsToNoScheduleIfWarningNotSeen() { + Secure.putString( + mContext.getContentResolver(), Secure.LOW_POWER_WARNING_ACKNOWLEDGED, "null"); + mController.setDefaultKey(BatterySaverScheduleRadioButtonsController.KEY_ROUTINE); + assertThat(mController.getDefaultKey()) + .isEqualTo(BatterySaverScheduleRadioButtonsController.KEY_NO_SCHEDULE); + } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverStickyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverStickyPreferenceControllerTest.java index 0ee9cfc5ede..0e7c312eb18 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverStickyPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverStickyPreferenceControllerTest.java @@ -16,11 +16,11 @@ package com.android.settings.fuelgauge.batterysaver; -import static com.android.settings.fuelgauge.batterysaver.BatterySaverStickyPreferenceController.LOW_POWER_STICKY_AUTO_DISABLE_ENABLED; import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.provider.Settings; +import android.provider.Settings.Global; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -43,21 +43,21 @@ public class BatterySaverStickyPreferenceControllerTest { private int getAutoDisableSetting() { return Settings.Global.getInt(mContext.getContentResolver(), - LOW_POWER_STICKY_AUTO_DISABLE_ENABLED, + Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 1); } @Test - public void testOnPreferenceChange_turnOnKeepActive_autoDisableOff() { - mController.onPreferenceChange(null, true); - final int isOn = getAutoDisableSetting(); - assertThat(isOn).isEqualTo(0); - } - - @Test - public void testOnPreferenceChange_TurnOffKeepActive_autoDisableOff() { - mController.onPreferenceChange(null, false); + public void testOnPreferenceChange_turnOnAutoOff_autoDisableOn() { + mController.setChecked(true); final int isOn = getAutoDisableSetting(); assertThat(isOn).isEqualTo(1); } + + @Test + public void testOnPreferenceChange_TurnOffAutoOff_autoDisableOff() { + mController.setChecked(false); + final int isOn = getAutoDisableSetting(); + assertThat(isOn).isEqualTo(0); + } } diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionControllerTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionControllerTest.java index 8c24735c77a..2fe4697f099 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionControllerTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/GrayscaleConditionControllerTest.java @@ -18,11 +18,13 @@ package com.android.settings.homepage.contextualcards.conditional; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.content.Context; +import android.content.Intent; import android.hardware.display.ColorDisplayManager; import org.junit.Before; @@ -80,4 +82,11 @@ public class GrayscaleConditionControllerTest { verify(mConditionManager).onConditionChanged(); } + + @Test + public void onActionClick_shouldSendBroadcast() { + mController.onActionClick(); + + verify(mContext).sendBroadcast(any(Intent.class), any(String.class)); + } } diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSliceTest.java index a744e68a64c..12513f67e1a 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSliceTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/NotificationChannelSliceTest.java @@ -16,6 +16,7 @@ package com.android.settings.homepage.contextualcards.slices; +import static android.app.NotificationManager.IMPORTANCE_LOW; import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.app.slice.Slice.HINT_LIST_ITEM; import static android.app.slice.SliceItem.FORMAT_SLICE; @@ -116,7 +117,8 @@ public class NotificationChannelSliceTest { public void getSlice_hasSuggestedApp_shouldHaveNotificationChannelTitle() { addMockPackageToPackageManager(true /* isRecentlyInstalled */, ApplicationInfo.FLAG_INSTALLED); - mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */); + mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */, + false /* isChannelBlocked */); final Slice slice = mNotificationChannelSlice.getSlice(); @@ -130,7 +132,8 @@ public class NotificationChannelSliceTest { public void getSlice_hasSuggestedApp_shouldSortByNotificationSentCount() { addMockPackageToPackageManager(true /* isRecentlyInstalled */, ApplicationInfo.FLAG_INSTALLED); - mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */); + mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */, + false /* isChannelBlocked */); final Slice slice = mNotificationChannelSlice.getSlice(); @@ -157,7 +160,8 @@ public class NotificationChannelSliceTest { public void getSlice_noRecentlyInstalledApp_shouldHaveNoSuggestedAppTitle() { addMockPackageToPackageManager(false /* isRecentlyInstalled */, ApplicationInfo.FLAG_INSTALLED); - mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */); + mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */, + false /* isChannelBlocked */); final Slice slice = mNotificationChannelSlice.getSlice(); @@ -169,7 +173,8 @@ public class NotificationChannelSliceTest { public void getSlice_noMultiChannelApp_shouldHaveNoSuggestedAppTitle() { addMockPackageToPackageManager(true /* isRecentlyInstalled */, ApplicationInfo.FLAG_INSTALLED); - mockNotificationBackend(1 /* channelCount */, NOTIFICATION_COUNT, false /* banned */); + mockNotificationBackend(1 /* channelCount */, NOTIFICATION_COUNT, false /* banned */, + false /* isChannelBlocked */); final Slice slice = mNotificationChannelSlice.getSlice(); @@ -178,10 +183,12 @@ public class NotificationChannelSliceTest { } @Test + @Config(shadows = ShadowRestrictedLockUtilsInternal.class) public void getSlice_insufficientNotificationSentCount_shouldHaveNoSuggestedAppTitle() { addMockPackageToPackageManager(true /* isRecentlyInstalled */, ApplicationInfo.FLAG_INSTALLED); - mockNotificationBackend(CHANNEL_COUNT, 1 /* notificationCount */, false /* banned */); + mockNotificationBackend(CHANNEL_COUNT, 1 /* notificationCount */, false /* banned */, + false /* isChannelBlocked */); final Slice slice = mNotificationChannelSlice.getSlice(); @@ -192,7 +199,8 @@ public class NotificationChannelSliceTest { @Test public void getSlice_isSystemApp_shouldHaveNoSuggestedAppTitle() { addMockPackageToPackageManager(true /* isRecentlyInstalled */, ApplicationInfo.FLAG_SYSTEM); - mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */); + mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */, + false /* isChannelBlocked */); final Slice slice = mNotificationChannelSlice.getSlice(); @@ -204,7 +212,8 @@ public class NotificationChannelSliceTest { public void getSlice_isNotificationBanned_shouldHaveNoSuggestedAppTitle() { addMockPackageToPackageManager(true /* isRecentlyInstalled */, ApplicationInfo.FLAG_INSTALLED); - mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, true /* banned */); + mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, true /* banned */, + false /* isChannelBlocked */); final Slice slice = mNotificationChannelSlice.getSlice(); @@ -218,7 +227,7 @@ public class NotificationChannelSliceTest { addMockPackageToPackageManager(true /* isRecentlyInstalled */, ApplicationInfo.FLAG_INSTALLED); mockNotificationBackend(NotificationChannelSlice.DEFAULT_EXPANDED_ROW_COUNT * 2, - NOTIFICATION_COUNT, false /* banned */); + NOTIFICATION_COUNT, false /* banned */, false /* isChannelBlocked */); final Slice slice = mNotificationChannelSlice.getSlice(); @@ -234,7 +243,8 @@ public class NotificationChannelSliceTest { public void getSlice_channelCountIsLessThanDefaultRows_subTitleShouldNotHaveTapToManagerAll() { addMockPackageToPackageManager(true /* isRecentlyInstalled */, ApplicationInfo.FLAG_INSTALLED); - mockNotificationBackend(CHANNEL_COUNT - 1, NOTIFICATION_COUNT, false /* banned */); + mockNotificationBackend(CHANNEL_COUNT - 1, NOTIFICATION_COUNT, false /* banned */, + false /* isChannelBlocked */); final Slice slice = mNotificationChannelSlice.getSlice(); @@ -249,7 +259,8 @@ public class NotificationChannelSliceTest { public void getSlice_channelCountIsEqualToDefaultRows_subTitleShouldNotHaveTapToManagerAll() { addMockPackageToPackageManager(true /* isRecentlyInstalled */, ApplicationInfo.FLAG_INSTALLED); - mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */); + mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */, + false /* isChannelBlocked */); final Slice slice = mNotificationChannelSlice.getSlice(); @@ -263,7 +274,8 @@ public class NotificationChannelSliceTest { public void getSlice_channelCountIsMoreThanDefaultRows_subTitleShouldHaveTapToManagerAll() { addMockPackageToPackageManager(true /* isRecentlyInstalled */, ApplicationInfo.FLAG_INSTALLED); - mockNotificationBackend(CHANNEL_COUNT + 1, NOTIFICATION_COUNT, false /* banned */); + mockNotificationBackend(CHANNEL_COUNT + 1, NOTIFICATION_COUNT, false /* banned */, + false /* isChannelBlocked */); final Slice slice = mNotificationChannelSlice.getSlice(); @@ -273,6 +285,20 @@ public class NotificationChannelSliceTest { CHANNEL_COUNT + 1)); } + @Test + @Config(shadows = ShadowRestrictedLockUtilsInternal.class) + public void getSlice_isAllDisplayableChannelBlocked_shouldHaveNoSuggestedAppTitle() { + addMockPackageToPackageManager(true /* isRecentlyInstalled */, + ApplicationInfo.FLAG_INSTALLED); + mockNotificationBackend(CHANNEL_COUNT, NOTIFICATION_COUNT, false /* banned */, + true /* isChannelBlocked */); + + final Slice slice = mNotificationChannelSlice.getSlice(); + + final SliceMetadata metadata = SliceMetadata.from(mContext, slice); + assertThat(metadata.getTitle()).isEqualTo(mContext.getString(R.string.no_suggested_app)); + } + private void addMockPackageToPackageManager(boolean isRecentlyInstalled, int flags) { final ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.name = APP_LABEL; @@ -294,8 +320,10 @@ public class NotificationChannelSliceTest { return System.currentTimeMillis(); } - private void mockNotificationBackend(int channelCount, int notificationCount, boolean banned) { - final List channels = buildNotificationChannel(channelCount); + private void mockNotificationBackend(int channelCount, int notificationCount, boolean banned, + boolean isChannelBlocked) { + final List channels = buildNotificationChannel(channelCount, + isChannelBlocked); final AppRow appRow = buildAppRow(channelCount, notificationCount, banned); doReturn(buildNotificationChannelGroups(channels)).when(mNotificationBackend).getGroups( @@ -308,6 +336,8 @@ public class NotificationChannelSliceTest { private AppRow buildAppRow(int channelCount, int sentCount, boolean banned) { final AppRow appRow = new AppRow(); + appRow.pkg = PACKAGE_NAME; + appRow.uid = UID; appRow.banned = banned; appRow.channelCount = channelCount; appRow.sentByApp = new NotificationsSentState(); @@ -317,11 +347,12 @@ public class NotificationChannelSliceTest { return appRow; } - private List buildNotificationChannel(int channelCount) { + private List buildNotificationChannel(int channelCount, + boolean isChannelBlock) { final List channels = new ArrayList<>(); for (int i = 0; i < channelCount; i++) { channels.add(new NotificationChannel(CHANNEL_NAME_PREFIX + i, CHANNEL_NAME_PREFIX + i, - IMPORTANCE_NONE)); + isChannelBlock ? IMPORTANCE_NONE : IMPORTANCE_LOW)); } return channels; @@ -369,4 +400,4 @@ public class NotificationChannelSliceTest { // Index 0: title; Index 1: summary. return rowSliceItems.get(1).getText(); } -} \ No newline at end of file +} diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java index e08d845196e..706f2386372 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceContextualCardRendererTest.java @@ -16,13 +16,11 @@ package com.android.settings.homepage.contextualcards.slices; -import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_DEFERRED_SETUP; import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.app.Activity; @@ -118,34 +116,25 @@ public class SliceContextualCardRendererTest { } @Test - public void longClick_shouldFlipCard() { + public void bindView_isPendingDismiss_shouldFlipToDismissalView() { final RecyclerView.ViewHolder viewHolder = getSliceViewHolder(); - final View card = viewHolder.itemView.findViewById(R.id.slice_view); final ViewFlipper viewFlipper = viewHolder.itemView.findViewById(R.id.view_flipper); final View dismissalView = viewHolder.itemView.findViewById(R.id.dismissal_view); - mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI)); + final ContextualCard card = buildContextualCard( + TEST_SLICE_URI).mutate().setIsPendingDismiss(true).build(); - card.performLongClick(); + mRenderer.bindView(viewHolder, card); assertThat(viewFlipper.getCurrentView()).isEqualTo(dismissalView); } @Test - public void longClick_deferredSetupCard_shouldNotBeClickable() { - final RecyclerView.ViewHolder viewHolder = getDeferredSetupViewHolder(); - final View contentView = viewHolder.itemView.findViewById(R.id.content); - mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI)); - - assertThat(contentView.isLongClickable()).isFalse(); - } - - @Test - public void longClick_shouldAddViewHolderToSet() { + public void bindView_isPendingDismiss_shouldAddViewHolderToSet() { final RecyclerView.ViewHolder viewHolder = getSliceViewHolder(); - final View card = viewHolder.itemView.findViewById(R.id.slice_view); - mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI)); + final ContextualCard card = buildContextualCard( + TEST_SLICE_URI).mutate().setIsPendingDismiss(true).build(); - card.performLongClick(); + mRenderer.bindView(viewHolder, card); assertThat(mRenderer.mFlippedCardSet).contains(viewHolder); } @@ -153,12 +142,11 @@ public class SliceContextualCardRendererTest { @Test public void viewClick_keepCard_shouldFlipBackToSlice() { final RecyclerView.ViewHolder viewHolder = getSliceViewHolder(); - final View card = viewHolder.itemView.findViewById(R.id.slice_view); final Button btnKeep = viewHolder.itemView.findViewById(R.id.keep); final ViewFlipper viewFlipper = viewHolder.itemView.findViewById(R.id.view_flipper); mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI)); + viewFlipper.setDisplayedChild(1); - card.performLongClick(); btnKeep.performClick(); assertThat(viewFlipper.getCurrentView()).isInstanceOf(SliceView.class); @@ -167,11 +155,10 @@ public class SliceContextualCardRendererTest { @Test public void viewClick_keepCard_shouldRemoveViewHolderFromSet() { final RecyclerView.ViewHolder viewHolder = getSliceViewHolder(); - final View card = viewHolder.itemView.findViewById(R.id.slice_view); final Button btnKeep = viewHolder.itemView.findViewById(R.id.keep); mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI)); + mRenderer.mFlippedCardSet.add(viewHolder); - card.performLongClick(); btnKeep.performClick(); assertThat(mRenderer.mFlippedCardSet).doesNotContain(viewHolder); @@ -180,14 +167,13 @@ public class SliceContextualCardRendererTest { @Test public void viewClick_removeCard_shouldRemoveViewHolderFromSet() { final RecyclerView.ViewHolder viewHolder = getSliceViewHolder(); - final View card = viewHolder.itemView.findViewById(R.id.slice_view); final Button btnRemove = viewHolder.itemView.findViewById(R.id.remove); final ContextualCard contextualCard = buildContextualCard(TEST_SLICE_URI); mRenderer.bindView(viewHolder, contextualCard); doReturn(mController).when(mControllerRendererPool).getController(mActivity, ContextualCard.CardType.SLICE); + mRenderer.mFlippedCardSet.add(viewHolder); - card.performLongClick(); btnRemove.performClick(); assertThat(mRenderer.mFlippedCardSet).doesNotContain(viewHolder); @@ -196,7 +182,6 @@ public class SliceContextualCardRendererTest { @Test public void viewClick_removeCard_sliceLiveDataShouldRemoveObservers() { final RecyclerView.ViewHolder viewHolder = getSliceViewHolder(); - final View card = viewHolder.itemView.findViewById(R.id.slice_view); final Button btnRemove = viewHolder.itemView.findViewById(R.id.remove); final ContextualCard contextualCard = buildContextualCard(TEST_SLICE_URI); mRenderer.mSliceLiveDataMap.put(TEST_SLICE_URI, mSliceLiveData); @@ -204,7 +189,6 @@ public class SliceContextualCardRendererTest { doReturn(mController).when(mControllerRendererPool).getController(mActivity, ContextualCard.CardType.SLICE); - card.performLongClick(); btnRemove.performClick(); assertThat(mRenderer.mSliceLiveDataMap.get(TEST_SLICE_URI).hasObservers()).isFalse(); @@ -213,11 +197,11 @@ public class SliceContextualCardRendererTest { @Test public void onStop_cardIsFlipped_shouldFlipBack() { final RecyclerView.ViewHolder viewHolder = getSliceViewHolder(); - final View card = viewHolder.itemView.findViewById(R.id.slice_view); final ViewFlipper viewFlipper = viewHolder.itemView.findViewById(R.id.view_flipper); mRenderer.bindView(viewHolder, buildContextualCard(TEST_SLICE_URI)); + viewFlipper.setDisplayedChild(1); + mRenderer.mFlippedCardSet.add(viewHolder); - card.performLongClick(); mRenderer.onStop(); assertThat(viewFlipper.getCurrentView()).isInstanceOf(SliceView.class); @@ -232,18 +216,6 @@ public class SliceContextualCardRendererTest { return mRenderer.createViewHolder(view, VIEW_TYPE_FULL_WIDTH); } - private RecyclerView.ViewHolder getDeferredSetupViewHolder() { - final RecyclerView recyclerView = new RecyclerView(mActivity); - recyclerView.setLayoutManager(new LinearLayoutManager(mActivity)); - final View view = LayoutInflater.from(mActivity).inflate(VIEW_TYPE_DEFERRED_SETUP, - recyclerView, false); - final RecyclerView.ViewHolder viewHolder = spy( - mRenderer.createViewHolder(view, VIEW_TYPE_DEFERRED_SETUP)); - doReturn(VIEW_TYPE_DEFERRED_SETUP).when(viewHolder).getItemViewType(); - - return viewHolder; - } - private ContextualCard buildContextualCard(Uri sliceUri) { return new ContextualCard.Builder() .setName("test_name") diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelperTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelperTest.java index 88820096fce..395748bc0fb 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelperTest.java +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelperTest.java @@ -78,7 +78,7 @@ public class SliceFullCardRendererHelperTest { public void bindView_shouldSetScrollableToFalse() { final RecyclerView.ViewHolder viewHolder = getSliceViewHolder(); - mHelper.bindView(viewHolder, buildContextualCard(), buildSlice(), Collections.emptySet()); + mHelper.bindView(viewHolder, buildContextualCard(), buildSlice()); assertThat(((SliceViewHolder) viewHolder).sliceView.isScrollable()).isFalse(); } @@ -88,7 +88,7 @@ public class SliceFullCardRendererHelperTest { final RecyclerView.ViewHolder viewHolder = getSliceViewHolder(); final ContextualCard card = buildContextualCard(); - mHelper.bindView(viewHolder, card, buildSlice(), Collections.emptySet()); + mHelper.bindView(viewHolder, card, buildSlice()); assertThat(((SliceViewHolder) viewHolder).sliceView.getTag()).isEqualTo(card.getSliceUri()); } @@ -97,7 +97,7 @@ public class SliceFullCardRendererHelperTest { public void bindView_shouldSetModeToLarge() { final RecyclerView.ViewHolder viewHolder = getSliceViewHolder(); - mHelper.bindView(viewHolder, buildContextualCard(), buildSlice(), Collections.emptySet()); + mHelper.bindView(viewHolder, buildContextualCard(), buildSlice()); assertThat(((SliceViewHolder) viewHolder).sliceView.getMode()).isEqualTo( SliceView.MODE_LARGE); @@ -107,7 +107,7 @@ public class SliceFullCardRendererHelperTest { public void bindView_shouldSetSlice() { final RecyclerView.ViewHolder viewHolder = getSliceViewHolder(); - mHelper.bindView(viewHolder, buildContextualCard(), buildSlice(), Collections.emptySet()); + mHelper.bindView(viewHolder, buildContextualCard(), buildSlice()); assertThat(((SliceViewHolder) viewHolder).sliceView.getSlice().getUri()).isEqualTo( TEST_SLICE_URI); diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegateTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegateTest.java new file mode 100644 index 00000000000..00b7815745b --- /dev/null +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/SwipeDismissalDelegateTest.java @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.homepage.contextualcards.slices; + +import static com.android.settings.homepage.contextualcards.slices.SliceContextualCardRenderer.VIEW_TYPE_DEFERRED_SETUP; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import android.app.Activity; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ViewFlipper; + +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.settings.R; +import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer; +import com.android.settings.homepage.contextualcards.conditional.ConditionContextualCardRenderer.ConditionalCardHolder; +import com.android.settings.homepage.contextualcards.slices.SliceDeferredSetupCardRendererHelper.DeferredSetupCardViewHolder; +import com.android.settings.homepage.contextualcards.slices.SliceFullCardRendererHelper.SliceViewHolder; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.android.controller.ActivityController; + +@RunWith(RobolectricTestRunner.class) +public class SwipeDismissalDelegateTest { + + @Mock + private SwipeDismissalDelegate.Listener mDismissalDelegateListener; + + private Activity mActivity; + private RecyclerView mRecyclerView; + private SwipeDismissalDelegate mDismissalDelegate; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + final ActivityController activityController = Robolectric.buildActivity( + Activity.class); + mActivity = activityController.get(); + mActivity.setTheme(R.style.Theme_Settings_Home); + activityController.create(); + mRecyclerView = new RecyclerView(mActivity); + mRecyclerView.setLayoutManager(new LinearLayoutManager(mActivity)); + mDismissalDelegate = new SwipeDismissalDelegate(mActivity, mDismissalDelegateListener); + } + + @Test + public void getMovementFlags_conditionalViewHolder_shouldDisableSwipe() { + assertThat(mDismissalDelegate.getMovementFlags(mRecyclerView, getConditionalViewHolder())) + .isEqualTo(0); + } + + @Test + public void getMovementFlags_deferredSetupViewHolder_shouldDisableSwipe() { + assertThat(mDismissalDelegate.getMovementFlags(mRecyclerView, getDeferredSetupViewHolder())) + .isEqualTo(0); + } + + @Test + public void getMovementFlags_dismissalView_shouldDisableSwipe() { + final RecyclerView.ViewHolder holder = getSliceViewHolder(); + final ViewFlipper viewFlipper = holder.itemView.findViewById(R.id.view_flipper); + viewFlipper.showNext(); + final View dismissalView = holder.itemView.findViewById(R.id.dismissal_view); + + assertThat(viewFlipper.getCurrentView()).isEqualTo(dismissalView); + assertThat(mDismissalDelegate.getMovementFlags(mRecyclerView, holder)).isEqualTo(0); + } + + @Test + public void getMovementFlags_SliceViewHolder_shouldEnableSwipe() { + final RecyclerView.ViewHolder holder = getSliceViewHolder(); + final ViewFlipper viewFlipper = holder.itemView.findViewById(R.id.view_flipper); + viewFlipper.setDisplayedChild(0); + final View sliceView = holder.itemView.findViewById(R.id.slice_view); + + assertThat(viewFlipper.getCurrentView()).isEqualTo(sliceView); + assertThat(mDismissalDelegate.getMovementFlags(mRecyclerView, getSliceViewHolder())) + .isNotEqualTo(0); + } + + @Test + public void onSwipe_shouldNotifyListener() { + mDismissalDelegate.onSwiped(getSliceViewHolder(), 1); + + verify(mDismissalDelegateListener).onSwiped(anyInt()); + } + + private RecyclerView.ViewHolder getSliceViewHolder() { + final View view = LayoutInflater.from(mActivity) + .inflate(SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH, mRecyclerView, false); + final RecyclerView.ViewHolder viewHolder = spy(new SliceViewHolder(view)); + doReturn(SliceContextualCardRenderer.VIEW_TYPE_FULL_WIDTH).when( + viewHolder).getItemViewType(); + + return viewHolder; + } + + private RecyclerView.ViewHolder getConditionalViewHolder() { + final View view = LayoutInflater.from(mActivity) + .inflate(ConditionContextualCardRenderer.VIEW_TYPE_FULL_WIDTH, mRecyclerView, + false); + final RecyclerView.ViewHolder viewHolder = spy(new ConditionalCardHolder(view)); + doReturn(ConditionContextualCardRenderer.VIEW_TYPE_FULL_WIDTH).when( + viewHolder).getItemViewType(); + + return viewHolder; + } + + private RecyclerView.ViewHolder getDeferredSetupViewHolder() { + final View view = LayoutInflater.from(mActivity) + .inflate(VIEW_TYPE_DEFERRED_SETUP, mRecyclerView, false); + final RecyclerView.ViewHolder viewHolder = spy(new DeferredSetupCardViewHolder(view)); + doReturn(VIEW_TYPE_DEFERRED_SETUP).when(viewHolder).getItemViewType(); + + return viewHolder; + } +} diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java index ab3f4de26f9..b39f77ed732 100644 --- a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java +++ b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorSliceTest.java @@ -17,32 +17,27 @@ package com.android.settings.media; -import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI; - import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; import android.content.Context; -import android.content.Intent; import androidx.slice.Slice; -import androidx.slice.SliceItem; import androidx.slice.SliceMetadata; import androidx.slice.SliceProvider; -import androidx.slice.core.SliceAction; import androidx.slice.widget.SliceLiveData; import com.android.settings.R; -import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; -import com.android.settingslib.media.LocalMediaManager; -import com.android.settingslib.media.MediaDevice; -import com.android.settingslib.media.MediaOutputSliceConstants; +import com.android.settings.testutils.shadow.ShadowBluetoothUtils; +import com.android.settingslib.bluetooth.A2dpProfile; +import com.android.settingslib.bluetooth.HearingAidProfile; +import com.android.settingslib.bluetooth.LocalBluetoothManager; +import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import org.junit.Before; import org.junit.Test; @@ -52,58 +47,108 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import org.robolectric.shadow.api.Shadow; import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) -@Config(shadows = {ShadowBluetoothAdapter.class}) +@Config(shadows = {ShadowBluetoothUtils.class}) public class MediaOutputIndicatorSliceTest { - private static final String TEST_DEVICE_NAME = "test_device_name"; - private static final int TEST_DEVICE_1_ICON = - com.android.internal.R.drawable.ic_bt_headphones_a2dp; + private static final String TEST_A2DP_DEVICE_NAME = "Test_A2DP_BT_Device_NAME"; + private static final String TEST_HAP_DEVICE_NAME = "Test_HAP_BT_Device_NAME"; + private static final String TEST_A2DP_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1"; + private static final String TEST_HAP_DEVICE_ADDRESS = "00:B2:B2:B2:B2:B2"; @Mock - private LocalMediaManager mLocalMediaManager; - - private final List mDevices = new ArrayList<>(); + private A2dpProfile mA2dpProfile; + @Mock + private HearingAidProfile mHearingAidProfile; + @Mock + private LocalBluetoothManager mLocalBluetoothManager; + @Mock + private LocalBluetoothProfileManager mLocalBluetoothProfileManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mA2dpDevice; + private BluetoothDevice mHapDevice; + private BluetoothManager mBluetoothManager; private Context mContext; + private List mDevicesList; private MediaOutputIndicatorSlice mMediaOutputIndicatorSlice; - private MediaOutputIndicatorWorker mMediaOutputIndicatorWorker; - private ShadowBluetoothAdapter mShadowBluetoothAdapter; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); - // Set-up specs for SliceMetadata. SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); + // Setup Bluetooth environment + ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager; + mBluetoothManager = new BluetoothManager(mContext); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager); + when(mLocalBluetoothProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile); + when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); + + // Setup A2dp device + mA2dpDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_A2DP_DEVICE_ADDRESS)); + when(mA2dpDevice.getName()).thenReturn(TEST_A2DP_DEVICE_NAME); + when(mA2dpDevice.isConnected()).thenReturn(true); + // Setup HearingAid device + mHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_HAP_DEVICE_ADDRESS)); + when(mHapDevice.getName()).thenReturn(TEST_HAP_DEVICE_NAME); + when(mHapDevice.isConnected()).thenReturn(true); + mMediaOutputIndicatorSlice = new MediaOutputIndicatorSlice(mContext); - mMediaOutputIndicatorWorker = spy(new MediaOutputIndicatorWorker( - mContext, MEDIA_OUTPUT_INDICATOR_SLICE_URI)); - mMediaOutputIndicatorSlice.mWorker = mMediaOutputIndicatorWorker; + mDevicesList = new ArrayList<>(); } @Test - public void getSlice_invisible_returnNull() { - when(mMediaOutputIndicatorWorker.isVisible()).thenReturn(false); + public void getSlice_noConnectableDevice_returnNull() { + mDevicesList.clear(); + when(mA2dpProfile.getConnectableDevices()).thenReturn(mDevicesList); assertThat(mMediaOutputIndicatorSlice.getSlice()).isNull(); } @Test - public void getSlice_withActiveDevice_checkContent() { - when(mMediaOutputIndicatorWorker.isVisible()).thenReturn(true); - when(mMediaOutputIndicatorWorker.findActiveDeviceName()).thenReturn(TEST_DEVICE_NAME); + public void getSlice_noActiveDevice_verifyDefaultName() { + mDevicesList.add(mA2dpDevice); + when(mA2dpProfile.getConnectableDevices()).thenReturn(mDevicesList); + when(mA2dpProfile.getActiveDevice()).thenReturn(null); + + // Verify slice title and subtitle final Slice mediaSlice = mMediaOutputIndicatorSlice.getSlice(); final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice); - // Verify slice title and subtitle assertThat(metadata.getTitle()).isEqualTo(mContext.getText(R.string.media_output_title)); - assertThat(metadata.getSubtitle()).isEqualTo(TEST_DEVICE_NAME); + assertThat(metadata.getSubtitle()).isEqualTo(mContext.getText( + R.string.media_output_default_summary)); + } + + @Test + public void getSlice_A2dpDeviceActive_verifyName() { + mDevicesList.add(mA2dpDevice); + when(mA2dpProfile.getConnectableDevices()).thenReturn(mDevicesList); + when(mA2dpProfile.getActiveDevice()).thenReturn(mA2dpDevice); + + final Slice mediaSlice = mMediaOutputIndicatorSlice.getSlice(); + final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice); + assertThat(metadata.getTitle()).isEqualTo(mContext.getText(R.string.media_output_title)); + assertThat(metadata.getSubtitle()).isEqualTo(TEST_A2DP_DEVICE_NAME); + } + + @Test + public void getSlice_HADeviceActive_verifyName() { + mDevicesList.add(mHapDevice); + when(mHearingAidProfile.getConnectableDevices()).thenReturn(mDevicesList); + when(mHearingAidProfile.getActiveDevices()).thenReturn(mDevicesList); + + // Verify slice title and subtitle + final Slice mediaSlice = mMediaOutputIndicatorSlice.getSlice(); + final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice); + assertThat(metadata.getTitle()).isEqualTo(mContext.getText(R.string.media_output_title)); + assertThat(metadata.getSubtitle()).isEqualTo(TEST_HAP_DEVICE_NAME); } } diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java index 4a5662e53de..3671d819f83 100644 --- a/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java +++ b/tests/robotests/src/com/android/settings/media/MediaOutputIndicatorWorkerTest.java @@ -16,25 +16,16 @@ package com.android.settings.media; -import static com.google.common.truth.Truth.assertThat; - import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothManager; import android.content.Context; import android.net.Uri; -import com.android.settings.R; -import com.android.settings.bluetooth.Utils; import com.android.settings.testutils.shadow.ShadowBluetoothUtils; -import com.android.settingslib.bluetooth.A2dpProfile; import com.android.settingslib.bluetooth.BluetoothEventManager; -import com.android.settingslib.bluetooth.HearingAidProfile; import com.android.settingslib.bluetooth.LocalBluetoothManager; -import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import org.junit.Before; import org.junit.Test; @@ -44,118 +35,38 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowBluetoothDevice; - -import java.util.ArrayList; -import java.util.List; @RunWith(RobolectricTestRunner.class) -@Config(shadows = {ShadowBluetoothUtils.class, - ShadowBluetoothDevice.class}) +@Config(shadows = {ShadowBluetoothUtils.class}) public class MediaOutputIndicatorWorkerTest { - - private static final String TEST_A2DP_DEVICE_NAME = "Test_A2DP_BT_Device_NAME"; - private static final String TEST_HAP_DEVICE_NAME = "Test_HAP_BT_Device_NAME"; - private static final String TEST_A2DP_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1"; - private static final String TEST_HAP_DEVICE_ADDRESS = "00:B2:B2:B2:B2:B2"; private static final Uri URI = Uri.parse("content://com.android.settings.slices/test"); - @Mock - private A2dpProfile mA2dpProfile; - @Mock - private HearingAidProfile mHearingAidProfile; - @Mock - private LocalBluetoothManager mLocalManager; @Mock private BluetoothEventManager mBluetoothEventManager; @Mock - private LocalBluetoothProfileManager mLocalBluetoothProfileManager; - - private BluetoothAdapter mBluetoothAdapter; - private BluetoothDevice mA2dpDevice; - private BluetoothDevice mHapDevice; - private BluetoothManager mBluetoothManager; - private Context mContext; - private List mDevicesList; private LocalBluetoothManager mLocalBluetoothManager; + private Context mContext; private MediaOutputIndicatorWorker mMediaDeviceUpdateWorker; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); - ShadowBluetoothUtils.sLocalBluetoothManager = mLocalManager; - mLocalBluetoothManager = Utils.getLocalBtManager(mContext); + ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager; when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager); - when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager); - when(mLocalBluetoothProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile); - when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); - mBluetoothManager = new BluetoothManager(mContext); - mBluetoothAdapter = mBluetoothManager.getAdapter(); - - // Setup A2dp device - mA2dpDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_A2DP_DEVICE_ADDRESS)); - when(mA2dpDevice.getName()).thenReturn(TEST_A2DP_DEVICE_NAME); - when(mA2dpDevice.isConnected()).thenReturn(true); - // Setup HearingAid device - mHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_HAP_DEVICE_ADDRESS)); - when(mHapDevice.getName()).thenReturn(TEST_HAP_DEVICE_NAME); - when(mHapDevice.isConnected()).thenReturn(true); - mMediaDeviceUpdateWorker = new MediaOutputIndicatorWorker(mContext, URI); - mDevicesList = new ArrayList<>(); } @Test - public void isVisible_noConnectableDevice_returnFalse() { - mDevicesList.clear(); - when(mA2dpProfile.getConnectableDevices()).thenReturn(mDevicesList); - - assertThat(mMediaDeviceUpdateWorker.isVisible()).isFalse(); + public void onSlicePinned_registerCallback() { + mMediaDeviceUpdateWorker.onSlicePinned(); + verify(mBluetoothEventManager).registerCallback(mMediaDeviceUpdateWorker); } @Test - public void isVisible_withConnectableA2dpDevice_returnTrue() { - mDevicesList.clear(); - mDevicesList.add(mA2dpDevice); - when(mHearingAidProfile.getConnectableDevices()).thenReturn(mDevicesList); - - assertThat(mMediaDeviceUpdateWorker.isVisible()).isTrue(); - } - - @Test - public void isVisible_withConnectableHADevice_returnTrue() { - mDevicesList.clear(); - mDevicesList.add(mHapDevice); - when(mA2dpProfile.getConnectableDevices()).thenReturn(mDevicesList); - - assertThat(mMediaDeviceUpdateWorker.isVisible()).isTrue(); - } - - @Test - public void findActiveDeviceName_A2dpDeviceActive_verifyName() { - when(mA2dpProfile.getActiveDevice()).thenReturn(mA2dpDevice); - - assertThat(mMediaDeviceUpdateWorker.findActiveDeviceName()) - .isEqualTo(mA2dpDevice.getAliasName()); - } - - @Test - public void findActiveDeviceName_HADeviceActive_verifyName() { - mDevicesList.add(mHapDevice); - when(mHearingAidProfile.getActiveDevices()).thenReturn(mDevicesList); - - assertThat(mMediaDeviceUpdateWorker.findActiveDeviceName()) - .isEqualTo(mHapDevice.getAliasName()); - } - - @Test - public void findActiveDeviceName_noActiveDevice_verifyDefaultName() { - when(mA2dpProfile.getActiveDevice()).thenReturn(null); - mDevicesList.clear(); - when(mHearingAidProfile.getActiveDevices()).thenReturn(mDevicesList); - - assertThat(mMediaDeviceUpdateWorker.findActiveDeviceName()) - .isEqualTo(mContext.getText(R.string.media_output_default_summary)); + public void onSliceUnpinned_unRegisterCallback() { + mMediaDeviceUpdateWorker.onSlicePinned(); + mMediaDeviceUpdateWorker.onSliceUnpinned(); + verify(mBluetoothEventManager).unregisterCallback(mMediaDeviceUpdateWorker); } } diff --git a/tests/robotests/src/com/android/settings/media/MediaOutputSliceTest.java b/tests/robotests/src/com/android/settings/media/MediaOutputSliceTest.java index d26a458011a..205f295e724 100644 --- a/tests/robotests/src/com/android/settings/media/MediaOutputSliceTest.java +++ b/tests/robotests/src/com/android/settings/media/MediaOutputSliceTest.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; import android.content.Context; import android.content.Intent; +import android.graphics.drawable.Drawable; import androidx.slice.Slice; import androidx.slice.SliceMetadata; @@ -66,6 +67,8 @@ public class MediaOutputSliceTest { @Mock private LocalMediaManager mLocalMediaManager; + @Mock + private Drawable mTestDrawable; private final List mDevices = new ArrayList<>(); @@ -105,7 +108,7 @@ public class MediaOutputSliceTest { mDevices.clear(); final MediaDevice device = mock(MediaDevice.class); when(device.getName()).thenReturn(TEST_DEVICE_1_NAME); - when(device.getIcon()).thenReturn(TEST_DEVICE_1_ICON); + when(device.getIcon()).thenReturn(mTestDrawable); when(mLocalMediaManager.getCurrentConnectedDevice()).thenReturn(device); final Slice mediaSlice = mMediaOutputSlice.getSlice(); diff --git a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceControllerTest.java index 78ed4b596d3..bea8f679604 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/Enhanced4gLtePreferenceControllerTest.java @@ -102,13 +102,60 @@ public class Enhanced4gLtePreferenceControllerTest { } @Test - public void updateState_variant4gLte_useVariantTitle() { + public void updateState_doNotShow4GForLTE_showVolteTitleAndSummary() { + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, false); + + mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 0); + mController.updateState(mPreference); + assertThat(mPreference.getTitle()).isEqualTo( + mContext.getString(R.string.enhanced_4g_lte_mode_title)); + assertThat(mPreference.getSummary()).isEqualTo( + mContext.getString(R.string.enhanced_4g_lte_mode_summary)); + + mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 2); + mController.updateState(mPreference); + assertThat(mPreference.getTitle()).isEqualTo( + mContext.getString(R.string.enhanced_4g_lte_mode_title)); + assertThat(mPreference.getSummary()).isEqualTo( + mContext.getString(R.string.enhanced_4g_lte_mode_summary)); + } + + @Test + public void updateState_show4GForLTE_show4GTitleAndSummary() { + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, true); + + mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 0); + mController.updateState(mPreference); + assertThat(mPreference.getTitle()).isEqualTo( + mContext.getString(R.string.enhanced_4g_lte_mode_title_4g_calling)); + assertThat(mPreference.getSummary()).isEqualTo( + mContext.getString(R.string.enhanced_4g_lte_mode_summary_4g_calling)); + + mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 2); + mController.updateState(mPreference); + assertThat(mPreference.getTitle()).isEqualTo( + mContext.getString(R.string.enhanced_4g_lte_mode_title_4g_calling)); + assertThat(mPreference.getSummary()).isEqualTo( + mContext.getString(R.string.enhanced_4g_lte_mode_summary_4g_calling)); + } + + @Test + public void updateState_variantAdvancedCalling_showAdvancedCallingTitleAndSummary() { mCarrierConfig.putInt(CarrierConfigManager.KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 1); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, false); mController.updateState(mPreference); - assertThat(mPreference.getTitle()).isEqualTo( - mContext.getString(R.string.enhanced_4g_lte_mode_title_variant)); + mContext.getString(R.string.enhanced_4g_lte_mode_title_advanced_calling)); + assertThat(mPreference.getSummary()).isEqualTo( + mContext.getString(R.string.enhanced_4g_lte_mode_summary)); + + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, true); + mController.updateState(mPreference); + assertThat(mPreference.getTitle()).isEqualTo( + mContext.getString(R.string.enhanced_4g_lte_mode_title_advanced_calling)); + assertThat(mPreference.getSummary()).isEqualTo( + mContext.getString(R.string.enhanced_4g_lte_mode_summary)); } @Test diff --git a/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java index c0b1dab0efd..9eb62f6ee9a 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/WifiCallingPreferenceControllerTest.java @@ -18,11 +18,14 @@ package com.android.settings.network.telephony; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.Context; +import android.os.PersistableBundle; +import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; @@ -32,6 +35,7 @@ import androidx.preference.PreferenceScreen; import com.android.ims.ImsConfig; import com.android.ims.ImsManager; +import com.android.internal.R; import com.android.settings.core.BasePreferenceController; import org.junit.Before; @@ -46,6 +50,8 @@ import org.robolectric.RuntimeEnvironment; public class WifiCallingPreferenceControllerTest { private static final int SUB_ID = 2; + @Mock + private CarrierConfigManager mCarrierConfigManager; @Mock private TelephonyManager mTelephonyManager; @Mock @@ -57,6 +63,7 @@ public class WifiCallingPreferenceControllerTest { private Preference mPreference; private PreferenceCategory mPreferenceCategory; private Context mContext; + private PersistableBundle mCarrierConfig; @Before public void setUp() { @@ -69,10 +76,14 @@ public class WifiCallingPreferenceControllerTest { mPreference = new Preference(mContext); mController = new WifiCallingPreferenceController(mContext, "wifi_calling"); + mController.mCarrierConfigManager = mCarrierConfigManager; mController.init(SUB_ID); mController.mImsManager = mImsManager; mPreference.setKey(mController.getPreferenceKey()); + mCarrierConfig = new PersistableBundle(); + when(mCarrierConfigManager.getConfigForSubId(SUB_ID)).thenReturn(mCarrierConfig); + mPreferenceCategory = new PreferenceCategory(mContext); when(mPreferenceScreen.findPreference( WifiCallingPreferenceController.KEY_PREFERENCE_CATEGORY)).thenReturn( @@ -102,6 +113,42 @@ public class WifiCallingPreferenceControllerTest { assertThat(mPreference.isEnabled()).isFalse(); } + @Test + public void updateState_wfcNonRoaming() { + assertNull(mController.mSimCallManager); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false); + // update the config value by calling init again. + mController.init(SUB_ID); + mController.mImsManager = mImsManager; + + when(mImsManager.getWfcMode(true)).thenReturn( + ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED); + when(mImsManager.getWfcMode(false)).thenReturn( + ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED); + when(mImsManager.isWfcEnabledByUser()).thenReturn(true); + when(mTelephonyManager.isNetworkRoaming()).thenReturn(true); + + mController.updateState(mPreference); + assertThat(mPreference.getSummary()) + .isEqualTo(mContext.getString(R.string.wfc_mode_cellular_preferred_summary)); + } + + @Test + public void updateState_wfcRoaming() { + assertNull(mController.mSimCallManager); + + when(mImsManager.getWfcMode(true)).thenReturn( + ImsConfig.WfcModeFeatureValueConstants.WIFI_PREFERRED); + when(mImsManager.getWfcMode(false)).thenReturn( + ImsConfig.WfcModeFeatureValueConstants.CELLULAR_PREFERRED); + when(mImsManager.isWfcEnabledByUser()).thenReturn(true); + when(mTelephonyManager.isNetworkRoaming()).thenReturn(true); + + mController.updateState(mPreference); + assertThat(mPreference.getSummary()) + .isEqualTo(mContext.getString(R.string.wfc_mode_wifi_preferred_summary)); + } + @Test public void displayPreference_notAvailable_setCategoryInvisible() { mController.init(SubscriptionManager.INVALID_SUBSCRIPTION_ID); diff --git a/tests/robotests/src/com/android/settings/notification/AppNotificationSettingsTest.java b/tests/robotests/src/com/android/settings/notification/AppNotificationSettingsTest.java deleted file mode 100644 index 9555a56e1ba..00000000000 --- a/tests/robotests/src/com/android/settings/notification/AppNotificationSettingsTest.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.android.settings.notification; - -import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.view.Window; -import android.view.WindowManager; - -import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; -import org.robolectric.annotation.Implementation; -import org.robolectric.annotation.Implements; - -@RunWith(RobolectricTestRunner.class) -public class AppNotificationSettingsTest { - - private WindowManager.LayoutParams mLayoutParams; - private AppNotificationSettings mFragment; - private FragmentActivity mActivity; - @Mock - private Window mWindow; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mLayoutParams = new WindowManager.LayoutParams(); - mActivity = spy(Robolectric.setupActivity(FragmentActivity.class)); - mFragment = spy(new AppNotificationSettings()); - when(mFragment.getActivity()).thenReturn(mActivity); - when(mFragment.getFragmentManager()).thenReturn(mock(FragmentManager.class)); - when(mActivity.getWindow()).thenReturn(mWindow); - when(mWindow.getAttributes()).thenReturn(mLayoutParams); - } - - @Test - @Config(shadows = {ShadowNotificationSettingsBase.class}) - public void onResume_shouldHideSystemOverlay() { - mFragment.onResume(); - - verify(mWindow).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); - } - - @Test - @Config(shadows = {ShadowNotificationSettingsBase.class}) - public void onPause_shouldRemoveHideSystemOverlay() { - mFragment.onResume(); - - verify(mWindow).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); - - mFragment.onPause(); - - // There's no Window.clearPrivateFlags() method, so the Window.attributes are updated. - ArgumentCaptor paramCaptor = ArgumentCaptor.forClass( - WindowManager.LayoutParams.class); - verify(mWindow).setAttributes(paramCaptor.capture()); - assertEquals(0, - paramCaptor.getValue().privateFlags - & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS); - } - - @Implements(NotificationSettingsBase.class) - public static class ShadowNotificationSettingsBase { - - protected void __constructor__() { - // Do nothing - } - - @Implementation - protected void onResume() { - // No-op. - } - - @Implementation - protected void onPause() { - // No-op. - } - } -} diff --git a/tests/robotests/src/com/android/settings/notification/BubblePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BubblePreferenceControllerTest.java index 99787d824bc..6d13798bd27 100644 --- a/tests/robotests/src/com/android/settings/notification/BubblePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/BubblePreferenceControllerTest.java @@ -23,6 +23,7 @@ import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -223,6 +224,7 @@ public class BubblePreferenceControllerTest { @Test public void testUpdateState_app() { NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.label = "App!"; appRow.allowBubbles = true; mController.onResume(appRow, null, null, null); @@ -235,6 +237,9 @@ public class BubblePreferenceControllerTest { mController.updateState(pref); assertFalse(pref.isChecked()); + + assertNotNull(pref.getSummary()); + assertTrue(pref.getSummary().toString().contains(appRow.label)); } @Test diff --git a/tests/robotests/src/com/android/settings/notification/BubbleSummaryNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BubbleSummaryNotificationPreferenceControllerTest.java new file mode 100644 index 00000000000..4bdb2cca72a --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/BubbleSummaryNotificationPreferenceControllerTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.notification; + +import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES; + +import static com.android.settings.notification.BadgingNotificationPreferenceController.OFF; +import static com.android.settings.notification.BadgingNotificationPreferenceController.ON; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.provider.Settings; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +import androidx.preference.Preference; + +@RunWith(RobolectricTestRunner.class) +public class BubbleSummaryNotificationPreferenceControllerTest { + + private Context mContext; + + private BubbleSummaryNotificationPreferenceController mController; + private Preference mPreference; + + private static final String KEY_NOTIFICATION_BUBBLES = "notification_bubbles"; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mController = new BubbleSummaryNotificationPreferenceController(mContext, + KEY_NOTIFICATION_BUBBLES); + mPreference = new Preference(RuntimeEnvironment.application); + } + + @Test + public void display_shouldDisplay() { + assertThat(mPreference.isVisible()).isTrue(); + } + + @Test + public void getSummary() { + Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, OFF); + + assertThat(mController.getSummary()).isEqualTo("Off"); + + Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, ON); + + assertThat(mController.getSummary()).isEqualTo("On"); + } +} diff --git a/tests/robotests/src/com/android/settings/notification/BubbleSummaryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BubbleSummaryPreferenceControllerTest.java new file mode 100644 index 00000000000..5158e82e3b4 --- /dev/null +++ b/tests/robotests/src/com/android/settings/notification/BubbleSummaryPreferenceControllerTest.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.notification; + +import static android.app.NotificationChannel.DEFAULT_CHANNEL_ID; +import static android.app.NotificationManager.IMPORTANCE_HIGH; +import static android.app.NotificationManager.IMPORTANCE_LOW; +import static android.app.NotificationManager.IMPORTANCE_NONE; +import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES; + +import static junit.framework.TestCase.assertEquals; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.Context; +import android.os.UserManager; +import android.provider.Settings; + +import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedSwitchPreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.shadows.ShadowApplication; + +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +@RunWith(RobolectricTestRunner.class) +public class BubbleSummaryPreferenceControllerTest { + + private Context mContext; + @Mock + private NotificationBackend mBackend; + + private BubbleSummaryPreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + ShadowApplication shadowApplication = ShadowApplication.getInstance(); + mContext = RuntimeEnvironment.application; + mController = spy(new BubbleSummaryPreferenceController(mContext, mBackend)); + } + + @Test + public void testNoCrashIfNoOnResume() { + mController.isAvailable(); + mController.updateState(mock(Preference.class)); + } + + @Test + public void testIsAvailable_notIfAppBlocked() { + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.banned = true; + mController.onResume(appRow, mock(NotificationChannel.class), null, null); + assertFalse(mController.isAvailable()); + } + + @Test + public void testIsAvailable_notIfOffGlobally() { + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + NotificationChannel channel = mock(NotificationChannel.class); + when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); + mController.onResume(appRow, channel, null, null); + Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 0); + + assertFalse(mController.isAvailable()); + } + + @Test + public void testIsAvailable_app() { + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + mController.onResume(appRow, null, null, null); + Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1); + + assertTrue(mController.isAvailable()); + } + + @Test + public void testIsAvailable_defaultChannel() { + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.allowBubbles = true; + NotificationChannel channel = mock(NotificationChannel.class); + when(channel.getImportance()).thenReturn(IMPORTANCE_HIGH); + when(channel.getId()).thenReturn(DEFAULT_CHANNEL_ID); + mController.onResume(appRow, channel, null, null); + Settings.Secure.putInt(mContext.getContentResolver(), NOTIFICATION_BUBBLES, 1); + + assertTrue(mController.isAvailable()); + } + + @Test + public void testUpdateState() { + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.allowBubbles = true; + mController.onResume(appRow, null, null, null); + + Preference pref = new Preference(mContext); + mController.updateState(pref); + assertNotNull(pref.getIntent()); + } + + @Test + public void testGetSummary() { + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.allowBubbles = true; + mController.onResume(appRow, null, null, null); + + assertEquals("On", mController.getSummary()); + + appRow.allowBubbles = false; + mController.onResume(appRow, null, null, null); + + assertEquals("Off", mController.getSummary()); + } +} diff --git a/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java index 2368af5f94b..9c53a7bfec0 100644 --- a/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/NotificationPreferenceControllerTest.java @@ -317,6 +317,30 @@ public class NotificationPreferenceControllerTest { assertTrue(mController.isChannelGroupBlockable()); } + @Test + public void testIsChannelBlockable_oemLocked() { + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.systemApp = false; + NotificationChannel channel = mock(NotificationChannel.class); + when(channel.isImportanceLockedByOEM()).thenReturn(true); + when(channel.getImportance()).thenReturn(IMPORTANCE_DEFAULT); + + mController.onResume(appRow, channel, null, null); + assertFalse(mController.isChannelBlockable()); + } + + @Test + public void testIsChannelBlockable_criticalDeviceFunction() { + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + appRow.systemApp = false; + NotificationChannel channel = mock(NotificationChannel.class); + when(channel.isImportanceLockedByCriticalDeviceFunction()).thenReturn(true); + when(channel.getImportance()).thenReturn(IMPORTANCE_DEFAULT); + + mController.onResume(appRow, channel, null, null); + assertFalse(mController.isChannelBlockable()); + } + @Test public void testIsChannelGroupBlockable_SystemNotBlockable() { NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); diff --git a/tests/robotests/src/com/android/settings/notification/SoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/SoundPreferenceControllerTest.java index 1b4ede5b14f..866f8668a21 100644 --- a/tests/robotests/src/com/android/settings/notification/SoundPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/SoundPreferenceControllerTest.java @@ -39,6 +39,8 @@ import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.content.Intent; +import android.media.AudioAttributes; +import android.media.RingtoneManager; import android.net.Uri; import android.os.UserManager; import android.provider.Settings; @@ -54,6 +56,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; +import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.Robolectric; @@ -230,6 +233,69 @@ public class SoundPreferenceControllerTest { verify(mFragment, times(1)).startActivityForResult(any(), anyInt()); } + @Test + public void testOnPreferenceTreeClick_alarmSound() { + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); + channel.setSound(null, new AudioAttributes.Builder().setUsage( + AudioAttributes.USAGE_ALARM).build()); + mController.onResume(appRow, channel, null, null); + + AttributeSet attributeSet = Robolectric.buildAttributeSet().build(); + NotificationSoundPreference pref = + spy(new NotificationSoundPreference(mContext, attributeSet)); + pref.setKey(mController.getPreferenceKey()); + mController.handlePreferenceTreeClick(pref); + + ArgumentCaptor intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(pref, times(1)).onPrepareRingtonePickerIntent(intentArgumentCaptor.capture()); + assertEquals(RingtoneManager.TYPE_ALARM, + intentArgumentCaptor.getValue().getIntExtra( + RingtoneManager.EXTRA_RINGTONE_TYPE, 0)); + } + + @Test + public void testOnPreferenceTreeClick_ringtoneSound() { + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); + channel.setSound(null, new AudioAttributes.Builder().setUsage( + AudioAttributes.USAGE_NOTIFICATION_RINGTONE).build()); + mController.onResume(appRow, channel, null, null); + + AttributeSet attributeSet = Robolectric.buildAttributeSet().build(); + NotificationSoundPreference pref = + spy(new NotificationSoundPreference(mContext, attributeSet)); + pref.setKey(mController.getPreferenceKey()); + mController.handlePreferenceTreeClick(pref); + + ArgumentCaptor intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(pref, times(1)).onPrepareRingtonePickerIntent(intentArgumentCaptor.capture()); + assertEquals(RingtoneManager.TYPE_RINGTONE, + intentArgumentCaptor.getValue().getIntExtra( + RingtoneManager.EXTRA_RINGTONE_TYPE, 0)); + } + + @Test + public void testOnPreferenceTreeClick_otherSound() { + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); + channel.setSound(null, new AudioAttributes.Builder().setUsage( + AudioAttributes.USAGE_UNKNOWN).build()); + mController.onResume(appRow, channel, null, null); + + AttributeSet attributeSet = Robolectric.buildAttributeSet().build(); + NotificationSoundPreference pref = + spy(new NotificationSoundPreference(mContext, attributeSet)); + pref.setKey(mController.getPreferenceKey()); + mController.handlePreferenceTreeClick(pref); + + ArgumentCaptor intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(pref, times(1)).onPrepareRingtonePickerIntent(intentArgumentCaptor.capture()); + assertEquals(RingtoneManager.TYPE_NOTIFICATION, + intentArgumentCaptor.getValue().getIntExtra( + RingtoneManager.EXTRA_RINGTONE_TYPE, 0)); + } + @Test public void testOnActivityResult() { NotificationSoundPreference pref = mock(NotificationSoundPreference.class); diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java index 3509d75ab81..48ebbecd884 100644 --- a/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java +++ b/tests/robotests/src/com/android/settings/password/ChooseLockPatternTest.java @@ -107,7 +107,7 @@ public class ChooseLockPatternTest { ChooseLockPatternFragment fragment = (ChooseLockPatternFragment) activity.getSupportFragmentManager().findFragmentById(R.id.main_content); - View iconView = fragment.getView().findViewById(R.id.suc_layout_icon); + View iconView = fragment.getView().findViewById(R.id.sud_layout_icon); assertThat(iconView.getVisibility()).isEqualTo(View.GONE); } diff --git a/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java index 332156e8b9a..988816897a7 100644 --- a/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java @@ -16,6 +16,14 @@ package com.android.settings.privacy; +import static android.Manifest.permission_group.CALENDAR; +import static android.Manifest.permission_group.CAMERA; +import static android.Manifest.permission_group.CONTACTS; +import static android.Manifest.permission_group.LOCATION; +import static android.Manifest.permission_group.MICROPHONE; +import static android.Manifest.permission_group.PHONE; +import static android.Manifest.permission_group.SMS; + import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE; import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE; @@ -221,4 +229,27 @@ public class PermissionBarChartPreferenceControllerTest { verify(mFragment).setLoadingEnabled(false /* enabled */); verify(mPreference).updateLoadingState(false /* isLoading */); } + + @Test + public void onPermissionUsageResult_shouldBeSorted() { + final List infos = new ArrayList<>(); + infos.add(new RuntimePermissionUsageInfo(PHONE, 10)); + infos.add(new RuntimePermissionUsageInfo(LOCATION, 10)); + infos.add(new RuntimePermissionUsageInfo(CAMERA, 10)); + infos.add(new RuntimePermissionUsageInfo(SMS, 1)); + infos.add(new RuntimePermissionUsageInfo(MICROPHONE, 10)); + infos.add(new RuntimePermissionUsageInfo(CONTACTS, 42)); + infos.add(new RuntimePermissionUsageInfo(CALENDAR, 10)); + mController.displayPreference(mScreen); + + mController.onPermissionUsageResult(infos); + + assertThat(infos.get(0).getName()).isEqualTo(CONTACTS); + assertThat(infos.get(1).getName()).isEqualTo(LOCATION); + assertThat(infos.get(2).getName()).isEqualTo(MICROPHONE); + assertThat(infos.get(3).getName()).isEqualTo(CAMERA); + assertThat(infos.get(4).getName()).isEqualTo(CALENDAR); + assertThat(infos.get(5).getName()).isEqualTo(PHONE); + assertThat(infos.get(6).getName()).isEqualTo(SMS); + } } diff --git a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java index 005ffbebc08..9f121306b8c 100644 --- a/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java +++ b/tests/robotests/src/com/android/settings/slices/SettingsSliceProviderTest.java @@ -55,7 +55,7 @@ import com.android.settings.testutils.shadow.ShadowLockPatternUtils; import com.android.settings.testutils.shadow.ShadowThreadUtils; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settings.testutils.shadow.ShadowUtils; -import com.android.settings.wifi.slice.WifiSlice; +import com.android.settings.wifi.slice.WifiScanWorker; import com.android.settingslib.wifi.WifiTracker; import org.junit.After; @@ -474,7 +474,7 @@ public class SettingsSliceProviderTest { mProvider.onSlicePinned(uri); } - @Implements(WifiSlice.WifiScanWorker.class) + @Implements(WifiScanWorker.class) public static class ShadowWifiScanWorker { private static WifiTracker mWifiTracker; diff --git a/tests/robotests/src/com/android/settings/system/SystemDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/system/SystemDashboardFragmentTest.java index 75cd552ab01..7bdc368364b 100644 --- a/tests/robotests/src/com/android/settings/system/SystemDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/system/SystemDashboardFragmentTest.java @@ -18,8 +18,17 @@ package com.android.settings.system; import static com.google.common.truth.Truth.assertThat; -import android.content.Context; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import android.content.Context; +import android.os.Bundle; + +import com.android.settings.aware.AwareFeatureProvider; +import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.XmlTestUtils; import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settings.testutils.shadow.ShadowUserManager; @@ -38,11 +47,17 @@ import java.util.List; @Config(shadows = {SettingsShadowResources.class, ShadowUserManager.class}) public class SystemDashboardFragmentTest { + private Context mContext; + private SystemDashboardFragment mFragment; + @Before public void setup() { SettingsShadowResources.overrideResource( com.android.internal.R.bool.config_supportSystemNavigationKeys, true); ShadowUserManager.getShadow().setIsAdminUser(true); + mContext = RuntimeEnvironment.application; + mFragment = spy(new SystemDashboardFragment()); + when(mFragment.getContext()).thenReturn(mContext); } @After @@ -52,13 +67,35 @@ public class SystemDashboardFragmentTest { @Test public void testNonIndexableKeys_existInXmlLayout() { - final Context context = RuntimeEnvironment.application; final List niks = SystemDashboardFragment.SEARCH_INDEX_DATA_PROVIDER - .getNonIndexableKeys(context); + .getNonIndexableKeys(mContext); final int xmlId = (new SystemDashboardFragment()).getPreferenceScreenResId(); - final List keys = XmlTestUtils.getKeysFromPreferenceXml(context, xmlId); + final List keys = XmlTestUtils.getKeysFromPreferenceXml(mContext, xmlId); assertThat(keys).containsAllIn(niks); } + + @Test + public void showRestrictionDialog_hasValidExtra_shouldShowDialog() { + final AwareFeatureProvider mProvider = + FakeFeatureFactory.setupForTest().mAwareFeatureProvider; + final Bundle bundle = new Bundle(); + bundle.putBoolean(SystemDashboardFragment.EXTRA_SHOW_AWARE_DISABLED, true); + when(mFragment.getArguments()).thenReturn(bundle); + + mFragment.showRestrictionDialog(); + + verify(mProvider).showRestrictionDialog(any()); + } + + @Test + public void showRestrictionDialog_hasInvalidExtra_shouldNotShowDialog() { + final AwareFeatureProvider mProvider = + FakeFeatureFactory.setupForTest().mAwareFeatureProvider; + + mFragment.showRestrictionDialog(); + + verify(mProvider, never()).showRestrictionDialog(any()); + } } diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java index bceba3c9864..a85fe107b3c 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowUserManager.java @@ -22,6 +22,8 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.UserManager.EnforcingUser; +import com.google.android.collect.Maps; + import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -48,6 +50,7 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager private boolean mIsQuietModeEnabled = false; private int[] profileIdsForUser = new int[0]; private boolean mUserSwitchEnabled; + private final Map mSameProfileGroupIds = Maps.newHashMap(); public void addProfile(UserInfo userInfo) { mUserProfileInfos.add(userInfo); @@ -138,6 +141,18 @@ public class ShadowUserManager extends org.robolectric.shadows.ShadowUserManager return sIsSupportsMultipleUsers; } + @Implementation + protected boolean isSameProfileGroup(@UserIdInt int userId, int otherUserId) { + return mSameProfileGroupIds.containsKey(userId) + && mSameProfileGroupIds.get(userId) == otherUserId + || mSameProfileGroupIds.containsKey(otherUserId) + && mSameProfileGroupIds.get(otherUserId) == userId; + } + + public Map getSameProfileGroupIds() { + return mSameProfileGroupIds; + } + public void setSupportsMultipleUsers(boolean supports) { sIsSupportsMultipleUsers = supports; } diff --git a/tests/robotests/src/com/android/settings/widget/AdaptiveIconTest.java b/tests/robotests/src/com/android/settings/widget/AdaptiveIconTest.java deleted file mode 100644 index 1be3332c222..00000000000 --- a/tests/robotests/src/com/android/settings/widget/AdaptiveIconTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.widget; - -import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB; -import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON_BACKGROUND_HINT; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.pm.ActivityInfo; -import android.graphics.Color; -import android.graphics.PorterDuff; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Icon; -import android.graphics.drawable.ShapeDrawable; -import android.os.Bundle; - -import com.android.settings.R; -import com.android.settings.homepage.AdaptiveIconShapeDrawable; -import com.android.settingslib.drawer.CategoryKey; -import com.android.settingslib.drawer.Tile; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class AdaptiveIconTest { - - private Context mContext; - private ActivityInfo mActivityInfo; - - @Before - public void setUp() { - mContext = RuntimeEnvironment.application; - mActivityInfo = new ActivityInfo(); - mActivityInfo.packageName = mContext.getPackageName(); - mActivityInfo.name = "class"; - mActivityInfo.metaData = new Bundle(); - } - - @Test - public void createIcon_shouldSetBackgroundAndInset() { - final AdaptiveIcon icon = - new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); - - assertThat(icon.getNumberOfLayers()).isEqualTo(2); - assertThat(icon.getDrawable(0)).isInstanceOf(AdaptiveIconShapeDrawable.class); - } - - @Test - public void setBackgroundColor_shouldUpdateColorFilter() { - final AdaptiveIcon icon = - spy(new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK))); - final ShapeDrawable background = mock(ShapeDrawable.class); - when(icon.getDrawable(0)).thenReturn(background); - - icon.setBackgroundColor(Color.BLUE); - - verify(background).setColorFilter(Color.BLUE, PorterDuff.Mode.SRC_ATOP); - } - - @Test - public void setBackgroundColor_externalTileWithBackgroundColorRawValue_shouldUpdateIcon() { - final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); - mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB, 0xff0000); - doReturn(Icon.createWithResource(mContext, R.drawable.ic_settings_accent)) - .when(tile).getIcon(mContext); - final AdaptiveIcon icon = - new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); - - icon.setBackgroundColor(mContext, tile); - assertThat(icon.mBackgroundColor).isEqualTo(0xff0000); - } - - @Test - public void setBackgroundColor_tileWithoutBackgroundColor_shouldSetDefaultBackgroundColor() { - final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); - doReturn(Icon.createWithResource(mContext, R.drawable.ic_settings_accent)) - .when(tile).getIcon(mContext); - final AdaptiveIcon icon = - new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); - - icon.setBackgroundColor(mContext, tile); - - assertThat(icon.mBackgroundColor).isEqualTo( - mContext.getColor(R.color.homepage_generic_icon_background)); - } - - @Test - public void onBindTile_externalTileWithBackgroundColorHint_shouldUpdateIcon() { - final Tile tile = spy(new Tile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE)); - mActivityInfo.metaData.putInt(META_DATA_PREFERENCE_ICON_BACKGROUND_HINT, - R.color.material_blue_500); - doReturn(Icon.createWithResource(mContext, R.drawable.ic_settings_accent)) - .when(tile).getIcon(mContext); - - final AdaptiveIcon icon = - new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); - icon.setBackgroundColor(mContext, tile); - - assertThat(icon.mBackgroundColor) - .isEqualTo(mContext.getColor(R.color.material_blue_500)); - } - - @Test - public void getConstantState_returnCorrectState() { - final AdaptiveIcon icon = - new AdaptiveIcon(mContext, new ColorDrawable(Color.BLACK)); - icon.setBackgroundColor(Color.YELLOW); - - final AdaptiveIcon.AdaptiveConstantState state = - (AdaptiveIcon.AdaptiveConstantState) icon.getConstantState(); - - assertThat(state.color).isEqualTo(Color.YELLOW); - assertThat(state.context).isEqualTo(mContext); - } -} diff --git a/tests/robotests/src/com/android/settings/widget/AppCheckBoxPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/AppCheckBoxPreferenceTest.java index 57c6e01749e..6340b164dd9 100644 --- a/tests/robotests/src/com/android/settings/widget/AppCheckBoxPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/widget/AppCheckBoxPreferenceTest.java @@ -35,8 +35,6 @@ import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) public class AppCheckBoxPreferenceTest { - private static final String SUMMARY = "summary info"; - private Context mContext; private AppCheckBoxPreference mPreference; private AppCheckBoxPreference mAttrPreference; @@ -57,26 +55,6 @@ public class AppCheckBoxPreferenceTest { assertThat(mAttrPreference.getLayoutResource()).isEqualTo(R.layout.preference_app); } - @Test - public void onBindViewHolder_noSummary_layoutGone() { - mPreference.setSummary(""); - - mPreference.onBindViewHolder(mPreferenceViewHolder); - - assertThat(mPreferenceViewHolder.findViewById(R.id.summary_container).getVisibility()) - .isEqualTo(View.GONE); - } - - @Test - public void onBindViewHolder_hasSummary_layoutVisible() { - mPreference.setSummary(SUMMARY); - - mPreference.onBindViewHolder(mPreferenceViewHolder); - - assertThat(mPreferenceViewHolder.findViewById(R.id.summary_container).getVisibility()) - .isEqualTo(View.VISIBLE); - } - @Test public void onBindViewHolder_appendixGone() { mPreference.onBindViewHolder(mPreferenceViewHolder); diff --git a/tests/robotests/src/com/android/settings/widget/AppSwitchPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/AppSwitchPreferenceTest.java deleted file mode 100644 index aa5e3e768a2..00000000000 --- a/tests/robotests/src/com/android/settings/widget/AppSwitchPreferenceTest.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.widget; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.Context; -import android.view.View; - -import androidx.preference.PreferenceViewHolder; - -import com.android.settings.R; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class AppSwitchPreferenceTest { - - private Context mContext; - private View mRootView; - private AppSwitchPreference mPref; - private PreferenceViewHolder mHolder; - - @Before - public void setUp() { - mContext = RuntimeEnvironment.application; - mRootView = View.inflate(mContext, R.layout.preference_app, null /* parent */); - mHolder = PreferenceViewHolder.createInstanceForTests(mRootView); - mPref = new AppSwitchPreference(mContext); - } - - @Test - public void setSummary_showSummaryContainer() { - mPref.setSummary("test"); - mPref.onBindViewHolder(mHolder); - - assertThat(mHolder.findViewById(R.id.summary_container).getVisibility()) - .isEqualTo(View.VISIBLE); - } - - @Test - public void noSummary_hideSummaryContainer() { - mPref.setSummary(null); - mPref.onBindViewHolder(mHolder); - - assertThat(mHolder.findViewById(R.id.summary_container).getVisibility()) - .isEqualTo(View.GONE); - } -} diff --git a/tests/robotests/src/com/android/settings/widget/VideoPreferenceTest.java b/tests/robotests/src/com/android/settings/widget/VideoPreferenceTest.java index 4cd6be4c15f..b53f3644575 100644 --- a/tests/robotests/src/com/android/settings/widget/VideoPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/widget/VideoPreferenceTest.java @@ -18,6 +18,10 @@ package com.android.settings.widget; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; @@ -29,6 +33,8 @@ import android.media.MediaPlayer; import android.view.LayoutInflater; import android.view.TextureView; +import android.view.View; +import android.widget.ImageView; import androidx.preference.PreferenceViewHolder; import com.android.settings.R; @@ -45,8 +51,13 @@ import org.robolectric.RuntimeEnvironment; public class VideoPreferenceTest { private static final int VIDEO_WIDTH = 100; private static final int VIDEO_HEIGHT = 150; + @Mock private MediaPlayer mMediaPlayer; + @Mock + private ImageView fakePreview; + @Mock + private ImageView fakePlayButton; private Context mContext; private VideoPreference mVideoPreference; private PreferenceViewHolder mPreferenceViewHolder; @@ -83,8 +94,8 @@ public class VideoPreferenceTest { (TextureView) mPreferenceViewHolder.findViewById(R.id.video_texture_view); mVideoPreference.mAnimationAvailable = true; mVideoPreference.mVideoReady = true; - mVideoPreference.onBindViewHolder(mPreferenceViewHolder); mVideoPreference.onViewInvisible(); + mVideoPreference.onBindViewHolder(mPreferenceViewHolder); when(mMediaPlayer.isPlaying()).thenReturn(false); final TextureView.SurfaceTextureListener listener = video.getSurfaceTextureListener(); @@ -101,4 +112,30 @@ public class VideoPreferenceTest { verify(mMediaPlayer).release(); } + + @Test + public void updateViewStates_paused_updatesViews() { + when(mMediaPlayer.isPlaying()).thenReturn(true); + mVideoPreference.updateViewStates(fakePreview, fakePlayButton); + verify(fakePlayButton).setVisibility(eq(View.VISIBLE)); + verify(fakePreview).setVisibility(eq(View.VISIBLE)); + verify(mMediaPlayer).pause(); + } + + @Test + public void updateViewStates_playing_updatesViews() { + when(mMediaPlayer.isPlaying()).thenReturn(false); + mVideoPreference.updateViewStates(fakePreview, fakePlayButton); + verify(fakePlayButton).setVisibility(eq(View.GONE)); + verify(fakePreview).setVisibility(eq(View.GONE)); + verify(mMediaPlayer).start(); + } + + @Test + public void updateViewStates_noMediaPlayer_skips() { + mVideoPreference.mMediaPlayer = null; + mVideoPreference.updateViewStates(fakePreview, fakePlayButton); + verify(fakePlayButton, never()).setVisibility(anyInt()); + verify(fakePreview, never()).setVisibility(anyInt()); + } } diff --git a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingDisclaimerFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingDisclaimerFragmentTest.java index 6c221e797f9..25fa737b591 100644 --- a/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingDisclaimerFragmentTest.java +++ b/tests/robotests/src/com/android/settings/wifi/calling/WifiCallingDisclaimerFragmentTest.java @@ -35,6 +35,7 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; +import androidx.fragment.app.FragmentActivity; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView.OnScrollListener; @@ -60,7 +61,7 @@ import org.robolectric.RobolectricTestRunner; public class WifiCallingDisclaimerFragmentTest { @Mock - private Activity mActivity; + private FragmentActivity mActivity; @Mock private DisclaimerItem mDisclaimerItem; @Mock @@ -89,7 +90,7 @@ public class WifiCallingDisclaimerFragmentTest { public void setUp() { MockitoAnnotations.initMocks(this); - mActivity = Robolectric.setupActivity(Activity.class); + mActivity = Robolectric.setupActivity(FragmentActivity.class); mFragment = spy(new WifiCallingDisclaimerFragment()); doReturn(mActivity).when(mFragment).getActivity(); diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java index 574d0d651cc..307712e686b 100644 --- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailPreferenceControllerTest.java @@ -43,6 +43,7 @@ import android.net.ConnectivityManager.NetworkCallback; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; +import android.net.MacAddress; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; @@ -53,6 +54,7 @@ import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Handler; import android.provider.Settings; +import android.util.FeatureFlagUtils; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; @@ -75,6 +77,8 @@ import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.widget.ActionButtonsPreference; import com.android.settingslib.widget.LayoutPreference; import com.android.settingslib.wifi.AccessPoint; +import com.android.settingslib.wifi.WifiTracker; +import com.android.settingslib.wifi.WifiTrackerFactory; import org.junit.Before; import org.junit.Test; @@ -94,6 +98,7 @@ import java.net.Inet4Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; +import java.util.ArrayList; import java.util.stream.Collectors; @RunWith(RobolectricTestRunner.class) @@ -104,7 +109,10 @@ public class WifiDetailPreferenceControllerTest { private static final int RSSI = -55; private static final int TX_LINK_SPEED = 123; private static final int RX_LINK_SPEED = 54; + private static final String SSID = "ssid"; private static final String MAC_ADDRESS = WifiInfo.DEFAULT_MAC_ADDRESS; + private static final String RANDOMIZED_MAC_ADDRESS = "RANDOMIZED_MAC_ADDRESS"; + private static final String FACTORY_MAC_ADDRESS = "FACTORY_MAC_ADDRESS"; private static final String SECURITY = "None"; @Mock(answer = Answers.RETURNS_DEEP_STUBS) @@ -129,9 +137,13 @@ public class WifiDetailPreferenceControllerTest { @Mock private WifiManager mockWifiManager; @Mock + private WifiTracker mockWifiTracker; + @Mock private MetricsFeatureProvider mockMetricsFeatureProvider; @Mock private WifiDetailPreferenceController.IconInjector mockIconInjector; + @Mock + private MacAddress mockMacAddress; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private EntityHeaderController mockHeaderController; @@ -153,6 +165,8 @@ public class WifiDetailPreferenceControllerTest { @Mock private Preference mockSecurityPref; @Mock + private Preference mockSsidPref; + @Mock private Preference mockMacAddressPref; @Mock private Preference mockIpAddressPref; @@ -244,6 +258,7 @@ public class WifiDetailPreferenceControllerTest { when(mockAccessPoint.getConfig()).thenReturn(mockWifiConfig); when(mockAccessPoint.getLevel()).thenReturn(LEVEL); when(mockAccessPoint.getSecurityString(false)).thenReturn(SECURITY); + when(mockAccessPoint.getSsidStr()).thenReturn(SSID); when(mockConnectivityManager.getNetworkInfo(any(Network.class))) .thenReturn(mockNetworkInfo); doNothing().when(mockConnectivityManager).registerNetworkCallback( @@ -272,6 +287,53 @@ public class WifiDetailPreferenceControllerTest { when(mockIconInjector.getIcon(anyInt())).thenReturn(new ColorDrawable()); setupMockedPreferenceScreen(); + + // Disable saved network detail page feature for this test + FeatureFlagUtils.setEnabled(mContext, FeatureFlags.WIFI_DETAILS_SAVED_SCREEN, false); + when(mockAccessPoint.isActive()).thenReturn(true); + + mController = newWifiDetailPreferenceController(); + } + + private void setUpForConnectedNetwork() { + // Enable saved network detail page feature for this test + FeatureFlagUtils.setEnabled(mContext, FeatureFlags.WIFI_DETAILS_SAVED_SCREEN, true); + when(mockAccessPoint.isActive()).thenReturn(true); + ArrayList list = new ArrayList<>(); + list.add(mockAccessPoint); + when(mockWifiTracker.getAccessPoints()).thenReturn(list); + WifiTrackerFactory.setTestingWifiTracker(mockWifiTracker); + when(mockAccessPoint.matches(any(WifiConfiguration.class))).thenReturn(true); + when(mockAccessPoint.isReachable()).thenReturn(true); + + mController = newWifiDetailPreferenceController(); + } + + private void setUpForDisconnectedNetwork() { + // Enable saved network detail page feature for this test + FeatureFlagUtils.setEnabled(mContext, FeatureFlags.WIFI_DETAILS_SAVED_SCREEN, true); + when(mockAccessPoint.isActive()).thenReturn(false); + ArrayList list = new ArrayList<>(); + list.add(mockAccessPoint); + when(mockWifiTracker.getAccessPoints()).thenReturn(list); + WifiTrackerFactory.setTestingWifiTracker(mockWifiTracker); + when(mockAccessPoint.matches(any(WifiConfiguration.class))).thenReturn(true); + when(mockAccessPoint.isReachable()).thenReturn(true); + + mController = newWifiDetailPreferenceController(); + } + + private void setUpForNotInRangeNetwork() { + // Enable saved network detail page feature for this test + FeatureFlagUtils.setEnabled(mContext, FeatureFlags.WIFI_DETAILS_SAVED_SCREEN, true); + when(mockAccessPoint.isActive()).thenReturn(false); + ArrayList list = new ArrayList<>(); + list.add(mockAccessPoint); + when(mockWifiTracker.getAccessPoints()).thenReturn(list); + WifiTrackerFactory.setTestingWifiTracker(mockWifiTracker); + when(mockAccessPoint.matches(any(WifiConfiguration.class))).thenReturn(false); + when(mockAccessPoint.isReachable()).thenReturn(false); + mController = newWifiDetailPreferenceController(); } @@ -308,6 +370,8 @@ public class WifiDetailPreferenceControllerTest { .thenReturn(mockFrequencyPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SECURITY_PREF)) .thenReturn(mockSecurityPref); + when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_SSID_PREF)) + .thenReturn(mockSsidPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_MAC_ADDRESS_PREF)) .thenReturn(mockMacAddressPref); when(mockScreen.findPreference(WifiDetailPreferenceController.KEY_IP_ADDRESS_PREF)) @@ -350,6 +414,33 @@ public class WifiDetailPreferenceControllerTest { verify(mockWifiManager, times(1)).getConnectionInfo(); } + @Test + public void latestWifiInfo_shouldBeFetchedInDisplayPreferenceForConnectedNetwork() { + setUpForConnectedNetwork(); + + displayAndResume(); + + verify(mockWifiManager, times(1)).getConnectionInfo(); + } + + @Test + public void latestWifiInfo_shouldNotBeFetchedInDisplayPreferenceForDisconnectedNetwork() { + setUpForDisconnectedNetwork(); + + displayAndResume(); + + verify(mockWifiManager, never()).getConnectionInfo(); + } + + @Test + public void latestWifiInfo_shouldNotBeFetchedInDisplayPreferenceForNotInRangeNetwork() { + setUpForNotInRangeNetwork(); + + displayAndResume(); + + verify(mockWifiManager, never()).getConnectionInfo(); + } + @Test public void latestNetworkInfo_shouldBeFetchedInDisplayPreference() { displayAndResume(); @@ -357,6 +448,33 @@ public class WifiDetailPreferenceControllerTest { verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class)); } + @Test + public void latestNetworkInfo_shouldBeFetchedInDisplayPreferenceForConnectedNetwork() { + setUpForConnectedNetwork(); + + displayAndResume(); + + verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class)); + } + + @Test + public void latestNetworkInfo_shouldNotBeFetchedInDisplayPreferenceForDisconnectedNetwork() { + setUpForDisconnectedNetwork(); + + displayAndResume(); + + verify(mockConnectivityManager, never()).getNetworkInfo(any(Network.class)); + } + + @Test + public void latestNetworkInfo_shouldNotBeFetchedInDisplayPreferenceForNotInRangeNetwork() { + setUpForNotInRangeNetwork(); + + displayAndResume(); + + verify(mockConnectivityManager, never()).getNetworkInfo(any(Network.class)); + } + @Test public void networkCallback_shouldBeRegisteredOnResume() { displayAndResume(); @@ -383,6 +501,35 @@ public class WifiDetailPreferenceControllerTest { verify(mockHeaderController).setIcon(expectedIcon); } + @Test + public void entityHeader_shouldHaveIconSetForConnectedNetwork() { + setUpForConnectedNetwork(); + Drawable expectedIcon = mockIconInjector.getIcon(LEVEL); + + displayAndResume(); + + verify(mockHeaderController).setIcon(expectedIcon); + } + + @Test + public void entityHeader_shouldHaveIconSetForDisconnectedNetwork() { + setUpForDisconnectedNetwork(); + Drawable expectedIcon = mockIconInjector.getIcon(LEVEL); + + displayAndResume(); + + verify(mockHeaderController).setIcon(expectedIcon); + } + + @Test + public void entityHeader_shouldNotHaveIconSetForNotInRangeNetwork() { + setUpForNotInRangeNetwork(); + + displayAndResume(); + + verify(mockHeaderController, never()).setIcon(any(Drawable.class)); + } + @Test public void entityHeader_shouldHaveLabelSetToTitle() { String label = "title"; @@ -410,6 +557,33 @@ public class WifiDetailPreferenceControllerTest { verify(mockSignalStrengthPref).setIcon(any(Drawable.class)); } + @Test + public void signalStrengthPref_shouldHaveIconSetForConnectedNetwork() { + setUpForConnectedNetwork(); + + displayAndResume(); + + verify(mockSignalStrengthPref).setIcon(any(Drawable.class)); + } + + @Test + public void signalStrengthPref_shouldHaveIconSetForDisconnectedNetwork() { + setUpForDisconnectedNetwork(); + + displayAndResume(); + + verify(mockSignalStrengthPref).setIcon(any(Drawable.class)); + } + + @Test + public void signalStrengthPref_shouldNotHaveIconSetForOutOfRangeNetwork() { + setUpForNotInRangeNetwork(); + + displayAndResume(); + + verify(mockSignalStrengthPref, never()).setIcon(any(Drawable.class)); + } + @Test public void signalStrengthPref_shouldHaveDetailTextSet() { String expectedStrength = @@ -420,6 +594,37 @@ public class WifiDetailPreferenceControllerTest { verify(mockSignalStrengthPref).setSummary(expectedStrength); } + @Test + public void signalStrengthPref_shouldHaveDetailTextSetForConnectedNetwork() { + setUpForConnectedNetwork(); + String expectedStrength = + mContext.getResources().getStringArray(R.array.wifi_signal)[LEVEL]; + + displayAndResume(); + + verify(mockSignalStrengthPref).setSummary(expectedStrength); + } + + @Test + public void signalStrengthPref_shouldHaveDetailTextSetForDisconnectedNetwork() { + setUpForDisconnectedNetwork(); + String expectedStrength = + mContext.getResources().getStringArray(R.array.wifi_signal)[LEVEL]; + + displayAndResume(); + + verify(mockSignalStrengthPref).setSummary(expectedStrength); + } + + @Test + public void signalStrengthPref_shouldNotHaveDetailTextSetForNotInRangeNetwork() { + setUpForNotInRangeNetwork(); + + displayAndResume(); + + verify(mockSignalStrengthPref, never()).setSummary(any(String.class)); + } + @Test public void linkSpeedPref_shouldHaveDetailTextSet() { String expectedLinkSpeed = mContext.getString(R.string.tx_link_speed, TX_LINK_SPEED); @@ -438,6 +643,37 @@ public class WifiDetailPreferenceControllerTest { verify(mockTxLinkSpeedPref).setVisible(false); } + @Test + public void linkSpeedPref_shouldVisibleForConnectedNetwork() { + setUpForConnectedNetwork(); + String expectedLinkSpeed = mContext.getString(R.string.tx_link_speed, TX_LINK_SPEED); + + displayAndResume(); + + verify(mockTxLinkSpeedPref).setVisible(true); + verify(mockTxLinkSpeedPref).setSummary(expectedLinkSpeed); + } + + @Test + public void linkSpeedPref_shouldInvisibleForDisconnectedNetwork() { + setUpForDisconnectedNetwork(); + + displayAndResume(); + + verify(mockTxLinkSpeedPref).setVisible(false); + verify(mockTxLinkSpeedPref, never()).setSummary(any(String.class)); + } + + @Test + public void linkSpeedPref_shouldInvisibleForNotInRangeNetwork() { + setUpForNotInRangeNetwork(); + + displayAndResume(); + + verify(mockTxLinkSpeedPref).setVisible(false); + verify(mockTxLinkSpeedPref, never()).setSummary(any(String.class)); + } + @Test public void rxLinkSpeedPref_shouldHaveDetailTextSet() { String expectedLinkSpeed = mContext.getString(R.string.rx_link_speed, RX_LINK_SPEED); @@ -456,6 +692,81 @@ public class WifiDetailPreferenceControllerTest { verify(mockRxLinkSpeedPref).setVisible(false); } + @Test + public void rxLinkSpeedPref_shouldVisibleForConnectedNetwork() { + setUpForConnectedNetwork(); + String expectedLinkSpeed = mContext.getString(R.string.rx_link_speed, RX_LINK_SPEED); + + displayAndResume(); + + verify(mockRxLinkSpeedPref).setVisible(true); + verify(mockRxLinkSpeedPref).setSummary(expectedLinkSpeed); + } + + @Test + public void rxLinkSpeedPref_shouldInvisibleForDisconnectedNetwork() { + setUpForDisconnectedNetwork(); + + displayAndResume(); + + verify(mockRxLinkSpeedPref).setVisible(false); + verify(mockRxLinkSpeedPref, never()).setSummary(any(String.class)); + } + + @Test + public void rxLinkSpeedPref_shouldInvisibleForNotInRangeNetwork() { + setUpForNotInRangeNetwork(); + + displayAndResume(); + + verify(mockRxLinkSpeedPref).setVisible(false); + verify(mockRxLinkSpeedPref, never()).setSummary(any(String.class)); + } + + @Test + public void ssidPref_shouldHaveDetailTextSet() { + when(mockAccessPoint.isPasspoint()).thenReturn(true); + when(mockAccessPoint.isOsuProvider()).thenReturn(false); + + displayAndResume(); + + verify(mockSsidPref, times(1)).setSummary(SSID); + + when(mockAccessPoint.isPasspoint()).thenReturn(false); + when(mockAccessPoint.isOsuProvider()).thenReturn(true); + + displayAndResume(); + + verify(mockSsidPref, times(2)).setSummary(SSID); + } + + @Test + public void ssidPref_shouldShowIfPasspointOrOsu() { + when(mockAccessPoint.isPasspoint()).thenReturn(true); + when(mockAccessPoint.isOsuProvider()).thenReturn(false); + + displayAndResume(); + + verify(mockSsidPref, times(1)).setVisible(true); + + when(mockAccessPoint.isPasspoint()).thenReturn(false); + when(mockAccessPoint.isOsuProvider()).thenReturn(true); + + displayAndResume(); + + verify(mockSsidPref, times(2)).setVisible(true); + } + + @Test + public void ssidPref_shouldNotShowIfNotPasspoint() { + when(mockAccessPoint.isPasspoint()).thenReturn(false); + when(mockAccessPoint.isOsuProvider()).thenReturn(false); + + displayAndResume(); + + verify(mockSsidPref).setVisible(false); + } + @Test public void macAddressPref_shouldHaveDetailTextSet() { displayAndResume(); @@ -463,6 +774,42 @@ public class WifiDetailPreferenceControllerTest { verify(mockMacAddressPref).setSummary(MAC_ADDRESS); } + @Test + public void macAddressPref_shouldVisibleForConnectedNetwork() { + setUpForConnectedNetwork(); + + displayAndResume(); + + verify(mockMacAddressPref).setVisible(true); + verify(mockMacAddressPref).setSummary(MAC_ADDRESS); + } + + @Test + public void macAddressPref_shouldVisibleAsRandomizedForDisconnectedNetwork() { + setUpForDisconnectedNetwork(); + mockWifiConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT; + when(mockWifiConfig.getRandomizedMacAddress()).thenReturn(mockMacAddress); + when(mockMacAddress.toString()).thenReturn(RANDOMIZED_MAC_ADDRESS); + + displayAndResume(); + + verify(mockMacAddressPref).setVisible(true); + verify(mockMacAddressPref).setSummary(RANDOMIZED_MAC_ADDRESS); + } + + @Test + public void macAddressPref_shouldVisibleAsFactoryForDisconnectedNetwork() { + setUpForDisconnectedNetwork(); + mockWifiConfig.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE; + when(mockWifiManager.getFactoryMacAddresses()) + .thenReturn(new String[]{FACTORY_MAC_ADDRESS}); + + displayAndResume(); + + verify(mockMacAddressPref).setVisible(true); + verify(mockMacAddressPref).setSummary(FACTORY_MAC_ADDRESS); + } + @Test public void ipAddressPref_shouldHaveDetailTextSet() { mLinkProperties.addLinkAddress(Constants.IPV4_ADDR); @@ -472,6 +819,26 @@ public class WifiDetailPreferenceControllerTest { verify(mockIpAddressPref).setSummary(Constants.IPV4_ADDR.getAddress().getHostAddress()); } + @Test + public void ipAddressPref_shouldHaveDetailTextSetForConnectedNetwork() { + setUpForConnectedNetwork(); + mLinkProperties.addLinkAddress(Constants.IPV4_ADDR); + + displayAndResume(); + + verify(mockIpAddressPref).setSummary(Constants.IPV4_ADDR.getAddress().getHostAddress()); + verify(mockIpAddressPref).setVisible(true); + } + + @Test + public void ipAddressPref_shouldInvisibleForDisconnectedNetwork() { + setUpForDisconnectedNetwork(); + + displayAndResume(); + + verify(mockIpAddressPref).setVisible(false); + } + @Test public void gatewayAndSubnet_shouldHaveDetailTextSet() { mLinkProperties.addLinkAddress(Constants.IPV4_ADDR); @@ -484,6 +851,29 @@ public class WifiDetailPreferenceControllerTest { verify(mockGatewayPref).setSummary("192.0.2.127"); } + @Test + public void gatewayAndSubnet_shouldHaveDetailTextSetForConnectedNetwork() { + setUpForConnectedNetwork(); + mLinkProperties.addLinkAddress(Constants.IPV4_ADDR); + mLinkProperties.addRoute(Constants.IPV4_DEFAULT); + mLinkProperties.addRoute(Constants.IPV4_SUBNET); + + displayAndResume(); + + verify(mockSubnetPref).setSummary("255.255.255.128"); + verify(mockGatewayPref).setSummary("192.0.2.127"); + verify(mockSubnetPref).setVisible(true); + } + + @Test + public void gatewayAndSubnet_shouldInvisibleSetForDisconnectedNetwork() { + setUpForDisconnectedNetwork(); + + displayAndResume(); + + verify(mockSubnetPref).setVisible(false); + } + @Test public void dnsServersPref_shouldHaveDetailTextSet() throws UnknownHostException { mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[] {8, 8, 4, 4})); @@ -498,6 +888,33 @@ public class WifiDetailPreferenceControllerTest { Constants.IPV6_DNS.getHostAddress()); } + @Test + public void dnsServersPref_shouldHaveDetailTextSetForConnectedNetwork() + throws UnknownHostException { + setUpForConnectedNetwork(); + mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[] {8, 8, 4, 4})); + mLinkProperties.addDnsServer(InetAddress.getByAddress(new byte[] {8, 8, 8, 8})); + mLinkProperties.addDnsServer(Constants.IPV6_DNS); + + displayAndResume(); + + verify(mockDnsPref).setSummary( + "8.8.4.4\n" + + "8.8.8.8\n" + + Constants.IPV6_DNS.getHostAddress()); + verify(mockDnsPref).setVisible(true); + } + + @Test + public void dnsServersPref_shouldInvisibleSetForDisconnectedNetwork() + throws UnknownHostException { + setUpForDisconnectedNetwork(); + + displayAndResume(); + + verify(mockDnsPref).setVisible(false); + } + @Test public void noCurrentNetwork_shouldFinishActivity() { // If WifiManager#getCurrentNetwork() returns null, then the network is neither connected @@ -509,6 +926,18 @@ public class WifiDetailPreferenceControllerTest { verify(mockActivity).finish(); } + @Test + public void noCurrentNetwork_shouldNotFinishActivityForConnectedNetwork() { + // For new feature for display detail page for saved network for disconnected network, + // mNetwork may be null, do finish activity + setUpForConnectedNetwork(); + when(mockWifiManager.getCurrentNetwork()).thenReturn(null); + + displayAndResume(); + + verify(mockActivity, never()).finish(); + } + @Test public void noLinkProperties_allIpDetailsHidden() { when(mockConnectivityManager.getLinkProperties(mockNetwork)).thenReturn(null); @@ -528,6 +957,25 @@ public class WifiDetailPreferenceControllerTest { verify(mockDnsPref, never()).setVisible(true); } + @Test + public void disconnectedNetwork_allIpDetailsHidden() { + setUpForDisconnectedNetwork(); + reset(mockIpv6Category, mockIpAddressPref, mockSubnetPref, mockGatewayPref, mockDnsPref); + + displayAndResume(); + + verify(mockIpv6Category).setVisible(false); + verify(mockIpAddressPref).setVisible(false); + verify(mockSubnetPref).setVisible(false); + verify(mockGatewayPref).setVisible(false); + verify(mockDnsPref).setVisible(false); + verify(mockIpv6Category, never()).setVisible(true); + verify(mockIpAddressPref, never()).setVisible(true); + verify(mockSubnetPref, never()).setVisible(true); + verify(mockGatewayPref, never()).setVisible(true); + verify(mockDnsPref, never()).setVisible(true); + } + // Convenience method to convert a LinkAddress to a string without a prefix length. private String asString(LinkAddress l) { return l.getAddress().getHostAddress(); @@ -706,7 +1154,7 @@ public class WifiDetailPreferenceControllerTest { displayAndResume(); - verify(mockButtonsPref).setButton3Visible(false); + verify(mockButtonsPref).setButton4Visible(false); } @Test @@ -815,6 +1263,20 @@ public class WifiDetailPreferenceControllerTest { verify(mockWifiManager, times(2)).getConnectionInfo(); } + @Test + public void networkStateChangedIntent_shouldRefetchInfoForConnectedNetwork() { + setUpForConnectedNetwork(); + displayAndResume(); + + verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class)); + verify(mockWifiManager, times(1)).getConnectionInfo(); + + mContext.sendBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION)); + + verify(mockConnectivityManager, times(2)).getNetworkInfo(any(Network.class)); + verify(mockWifiManager, times(2)).getConnectionInfo(); + } + @Test public void rssiChangedIntent_shouldRefetchInfo() { displayAndResume(); @@ -828,6 +1290,20 @@ public class WifiDetailPreferenceControllerTest { verify(mockWifiManager, times(2)).getConnectionInfo(); } + @Test + public void rssiChangedIntent_shouldRefetchInfoForConnectedNetwork() { + setUpForConnectedNetwork(); + displayAndResume(); + + verify(mockConnectivityManager, times(1)).getNetworkInfo(any(Network.class)); + verify(mockWifiManager, times(1)).getConnectionInfo(); + + mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION)); + + verify(mockConnectivityManager, times(2)).getNetworkInfo(any(Network.class)); + verify(mockWifiManager, times(2)).getConnectionInfo(); + } + @Test public void networkDisconnectedState_shouldFinishActivity() { displayAndResume(); @@ -838,6 +1314,18 @@ public class WifiDetailPreferenceControllerTest { verify(mockActivity).finish(); } + @Test + public void networkDisconnectedState_shouldNotFinishActivityForConnectedNetwork() { + setUpForConnectedNetwork(); + + displayAndResume(); + + when(mockConnectivityManager.getNetworkInfo(any(Network.class))).thenReturn(null); + mContext.sendBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION)); + + verify(mockActivity, never()).finish(); + } + @Test public void networkOnLost_shouldFinishActivity() { displayAndResume(); @@ -847,6 +1335,17 @@ public class WifiDetailPreferenceControllerTest { verify(mockActivity).finish(); } + @Test + public void networkOnLost_shouldNotFinishActivityForConnectedNetwork() { + setUpForConnectedNetwork(); + + displayAndResume(); + + mCallbackCaptor.getValue().onLost(mockNetwork); + + verify(mockActivity, never()).finish(); + } + @Test public void ipv6AddressPref_shouldHaveHostAddressTextSet() { mLinkProperties.addLinkAddress(Constants.IPV6_LINKLOCAL); @@ -926,6 +1425,19 @@ public class WifiDetailPreferenceControllerTest { verify(mockIconInjector, times(2)).getIcon(anyInt()); } + @Test + public void testRefreshRssiViews_shouldNotUpdateForNotInRangeNetwork() { + setUpForNotInRangeNetwork(); + + displayAndResume(); + + when(mockAccessPoint.getLevel()).thenReturn(0); + mContext.sendBroadcast(new Intent(WifiManager.RSSI_CHANGED_ACTION)); + + verify(mockSignalStrengthPref, times(2)).setVisible(false); + } + + private ActionButtonsPreference createMock() { final ActionButtonsPreference pref = mock(ActionButtonsPreference.class); when(pref.setButton1Text(anyInt())).thenReturn(pref); @@ -946,6 +1458,12 @@ public class WifiDetailPreferenceControllerTest { when(pref.setButton3Visible(anyBoolean())).thenReturn(pref); when(pref.setButton3OnClickListener(any(View.OnClickListener.class))).thenReturn(pref); + when(pref.setButton4Text(anyInt())).thenReturn(pref); + when(pref.setButton4Icon(anyInt())).thenReturn(pref); + when(pref.setButton4Enabled(anyBoolean())).thenReturn(pref); + when(pref.setButton4Visible(anyBoolean())).thenReturn(pref); + when(pref.setButton4OnClickListener(any(View.OnClickListener.class))).thenReturn(pref); + return pref; } } diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiPrivacyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiPrivacyPreferenceControllerTest.java index a1af8bf272c..2e588b54a69 100644 --- a/tests/robotests/src/com/android/settings/wifi/details/WifiPrivacyPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/details/WifiPrivacyPreferenceControllerTest.java @@ -109,4 +109,20 @@ public class WifiPrivacyPreferenceControllerTest { assertThat(mDropDownPreference.isSelectable()).isFalse(); } + + @Test + public void testUpdateState_isNotPasspointNetwork_shouldBeSelectable() { + mPreferenceController.setIsPasspoint(false); + mPreferenceController.updateState(mDropDownPreference); + + assertThat(mDropDownPreference.isSelectable()).isTrue(); + } + + @Test + public void testUpdateState_isPasspointNetwork_shouldNotSelectable() { + mPreferenceController.setIsPasspoint(true); + mPreferenceController.updateState(mDropDownPreference); + + assertThat(mDropDownPreference.isSelectable()).isFalse(); + } } diff --git a/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java b/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java index a7cf327a245..b18102d226d 100644 --- a/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/slice/ConnectToWifiHandlerTest.java @@ -18,12 +18,14 @@ package com.android.settings.wifi.slice; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration.NetworkSelectionStatus; +import android.net.wifi.WifiManager; import com.android.settings.testutils.shadow.ShadowConnectivityManager; import com.android.settings.testutils.shadow.ShadowWifiManager; @@ -78,7 +80,7 @@ public class ConnectToWifiHandlerTest { mHandler.connect(mAccessPoint); - verify(mAccessPoint).startOsuProvisioning(); + verify(mAccessPoint).startOsuProvisioning(any(WifiManager.ActionListener.class)); } diff --git a/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java b/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java new file mode 100644 index 00000000000..7ddbce48a9f --- /dev/null +++ b/tests/robotests/src/com/android/settings/wifi/slice/WifiScanWorkerTest.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.wifi.slice; + +import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import android.content.ContentResolver; +import android.content.Context; +import android.net.NetworkInfo; +import android.net.NetworkInfo.State; +import android.net.wifi.WifiManager; +import android.os.Bundle; + +import androidx.slice.SliceProvider; +import androidx.slice.widget.SliceLiveData; + +import com.android.settingslib.wifi.AccessPoint; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class WifiScanWorkerTest { + + private static final String AP_NAME = "ap"; + + private Context mContext; + private ContentResolver mResolver; + private WifiManager mWifiManager; + private WifiScanWorker mWifiScanWorker; + + @Before + public void setUp() { + mContext = spy(RuntimeEnvironment.application); + mResolver = mock(ContentResolver.class); + doReturn(mResolver).when(mContext).getContentResolver(); + mWifiManager = mContext.getSystemService(WifiManager.class); + + // Set-up specs for SliceMetadata. + SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); + mWifiManager.setWifiEnabled(true); + + mWifiScanWorker = new WifiScanWorker(mContext, WIFI_SLICE_URI); + } + + @Test + public void onWifiStateChanged_shouldNotifyChange() { + mWifiScanWorker.onWifiStateChanged(WifiManager.WIFI_STATE_DISABLED); + + verify(mResolver).notifyChange(WIFI_SLICE_URI, null); + } + + private AccessPoint createAccessPoint(String name, State state) { + final NetworkInfo info = mock(NetworkInfo.class); + doReturn(state).when(info).getState(); + + final Bundle savedState = new Bundle(); + savedState.putString("key_ssid", name); + savedState.putParcelable("key_networkinfo", info); + return new AccessPoint(mContext, savedState); + } + + @Test + public void SliceAccessPoint_sameState_shouldBeTheSame() { + final AccessPoint ap1 = createAccessPoint(AP_NAME, State.CONNECTED); + final AccessPoint ap2 = createAccessPoint(AP_NAME, State.CONNECTED); + + assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2))) + .isTrue(); + } + + @Test + public void SliceAccessPoint_differentState_shouldBeDifferent() { + final AccessPoint ap1 = createAccessPoint(AP_NAME, State.CONNECTING); + final AccessPoint ap2 = createAccessPoint(AP_NAME, State.CONNECTED); + + assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2))) + .isFalse(); + } + + @Test + public void SliceAccessPoint_differentLength_shouldBeDifferent() { + final AccessPoint ap1 = createAccessPoint(AP_NAME, State.CONNECTED); + final AccessPoint ap2 = createAccessPoint(AP_NAME, State.CONNECTED); + final List list = new ArrayList<>(); + list.add(ap1); + list.add(ap2); + + assertThat(mWifiScanWorker.areListsTheSame(list, Arrays.asList(ap1))).isFalse(); + } +} diff --git a/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java b/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java index 75a9e117739..b2718fc0631 100644 --- a/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java +++ b/tests/robotests/src/com/android/settings/wifi/slice/WifiSliceTest.java @@ -19,25 +19,20 @@ package com.android.settings.wifi.slice; import static android.app.slice.Slice.HINT_LIST_ITEM; import static android.app.slice.SliceItem.FORMAT_SLICE; -import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI; import static com.android.settings.wifi.slice.WifiSlice.DEFAULT_EXPANDED_ROW_COUNT; -import static com.android.settings.wifi.slice.WifiSlice.WifiScanWorker; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.net.NetworkInfo; -import android.net.NetworkInfo.State; import android.net.Uri; import android.net.wifi.WifiManager; -import android.os.Bundle; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; @@ -53,6 +48,9 @@ import com.android.settings.slices.SliceBackgroundWorker; import com.android.settings.testutils.SliceTester; import com.android.settingslib.wifi.AccessPoint; +import java.util.ArrayList; +import java.util.List; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -62,11 +60,8 @@ import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - @RunWith(RobolectricTestRunner.class) +@Config(shadows = WifiSliceTest.ShadowSliceBackgroundWorker.class) public class WifiSliceTest { private static final String AP1_NAME = "ap1"; @@ -76,7 +71,6 @@ public class WifiSliceTest { private ContentResolver mResolver; private WifiManager mWifiManager; private WifiSlice mWifiSlice; - private WifiScanWorker mWifiScanWorker; @Before public void setUp() { @@ -90,7 +84,6 @@ public class WifiSliceTest { mWifiManager.setWifiEnabled(true); mWifiSlice = new WifiSlice(mContext); - mWifiScanWorker = new WifiScanWorker(mContext, WIFI_SLICE_URI); } @Test @@ -139,7 +132,7 @@ public class WifiSliceTest { private AccessPoint createAccessPoint(String name, boolean active, boolean reachable) { final AccessPoint accessPoint = mock(AccessPoint.class); - doReturn(name).when(accessPoint).getConfigName(); + doReturn(name).when(accessPoint).getTitle(); doReturn(active).when(accessPoint).isActive(); doReturn(reachable).when(accessPoint).isReachable(); if (active) { @@ -160,13 +153,12 @@ public class WifiSliceTest { } @Test - @Config(shadows = ShadowSliceBackgroundWorker.class) public void getWifiSlice_noReachableAp_shouldReturnLoadingRow() { setWorkerResults( createAccessPoint(AP1_NAME, false, false), createAccessPoint(AP2_NAME, false, false)); - final Slice wifiSlice = mWifiSlice.getSlice(); + final Slice wifiSlice = mWifiSlice.getSlice(); final List sliceItems = wifiSlice.getItems(); SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME); @@ -177,11 +169,10 @@ public class WifiSliceTest { } @Test - @Config(shadows = ShadowSliceBackgroundWorker.class) public void getWifiSlice_oneActiveAp_shouldReturnLoadingRow() { setWorkerResults(createAccessPoint(AP1_NAME, true, true)); - final Slice wifiSlice = mWifiSlice.getSlice(); + final Slice wifiSlice = mWifiSlice.getSlice(); final List sliceItems = wifiSlice.getItems(); SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME); @@ -191,13 +182,12 @@ public class WifiSliceTest { } @Test - @Config(shadows = ShadowSliceBackgroundWorker.class) public void getWifiSlice_oneActiveApAndOneUnreachableAp_shouldReturnLoadingRow() { setWorkerResults( createAccessPoint(AP1_NAME, true, true), createAccessPoint(AP2_NAME, false, false)); - final Slice wifiSlice = mWifiSlice.getSlice(); + final Slice wifiSlice = mWifiSlice.getSlice(); final List sliceItems = wifiSlice.getItems(); SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME); @@ -208,11 +198,10 @@ public class WifiSliceTest { } @Test - @Config(shadows = ShadowSliceBackgroundWorker.class) public void getWifiSlice_oneReachableAp_shouldNotReturnLoadingRow() { setWorkerResults(createAccessPoint(AP1_NAME, false, true)); - final Slice wifiSlice = mWifiSlice.getSlice(); + final Slice wifiSlice = mWifiSlice.getSlice(); final List sliceItems = wifiSlice.getItems(); SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME); @@ -222,13 +211,12 @@ public class WifiSliceTest { } @Test - @Config(shadows = ShadowSliceBackgroundWorker.class) public void getWifiSlice_allReachableAps_shouldNotReturnLoadingRow() { setWorkerResults( createAccessPoint(AP1_NAME, false, true), createAccessPoint(AP2_NAME, false, true)); - final Slice wifiSlice = mWifiSlice.getSlice(); + final Slice wifiSlice = mWifiSlice.getSlice(); final List sliceItems = wifiSlice.getItems(); SliceTester.assertAnySliceItemContainsTitle(sliceItems, AP1_NAME); @@ -249,51 +237,6 @@ public class WifiSliceTest { assertThat(wifiManager.getWifiState()).isEqualTo(WifiManager.WIFI_STATE_ENABLED); } - @Test - public void onWifiStateChanged_shouldNotifyChange() { - mWifiScanWorker.onWifiStateChanged(WifiManager.WIFI_STATE_DISABLED); - - verify(mResolver).notifyChange(WIFI_SLICE_URI, null); - } - - private AccessPoint createAccessPoint(String name, State state) { - final NetworkInfo info = mock(NetworkInfo.class); - doReturn(state).when(info).getState(); - - final Bundle savedState = new Bundle(); - savedState.putString("key_ssid", name); - savedState.putParcelable("key_networkinfo", info); - return new AccessPoint(mContext, savedState); - } - - @Test - public void SliceAccessPoint_sameState_shouldBeTheSame() { - final AccessPoint ap1 = createAccessPoint(AP1_NAME, State.CONNECTED); - final AccessPoint ap2 = createAccessPoint(AP1_NAME, State.CONNECTED); - - assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2))) - .isTrue(); - } - - @Test - public void SliceAccessPoint_differentState_shouldBeDifferent() { - final AccessPoint ap1 = createAccessPoint(AP1_NAME, State.CONNECTING); - final AccessPoint ap2 = createAccessPoint(AP1_NAME, State.CONNECTED); - - assertThat(mWifiScanWorker.areListsTheSame(Arrays.asList(ap1), Arrays.asList(ap2))) - .isFalse(); - } - @Test - public void SliceAccessPoint_differentLength_shouldBeDifferent() { - final AccessPoint ap1 = createAccessPoint(AP1_NAME, State.CONNECTED); - final AccessPoint ap2 = createAccessPoint(AP1_NAME, State.CONNECTED); - final List list = new ArrayList<>(); - list.add(ap1); - list.add(ap2); - - assertThat(mWifiScanWorker.areListsTheSame(list, Arrays.asList(ap1))).isFalse(); - } - @Implements(SliceBackgroundWorker.class) public static class ShadowSliceBackgroundWorker { private static WifiScanWorker mWifiScanWorker = mock(WifiScanWorker.class);