diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentSearchIndexProviderInspector.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentSearchIndexProviderInspector.java index 6103b2b89f4..24d4d330e8b 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentSearchIndexProviderInspector.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentSearchIndexProviderInspector.java @@ -24,7 +24,6 @@ import com.android.settings.core.BasePreferenceController; import com.android.settings.core.PreferenceControllerListHelper; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.DatabaseIndexingUtils; -import com.android.settingslib.search.Indexable; import com.android.settingslib.core.AbstractPreferenceController; import org.robolectric.RuntimeEnvironment; diff --git a/tests/robotests/src/com/android/settings/panel/FakeSettingsPanelActivity.java b/tests/robotests/src/com/android/settings/panel/FakeSettingsPanelActivity.java index 2a62b5423e4..ba763ce3a06 100644 --- a/tests/robotests/src/com/android/settings/panel/FakeSettingsPanelActivity.java +++ b/tests/robotests/src/com/android/settings/panel/FakeSettingsPanelActivity.java @@ -30,4 +30,4 @@ public class FakeSettingsPanelActivity extends SettingsPanelActivity { final Intent intent = new Intent(FakePanelContent.FAKE_ACTION); return intent; } -} \ No newline at end of file +} diff --git a/tests/robotests/src/com/android/settings/search/FakeSettingsFragment.java b/tests/robotests/src/com/android/settings/search/FakeSettingsFragment.java index 19282ddff4d..7a229f68e6f 100644 --- a/tests/robotests/src/com/android/settings/search/FakeSettingsFragment.java +++ b/tests/robotests/src/com/android/settings/search/FakeSettingsFragment.java @@ -115,4 +115,4 @@ public class FakeSettingsFragment extends DashboardFragment { return keys; } }; -} \ No newline at end of file +} diff --git a/tests/robotests/src/com/android/settings/testutils/FakeToggleController.java b/tests/robotests/src/com/android/settings/testutils/FakeToggleController.java index 8bceb13669b..68124512cfc 100644 --- a/tests/robotests/src/com/android/settings/testutils/FakeToggleController.java +++ b/tests/robotests/src/com/android/settings/testutils/FakeToggleController.java @@ -12,9 +12,7 @@ * 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.testutils; import android.content.Context; @@ -26,8 +24,6 @@ import android.provider.Settings; import com.android.settings.core.TogglePreferenceController; import com.android.settings.slices.SliceBackgroundWorker; -import java.io.IOException; - public class FakeToggleController extends TogglePreferenceController { public static final String AVAILABILITY_KEY = "fake_toggle_availability_key"; diff --git a/tests/robotests/src/com/android/settings/testutils/SliceTester.java b/tests/robotests/src/com/android/settings/testutils/SliceTester.java index f2cce3cdf65..ede5fbdd58a 100644 --- a/tests/robotests/src/com/android/settings/testutils/SliceTester.java +++ b/tests/robotests/src/com/android/settings/testutils/SliceTester.java @@ -322,4 +322,4 @@ public class SliceTester { expectedKeywords.add(data.getScreenTitle().toString()); assertThat(keywords).containsExactlyElementsIn(expectedKeywords); } -} \ No newline at end of file +} diff --git a/tests/robotests/src/com/android/settings/widget/DonutViewTest.java b/tests/robotests/src/com/android/settings/widget/DonutViewTest.java deleted file mode 100644 index cc41f92acf9..00000000000 --- a/tests/robotests/src/com/android/settings/widget/DonutViewTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.android.settings.widget; - -import android.content.Context; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class DonutViewTest { - @Test - public void getPercentageStringSpannable_doesntCrashForMissingPercentage() { - Context context = RuntimeEnvironment.application; - - DonutView.getPercentageStringSpannable(context.getResources(), "50%", "h"); - } -} diff --git a/tests/robotests/src/com/android/settings/LinkifyUtilsTest.java b/tests/unit/src/com/android/settings/LinkifyUtilsTest.java similarity index 91% rename from tests/robotests/src/com/android/settings/LinkifyUtilsTest.java rename to tests/unit/src/com/android/settings/LinkifyUtilsTest.java index de0630210f0..34586d56186 100644 --- a/tests/robotests/src/com/android/settings/LinkifyUtilsTest.java +++ b/tests/unit/src/com/android/settings/LinkifyUtilsTest.java @@ -21,13 +21,14 @@ import android.text.Spannable; import android.text.style.ClickableSpan; import android.widget.TextView; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class LinkifyUtilsTest { private static final String TEST_STRING = "to LINK_BEGINscanning settingsLINK_END."; private static final String WRONG_STRING = "to scanning settingsLINK_END."; @@ -41,7 +42,7 @@ public class LinkifyUtilsTest { public void setUp() throws Exception { mSpanStringBuilder = new StringBuilder(TEST_STRING); mWrongSpanStringBuilder = new StringBuilder(WRONG_STRING); - mTextView = new TextView(RuntimeEnvironment.application); + mTextView = new TextView(ApplicationProvider.getApplicationContext()); } @Test diff --git a/tests/unit/src/com/android/settings/TestUtils.java b/tests/unit/src/com/android/settings/TestUtils.java new file mode 100644 index 00000000000..d7b1ea4a8b1 --- /dev/null +++ b/tests/unit/src/com/android/settings/TestUtils.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2020 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; + +/** + * Convenience methods and constants for testing. + */ +public class TestUtils { + public static final long KILOBYTE = 1024L; // TODO: Change to 1000 in O Robolectric. + public static final long MEGABYTE = KILOBYTE * KILOBYTE; + public static final long GIGABYTE = KILOBYTE * MEGABYTE; +} diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceControllerTest.java similarity index 93% rename from tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceControllerTest.java index 53f6cc099e9..7d903ee01a4 100644 --- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceControllerTest.java @@ -19,6 +19,9 @@ package com.android.settings.accessibility; import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.ON; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import static com.google.common.truth.Truth.assertThat; import android.content.Context; @@ -30,10 +33,8 @@ import androidx.preference.SwitchPreference; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class AccessibilityShortcutPreferenceControllerTest { private Context mContext; @@ -42,7 +43,7 @@ public class AccessibilityShortcutPreferenceControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mPreference = new SwitchPreference(mContext); mController = new AccessibilityShortcutPreferenceController(mContext, "accessibility_shortcut_preference"); diff --git a/tests/robotests/src/com/android/settings/accessibility/DisableAnimationsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/DisableAnimationsPreferenceControllerTest.java similarity index 93% rename from tests/robotests/src/com/android/settings/accessibility/DisableAnimationsPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/accessibility/DisableAnimationsPreferenceControllerTest.java index 245fb74da84..57060088a63 100644 --- a/tests/robotests/src/com/android/settings/accessibility/DisableAnimationsPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/accessibility/DisableAnimationsPreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 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. @@ -26,16 +26,16 @@ import android.content.Context; import android.provider.Settings; import androidx.preference.SwitchPreference; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.settings.core.BasePreferenceController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class DisableAnimationsPreferenceControllerTest { private Context mContext; @@ -44,7 +44,7 @@ public class DisableAnimationsPreferenceControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mPreference = new SwitchPreference(mContext); mController = new DisableAnimationsPreferenceController(mContext, "disable_animation"); } diff --git a/tests/robotests/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceControllerTest.java similarity index 93% rename from tests/robotests/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceControllerTest.java index eb49edd47bd..7f4048d9e09 100644 --- a/tests/robotests/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/accessibility/FontWeightAdjustmentPreferenceControllerTest.java @@ -22,16 +22,16 @@ import android.content.Context; import android.provider.Settings; import androidx.preference.SwitchPreference; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.settings.core.BasePreferenceController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class FontWeightAdjustmentPreferenceControllerTest { private static final int ON = FontWeightAdjustmentPreferenceController.BOLD_TEXT_ADJUSTMENT; private static final int OFF = 0; @@ -42,7 +42,7 @@ public class FontWeightAdjustmentPreferenceControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mPreference = new SwitchPreference(mContext); mController = new FontWeightAdjustmentPreferenceController( mContext, "font_weight_adjustment"); diff --git a/tests/robotests/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java similarity index 92% rename from tests/robotests/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java index 6eaf7a7e2d0..6250fefafe1 100644 --- a/tests/robotests/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/accessibility/HighTextContrastPreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 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. @@ -22,16 +22,16 @@ import android.content.Context; import android.provider.Settings; import androidx.preference.SwitchPreference; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.settings.core.BasePreferenceController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class HighTextContrastPreferenceControllerTest { private static final int ON = 1; @@ -44,7 +44,7 @@ public class HighTextContrastPreferenceControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mPreference = new SwitchPreference(mContext); mController = new HighTextContrastPreferenceController(mContext, "text_contrast"); } diff --git a/tests/robotests/src/com/android/settings/accessibility/LargePointerIconPreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/LargePointerIconPreferenceControllerTest.java similarity index 92% rename from tests/robotests/src/com/android/settings/accessibility/LargePointerIconPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/accessibility/LargePointerIconPreferenceControllerTest.java index 1f7f5ad7788..db588e84b5c 100644 --- a/tests/robotests/src/com/android/settings/accessibility/LargePointerIconPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/accessibility/LargePointerIconPreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 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. @@ -25,16 +25,16 @@ import android.content.Context; import android.provider.Settings; import androidx.preference.SwitchPreference; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.settings.core.BasePreferenceController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class LargePointerIconPreferenceControllerTest { private static final int UNKNOWN = -1; @@ -45,7 +45,7 @@ public class LargePointerIconPreferenceControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mPreference = new SwitchPreference(mContext); mController = new LargePointerIconPreferenceController(mContext, "large_pointer"); } diff --git a/tests/robotests/src/com/android/settings/accessibility/MagnificationPreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/MagnificationPreferenceControllerTest.java similarity index 83% rename from tests/robotests/src/com/android/settings/accessibility/MagnificationPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/accessibility/MagnificationPreferenceControllerTest.java index d462c2aeb3e..a81c3e466db 100644 --- a/tests/robotests/src/com/android/settings/accessibility/MagnificationPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/accessibility/MagnificationPreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 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. @@ -20,15 +20,16 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.core.BasePreferenceController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class MagnificationPreferenceControllerTest { private Context mContext; @@ -36,7 +37,7 @@ public class MagnificationPreferenceControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mController = new MagnificationPreferenceController(mContext, "magnification"); } diff --git a/tests/robotests/src/com/android/settings/accessibility/PreferredShortcutTest.java b/tests/unit/src/com/android/settings/accessibility/PreferredShortcutTest.java similarity index 100% rename from tests/robotests/src/com/android/settings/accessibility/PreferredShortcutTest.java rename to tests/unit/src/com/android/settings/accessibility/PreferredShortcutTest.java diff --git a/tests/robotests/src/com/android/settings/accessibility/PreferredShortcutsTest.java b/tests/unit/src/com/android/settings/accessibility/PreferredShortcutsTest.java similarity index 97% rename from tests/robotests/src/com/android/settings/accessibility/PreferredShortcutsTest.java rename to tests/unit/src/com/android/settings/accessibility/PreferredShortcutsTest.java index a694aa3f289..95a0b836f05 100644 --- a/tests/robotests/src/com/android/settings/accessibility/PreferredShortcutsTest.java +++ b/tests/unit/src/com/android/settings/accessibility/PreferredShortcutsTest.java @@ -22,13 +22,13 @@ import android.content.ComponentName; import android.content.Context; import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; /** Tests for {@link PreferredShortcuts} */ -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class PreferredShortcutsTest { private static final String PACKAGE_NAME_1 = "com.test1.example"; diff --git a/tests/robotests/src/com/android/settings/accessibility/PrimaryMonoPreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/PrimaryMonoPreferenceControllerTest.java similarity index 92% rename from tests/robotests/src/com/android/settings/accessibility/PrimaryMonoPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/accessibility/PrimaryMonoPreferenceControllerTest.java index fab1b95c968..8caeaff104d 100644 --- a/tests/robotests/src/com/android/settings/accessibility/PrimaryMonoPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/accessibility/PrimaryMonoPreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 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. @@ -23,16 +23,16 @@ import android.os.UserHandle; import android.provider.Settings; import androidx.preference.SwitchPreference; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.settings.core.BasePreferenceController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class PrimaryMonoPreferenceControllerTest { private static final int ON = 1; @@ -45,7 +45,7 @@ public class PrimaryMonoPreferenceControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mPreference = new SwitchPreference(mContext); mController = new PrimaryMonoPreferenceController(mContext, "test_key"); } diff --git a/tests/robotests/src/com/android/settings/accessibility/ReduceBrightColorsIntensityPreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/ReduceBrightColorsIntensityPreferenceControllerTest.java similarity index 100% rename from tests/robotests/src/com/android/settings/accessibility/ReduceBrightColorsIntensityPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/accessibility/ReduceBrightColorsIntensityPreferenceControllerTest.java diff --git a/tests/robotests/src/com/android/settings/accessibility/ReduceBrightColorsPersistencePreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/ReduceBrightColorsPersistencePreferenceControllerTest.java similarity index 100% rename from tests/robotests/src/com/android/settings/accessibility/ReduceBrightColorsPersistencePreferenceControllerTest.java rename to tests/unit/src/com/android/settings/accessibility/ReduceBrightColorsPersistencePreferenceControllerTest.java diff --git a/tests/robotests/src/com/android/settings/accessibility/SelectLongPressTimeoutPreferenceControllerTest.java b/tests/unit/src/com/android/settings/accessibility/SelectLongPressTimeoutPreferenceControllerTest.java similarity index 90% rename from tests/robotests/src/com/android/settings/accessibility/SelectLongPressTimeoutPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/accessibility/SelectLongPressTimeoutPreferenceControllerTest.java index 1bdfb41a9ee..899fc092080 100644 --- a/tests/robotests/src/com/android/settings/accessibility/SelectLongPressTimeoutPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/accessibility/SelectLongPressTimeoutPreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 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. @@ -21,15 +21,16 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.provider.Settings; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.core.BasePreferenceController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class SelectLongPressTimeoutPreferenceControllerTest { private static final int VALID_VALUE = 1500; private static final int INVALID_VALUE = 0; @@ -40,7 +41,7 @@ public class SelectLongPressTimeoutPreferenceControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mController = new SelectLongPressTimeoutPreferenceController(mContext, "press_timeout"); } diff --git a/tests/robotests/src/com/android/settings/accounts/RemoveUserFragmentTest.java b/tests/unit/src/com/android/settings/accounts/RemoveUserFragmentTest.java similarity index 87% rename from tests/robotests/src/com/android/settings/accounts/RemoveUserFragmentTest.java rename to tests/unit/src/com/android/settings/accounts/RemoveUserFragmentTest.java index 4537eb92452..e38f42d16dc 100644 --- a/tests/robotests/src/com/android/settings/accounts/RemoveUserFragmentTest.java +++ b/tests/unit/src/com/android/settings/accounts/RemoveUserFragmentTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2020 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. @@ -18,13 +18,14 @@ package com.android.settings.accounts; import static com.google.common.truth.Truth.assertThat; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Test; import org.junit.runner.RunWith; import java.lang.reflect.Modifier; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class RemoveUserFragmentTest { @Test diff --git a/tests/robotests/src/com/android/settings/accounts/SyncStateSwitchPreferenceTest.java b/tests/unit/src/com/android/settings/accounts/SyncStateSwitchPreferenceTest.java similarity index 87% rename from tests/robotests/src/com/android/settings/accounts/SyncStateSwitchPreferenceTest.java rename to tests/unit/src/com/android/settings/accounts/SyncStateSwitchPreferenceTest.java index 9c7b346d36c..cda637399a9 100644 --- a/tests/robotests/src/com/android/settings/accounts/SyncStateSwitchPreferenceTest.java +++ b/tests/unit/src/com/android/settings/accounts/SyncStateSwitchPreferenceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -22,13 +22,14 @@ import android.accounts.Account; import android.content.Context; import android.os.UserHandle; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class SyncStateSwitchPreferenceTest { private Context mContext; @@ -36,7 +37,7 @@ public class SyncStateSwitchPreferenceTest { @Before public void setup() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); } @Test diff --git a/tests/robotests/src/com/android/settings/applications/AppStateInstallAppsBridgeTest.java b/tests/unit/src/com/android/settings/applications/AppStateInstallAppsBridgeTest.java similarity index 85% rename from tests/robotests/src/com/android/settings/applications/AppStateInstallAppsBridgeTest.java rename to tests/unit/src/com/android/settings/applications/AppStateInstallAppsBridgeTest.java index 277f63e5745..a3bfff92d15 100644 --- a/tests/robotests/src/com/android/settings/applications/AppStateInstallAppsBridgeTest.java +++ b/tests/unit/src/com/android/settings/applications/AppStateInstallAppsBridgeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2020 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,26 +11,26 @@ * 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.applications; import static com.google.common.truth.Truth.assertThat; import android.app.AppOpsManager; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class AppStateInstallAppsBridgeTest { @Test public void testInstallAppsStateCanInstallApps() { AppStateInstallAppsBridge.InstallAppsState appState = - new AppStateInstallAppsBridge.InstallAppsState(); + new AppStateInstallAppsBridge.InstallAppsState(); assertThat(appState.canInstallApps()).isFalse(); appState.permissionRequested = true; @@ -46,7 +46,7 @@ public class AppStateInstallAppsBridgeTest { @Test public void testInstallAppsStateIsPotentialAppSource() { AppStateInstallAppsBridge.InstallAppsState appState = - new AppStateInstallAppsBridge.InstallAppsState(); + new AppStateInstallAppsBridge.InstallAppsState(); assertThat(appState.isPotentialAppSource()).isFalse(); appState.appOpMode = AppOpsManager.MODE_ERRORED; diff --git a/tests/robotests/src/com/android/settings/applications/EnterpriseDefaultAppsTest.java b/tests/unit/src/com/android/settings/applications/EnterpriseDefaultAppsTest.java similarity index 85% rename from tests/robotests/src/com/android/settings/applications/EnterpriseDefaultAppsTest.java rename to tests/unit/src/com/android/settings/applications/EnterpriseDefaultAppsTest.java index 558334da958..b956089d46a 100644 --- a/tests/robotests/src/com/android/settings/applications/EnterpriseDefaultAppsTest.java +++ b/tests/unit/src/com/android/settings/applications/EnterpriseDefaultAppsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2020 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,24 +11,24 @@ * 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.applications; import static org.junit.Assert.assertTrue; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.R; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class EnterpriseDefaultAppsTest { @Test public void testNumberOfIntentsCorrelateWithUI() { - final int concatenation_templates[] = + final int[] concatenation_templates = new int[]{0 /* no need for single app name */, R.string.app_names_concatenation_template_2, R.string.app_names_concatenation_template_3}; diff --git a/tests/robotests/src/com/android/settings/applications/assist/AssistSettingObserverTest.java b/tests/unit/src/com/android/settings/applications/assist/AssistSettingObserverTest.java similarity index 88% rename from tests/robotests/src/com/android/settings/applications/assist/AssistSettingObserverTest.java rename to tests/unit/src/com/android/settings/applications/assist/AssistSettingObserverTest.java index f930106910e..2bfdd0c4ea5 100644 --- a/tests/robotests/src/com/android/settings/applications/assist/AssistSettingObserverTest.java +++ b/tests/unit/src/com/android/settings/applications/assist/AssistSettingObserverTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2020 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. @@ -18,13 +18,14 @@ package com.android.settings.applications.assist; import android.net.Uri; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Test; import org.junit.runner.RunWith; import java.util.List; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class AssistSettingObserverTest { @Test diff --git a/tests/robotests/src/com/android/settings/applications/manageapplications/AppFilterRegistryTest.java b/tests/unit/src/com/android/settings/applications/manageapplications/AppFilterRegistryTest.java similarity index 96% rename from tests/robotests/src/com/android/settings/applications/manageapplications/AppFilterRegistryTest.java rename to tests/unit/src/com/android/settings/applications/manageapplications/AppFilterRegistryTest.java index 4c51ae7fb6a..ba7a0d237a6 100644 --- a/tests/robotests/src/com/android/settings/applications/manageapplications/AppFilterRegistryTest.java +++ b/tests/unit/src/com/android/settings/applications/manageapplications/AppFilterRegistryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2020 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. @@ -37,11 +37,12 @@ import static com.android.settings.applications.manageapplications.ManageApplica import static com.google.common.truth.Truth.assertThat; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class AppFilterRegistryTest { @Test diff --git a/tests/robotests/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceControllerTest.java b/tests/unit/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceControllerTest.java similarity index 82% rename from tests/robotests/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceControllerTest.java index 6dd53a368f5..c46f84a4acc 100644 --- a/tests/robotests/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 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. @@ -20,13 +20,14 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class FaceSettingsAttentionPreferenceControllerTest { private Context mContext; @@ -34,7 +35,7 @@ public class FaceSettingsAttentionPreferenceControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mController = new FaceSettingsAttentionPreferenceController(mContext); } diff --git a/tests/unit/src/com/android/settings/core/BadPreferenceController.java b/tests/unit/src/com/android/settings/core/BadPreferenceController.java new file mode 100644 index 00000000000..68d3b531ffe --- /dev/null +++ b/tests/unit/src/com/android/settings/core/BadPreferenceController.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 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; + +import android.content.Context; + +public class BadPreferenceController extends BasePreferenceController { + + public BadPreferenceController(Context context, String preferenceKey) { + super(context, preferenceKey); + throw new IllegalArgumentException("error"); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public boolean useDynamicSliceSummary() { + return true; + } +} diff --git a/tests/unit/src/com/android/settings/core/BasePreferenceControllerSignatureInspector.java b/tests/unit/src/com/android/settings/core/BasePreferenceControllerSignatureInspector.java new file mode 100644 index 00000000000..d2f53466531 --- /dev/null +++ b/tests/unit/src/com/android/settings/core/BasePreferenceControllerSignatureInspector.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 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; + +import static com.google.common.truth.Truth.assertWithMessage; + +import android.content.Context; + +import com.android.settings.core.codeinspection.CodeInspector; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; + +public class BasePreferenceControllerSignatureInspector extends CodeInspector { + + private final List mExemptList; + + public BasePreferenceControllerSignatureInspector(List> classes) { + super(classes); + mExemptList = new ArrayList<>(); + initializeExemptList(mExemptList, + "exempt_invalid_base_preference_controller_constructor"); + } + + @Override + public void run() { + StringBuilder badClasses = new StringBuilder(); + + for (Class c : mClasses) { + if (!isConcreteSettingsClass(c)) { + // Not a Settings class, or is abstract, don't care. + continue; + } + if (!BasePreferenceController.class.isAssignableFrom(c)) { + // Not a BasePreferenceController, don't care. + continue; + } + final String className = c.getName(); + if (mExemptList.remove(className)) { + continue; + } + final Constructor[] constructors = c.getDeclaredConstructors(); + if (constructors == null || constructors.length == 0) { + badClasses.append(c.getName()).append(","); + } + + boolean hasValidConstructor = false; + for (Constructor constructor : constructors) { + if (hasValidConstructorSignature(constructor)) { + hasValidConstructor = true; + break; + } + } + if (!hasValidConstructor) { + badClasses.append(className).append(","); + } + } + + assertWithMessage("All BasePreferenceController (and subclasses) constructor must either" + + " only take Context, or (Context, String). No other types are allowed") + .that(badClasses.toString()) + .isEmpty(); + + assertWithMessage("Something in the exempt list is no longer relevant. Please remove" + + "it from packages/apps/Settings/tests/robotests/assets/" + + "exempt_invalid_base_preference_controller_constructor") + .that(mExemptList) + .isEmpty(); + } + + private static boolean hasValidConstructorSignature(Constructor constructor) { + final Class[] parameterTypes = constructor.getParameterTypes(); + if (parameterTypes.length == 1) { + return Context.class.isAssignableFrom(parameterTypes[0]); + } else if (parameterTypes.length == 2) { + return Context.class.isAssignableFrom(parameterTypes[0]) + && String.class.isAssignableFrom(parameterTypes[1]); + } + return false; + } +} diff --git a/tests/robotests/src/com/android/settings/core/SettingsSliderPreferenceControllerTest.java b/tests/unit/src/com/android/settings/core/SettingsSliderPreferenceControllerTest.java similarity index 73% rename from tests/robotests/src/com/android/settings/core/SettingsSliderPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/core/SettingsSliderPreferenceControllerTest.java index a04ec373e2c..846ffd753af 100644 --- a/tests/robotests/src/com/android/settings/core/SettingsSliderPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/core/SettingsSliderPreferenceControllerTest.java @@ -1,33 +1,35 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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 + * 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. + * 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; import static com.google.common.truth.Truth.assertThat; import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.slices.SliceData; import com.android.settings.widget.SeekBarPreference; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class SettingsSliderPreferenceControllerTest { private FakeSliderPreferenceController mSliderController; @@ -36,9 +38,9 @@ public class SettingsSliderPreferenceControllerTest { @Before public void setUp() { - mPreference = new SeekBarPreference(RuntimeEnvironment.application); - mSliderController = new FakeSliderPreferenceController(RuntimeEnvironment.application, - "key"); + mPreference = new SeekBarPreference(ApplicationProvider.getApplicationContext()); + mSliderController = new FakeSliderPreferenceController( + ApplicationProvider.getApplicationContext(), "key"); mPreference.setContinuousUpdates(true); mPreference.setMin(mSliderController.getMin()); @@ -71,7 +73,7 @@ public class SettingsSliderPreferenceControllerTest { private class FakeSliderPreferenceController extends SliderPreferenceController { - private final int MAX_STEPS = 2112; + private static final int MAX_STEPS = 2112; private int mPosition; private FakeSliderPreferenceController(Context context, String key) { diff --git a/tests/robotests/src/com/android/settings/core/TogglePreferenceControllerTest.java b/tests/unit/src/com/android/settings/core/TogglePreferenceControllerTest.java similarity index 89% rename from tests/robotests/src/com/android/settings/core/TogglePreferenceControllerTest.java rename to tests/unit/src/com/android/settings/core/TogglePreferenceControllerTest.java index 541f0c412ba..8817a176203 100644 --- a/tests/robotests/src/com/android/settings/core/TogglePreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/core/TogglePreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2020 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. @@ -20,16 +20,16 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import androidx.preference.SwitchPreference; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.settings.slices.SliceData; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class TogglePreferenceControllerTest { private FakeToggle mToggleController; @@ -39,7 +39,7 @@ public class TogglePreferenceControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mPreference = new SwitchPreference(mContext); mToggleController = new FakeToggle(mContext, "key"); } @@ -102,7 +102,7 @@ public class TogglePreferenceControllerTest { private static class FakeToggle extends TogglePreferenceController { - private boolean checkedFlag; + private boolean mCheckedFlag; private FakeToggle(Context context, String preferenceKey) { super(context, preferenceKey); @@ -110,12 +110,12 @@ public class TogglePreferenceControllerTest { @Override public boolean isChecked() { - return checkedFlag; + return mCheckedFlag; } @Override public boolean setChecked(boolean isChecked) { - checkedFlag = isChecked; + mCheckedFlag = isChecked; return true; } diff --git a/tests/unit/src/com/android/settings/core/codeinspection/ClassScanner.java b/tests/unit/src/com/android/settings/core/codeinspection/ClassScanner.java new file mode 100644 index 00000000000..b129ecd132a --- /dev/null +++ b/tests/unit/src/com/android/settings/core/codeinspection/ClassScanner.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2020 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.codeinspection; + +import com.google.common.reflect.ClassPath; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Scans and builds all classes in current classloader. + */ +public class ClassScanner { + + public List> getClassesForPackage(String packageName) throws ClassNotFoundException { + final List> classes = new ArrayList<>(); + + try { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + ClassPath classPath = ClassPath.from(classLoader); + + // Some anonymous classes don't return true when calling isAnonymousClass(), but they + // always seem to be nested anonymous classes like com.android.settings.Foo$1$2. In + // general we don't want any anonymous classes so we just filter these out by searching + // for $[0-9] in the name. + Pattern anonymousClassPattern = Pattern.compile(".*\\$\\d+.*"); + Matcher anonymousClassMatcher = anonymousClassPattern.matcher(""); + + for (ClassPath.ClassInfo info : classPath.getAllClasses()) { + if (info.getPackageName().startsWith(packageName)) { + try { + Class clazz = classLoader.loadClass(info.getName()); + if (clazz.isAnonymousClass() || anonymousClassMatcher.reset( + clazz.getName()).matches()) { + continue; + } + classes.add(clazz); + } catch (NoClassDefFoundError e) { + // do nothing. this class hasn't been found by the + // loader, and we don't care. + } + } + } + } catch (final IOException e) { + throw new ClassNotFoundException("Error when parsing " + packageName, e); + } + return classes; + } +} diff --git a/tests/unit/src/com/android/settings/core/codeinspection/CodeInspector.java b/tests/unit/src/com/android/settings/core/codeinspection/CodeInspector.java new file mode 100644 index 00000000000..fb8ad6e6d56 --- /dev/null +++ b/tests/unit/src/com/android/settings/core/codeinspection/CodeInspector.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2020 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.codeinspection; + +import static com.google.common.truth.Truth.assertWithMessage; + +import androidx.test.core.app.ApplicationProvider; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Modifier; +import java.util.List; + +/** + * Inspector takes a list of class objects and perform static code analysis in its {@link #run()} + * method. + */ +public abstract class CodeInspector { + + protected static final String PACKAGE_NAME = "com.android.settings"; + + private static final String TEST_CLASS_SUFFIX = "Test"; + private static final String TEST_INNER_CLASS_SIGNATURE = "Test$"; + + protected final List> mClasses; + + public CodeInspector(List> classes) { + mClasses = classes; + } + + /** + * Code inspection runner method. + */ + public abstract void run(); + + protected void assertNoObsoleteInExemptList(String listName, List list) { + final StringBuilder obsoleteExemptItems = new StringBuilder(listName).append( + " contains item that should not be exempted.\n"); + for (String c : list) { + obsoleteExemptItems.append(c).append("\n"); + } + assertWithMessage(obsoleteExemptItems.toString()).that(list).isEmpty(); + } + + protected boolean isConcreteSettingsClass(Class clazz) { + // Abstract classes + if (Modifier.isAbstract(clazz.getModifiers())) { + return false; + } + final String packageName = clazz.getPackage().getName(); + // Classes that are not in Settings + if (!packageName.contains(PACKAGE_NAME + ".") && !packageName.endsWith(PACKAGE_NAME)) { + return false; + } + final String className = clazz.getName(); + // Classes from tests + if (className.endsWith(TEST_CLASS_SUFFIX)) { + return false; + } + if (className.contains(TEST_INNER_CLASS_SIGNATURE)) { + return false; + } + return true; + } + + public static void initializeExemptList(List exemptList, String filename) { + try { + final InputStream in = ApplicationProvider.getApplicationContext() + .getAssets().open(filename); + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + String line; + while ((line = reader.readLine()) != null) { + exemptList.add(line); + } + } catch (Exception e) { + throw new IllegalArgumentException("Error initializing exempt list " + filename, e); + } + } +} diff --git a/tests/unit/src/com/android/settings/core/codeinspection/LifecycleObserverCodeInspector.java b/tests/unit/src/com/android/settings/core/codeinspection/LifecycleObserverCodeInspector.java new file mode 100644 index 00000000000..f8b2a466667 --- /dev/null +++ b/tests/unit/src/com/android/settings/core/codeinspection/LifecycleObserverCodeInspector.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2020 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.codeinspection; + +import static org.junit.Assert.fail; + +import android.util.ArraySet; + +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnAttach; +import com.android.settingslib.core.lifecycle.events.OnCreate; +import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu; +import com.android.settingslib.core.lifecycle.events.OnDestroy; +import com.android.settingslib.core.lifecycle.events.OnOptionsItemSelected; +import com.android.settingslib.core.lifecycle.events.OnPause; +import com.android.settingslib.core.lifecycle.events.OnPrepareOptionsMenu; +import com.android.settingslib.core.lifecycle.events.OnResume; +import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState; +import com.android.settingslib.core.lifecycle.events.OnStart; +import com.android.settingslib.core.lifecycle.events.OnStop; +import com.android.settingslib.core.lifecycle.events.SetPreferenceScreen; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +public class LifecycleObserverCodeInspector extends CodeInspector { + + private static final List LIFECYCLE_EVENTS = Arrays.asList( + OnAttach.class, + OnCreate.class, + OnCreateOptionsMenu.class, + OnDestroy.class, + OnOptionsItemSelected.class, + OnPause.class, + OnPrepareOptionsMenu.class, + OnResume.class, + OnSaveInstanceState.class, + OnStart.class, + OnStop.class, + SetPreferenceScreen.class + ); + + public LifecycleObserverCodeInspector(List> classes) { + super(classes); + } + + @Override + public void run() { + final Set notImplementingLifecycleObserver = new ArraySet<>(); + for (Class clazz : mClasses) { + if (!isConcreteSettingsClass(clazz)) { + continue; + } + boolean classObservesLifecycleEvent = false; + for (Class event : LIFECYCLE_EVENTS) { + if (event.isAssignableFrom(clazz)) { + classObservesLifecycleEvent = true; + break; + } + } + if (classObservesLifecycleEvent && !LifecycleObserver.class.isAssignableFrom(clazz)) { + // Observes LifecycleEvent but not implementing LifecycleObserver. Something is + // wrong. + notImplementingLifecycleObserver.add(clazz.getName()); + } + } + if (!notImplementingLifecycleObserver.isEmpty()) { + final String errorTemplate = + "The following class(es) implements lifecycle.events.*, but don't " + + "implement LifecycleObserver. Something is wrong:\n"; + final StringBuilder error = new StringBuilder(errorTemplate); + for (String name : notImplementingLifecycleObserver) { + error.append(name).append('\n'); + } + fail(error.toString()); + } + } +} diff --git a/tests/unit/src/com/android/settings/core/instrumentation/InstrumentableFragmentCodeInspector.java b/tests/unit/src/com/android/settings/core/instrumentation/InstrumentableFragmentCodeInspector.java new file mode 100644 index 00000000000..98958cf9184 --- /dev/null +++ b/tests/unit/src/com/android/settings/core/instrumentation/InstrumentableFragmentCodeInspector.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2020 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.assertWithMessage; + +import android.util.ArraySet; + +import androidx.fragment.app.Fragment; + +import com.android.settings.core.codeinspection.CodeInspector; +import com.android.settingslib.core.instrumentation.Instrumentable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * {@link CodeInspector} that verifies all fragments implements Instrumentable. + */ +public class InstrumentableFragmentCodeInspector extends CodeInspector { + + private final List mNotImplementingInstrumentableExemptList; + + public InstrumentableFragmentCodeInspector(List> classes) { + super(classes); + mNotImplementingInstrumentableExemptList = new ArrayList<>(); + initializeExemptList(mNotImplementingInstrumentableExemptList, + "exempt_not_implementing_instrumentable"); + } + + @Override + public void run() { + final Set broken = new ArraySet<>(); + + for (Class clazz : mClasses) { + if (!isConcreteSettingsClass(clazz)) { + continue; + } + final String className = clazz.getName(); + // If it's a fragment, it must also be instrumentable. + final boolean allowlisted = + mNotImplementingInstrumentableExemptList.remove(className); + if (Fragment.class.isAssignableFrom(clazz) + && !Instrumentable.class.isAssignableFrom(clazz) + && !allowlisted) { + broken.add(className); + } + } + final StringBuilder sb = new StringBuilder( + "All fragments should implement Instrumentable, but the following are not:\n"); + for (String c : broken) { + sb.append(c).append("\n"); + } + assertWithMessage(sb.toString()).that(broken.isEmpty()).isTrue(); + assertNoObsoleteInExemptList("exempt_not_implementing_instrumentable", + mNotImplementingInstrumentableExemptList); + } +} diff --git a/tests/robotests/src/com/android/settings/dashboard/CategoryManagerTest.java b/tests/unit/src/com/android/settings/dashboard/CategoryManagerTest.java similarity index 97% rename from tests/robotests/src/com/android/settings/dashboard/CategoryManagerTest.java rename to tests/unit/src/com/android/settings/dashboard/CategoryManagerTest.java index a0db866925c..98540f92e1b 100644 --- a/tests/robotests/src/com/android/settings/dashboard/CategoryManagerTest.java +++ b/tests/unit/src/com/android/settings/dashboard/CategoryManagerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2020 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. @@ -29,6 +29,9 @@ import android.content.pm.ProviderInfo; import android.os.Bundle; import android.util.Pair; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settingslib.drawer.ActivityTile; import com.android.settingslib.drawer.CategoryKey; import com.android.settingslib.drawer.DashboardCategory; @@ -38,13 +41,11 @@ 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; import java.util.HashMap; import java.util.Map; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class CategoryManagerTest { private ActivityInfo mActivityInfo; @@ -55,7 +56,7 @@ public class CategoryManagerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mActivityInfo = new ActivityInfo(); mActivityInfo.packageName = "pkg"; mActivityInfo.name = "class"; @@ -144,7 +145,8 @@ public class CategoryManagerTest { mCategoryByKeyMap.put(CATEGORY_HOMEPAGE, category); // Sort their priorities - mCategoryManager.sortCategories(RuntimeEnvironment.application, mCategoryByKeyMap); + mCategoryManager.sortCategories(ApplicationProvider.getApplicationContext(), + mCategoryByKeyMap); // Verify they are now sorted. assertThat(category.getTile(0)).isSameInstanceAs(tile3); diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentRegistryTest.java b/tests/unit/src/com/android/settings/dashboard/DashboardFragmentRegistryTest.java similarity index 91% rename from tests/robotests/src/com/android/settings/dashboard/DashboardFragmentRegistryTest.java rename to tests/unit/src/com/android/settings/dashboard/DashboardFragmentRegistryTest.java index 10aaad8b2f0..435fe01ab81 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardFragmentRegistryTest.java +++ b/tests/unit/src/com/android/settings/dashboard/DashboardFragmentRegistryTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -18,14 +18,15 @@ package com.android.settings.dashboard; import static com.google.common.truth.Truth.assertThat; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.accounts.AccountDashboardFragment; import com.android.settingslib.drawer.CategoryKey; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class DashboardFragmentRegistryTest { @Test public void pageAndKeyShouldHave1to1Mapping() { diff --git a/tests/unit/src/com/android/settings/dashboard/DashboardFragmentSearchIndexProviderInspector.java b/tests/unit/src/com/android/settings/dashboard/DashboardFragmentSearchIndexProviderInspector.java new file mode 100644 index 00000000000..68a6788f00c --- /dev/null +++ b/tests/unit/src/com/android/settings/dashboard/DashboardFragmentSearchIndexProviderInspector.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2020 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.dashboard; + +import android.content.Context; + +import androidx.fragment.app.Fragment; +import androidx.test.core.app.ApplicationProvider; + +import com.android.settings.core.BasePreferenceController; +import com.android.settings.core.PreferenceControllerListHelper; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.search.DatabaseIndexingUtils; +import com.android.settingslib.core.AbstractPreferenceController; + +import java.util.List; + +public class DashboardFragmentSearchIndexProviderInspector { + + public static boolean isSharingPreferenceControllers(Class clazz) { + final Context context = ApplicationProvider.getApplicationContext(); + final Fragment fragment; + try { + fragment = Fragment.instantiate(context, clazz.getName()); + } catch (Throwable e) { + // Can't do much with exception, assume the test passed. + return true; + } + if (!(fragment instanceof DashboardFragment)) { + return true; + } + + final BaseSearchIndexProvider provider = + (BaseSearchIndexProvider) DatabaseIndexingUtils.getSearchIndexProvider(clazz); + if (provider == null) { + return true; + } + final List controllersFromSearchIndexProvider; + final List controllersFromFragment; + try { + controllersFromSearchIndexProvider = provider.getPreferenceControllers(context); + } catch (Throwable e) { + // Can't do much with exception, assume the test passed. + return true; + } + try { + controllersFromFragment = + ((DashboardFragment) fragment).createPreferenceControllers(context); + List controllersFromXml = PreferenceControllerListHelper + .getPreferenceControllersFromXml(context, + ((DashboardFragment) fragment).getPreferenceScreenResId()); + final List uniqueControllerFromXml = + PreferenceControllerListHelper.filterControllers( + controllersFromXml, controllersFromFragment); + controllersFromFragment.addAll(uniqueControllerFromXml); + + } catch (Throwable e) { + // Can't do much with exception, assume the test passed. + return true; + } + + if (controllersFromFragment == controllersFromSearchIndexProvider) { + return true; + } else if (controllersFromFragment != null && controllersFromSearchIndexProvider != null) { + return controllersFromFragment.size() == controllersFromSearchIndexProvider.size(); + } else { + return false; + } + } +} diff --git a/tests/robotests/src/com/android/settings/datetime/timezone/RegionZonePickerTest.java b/tests/unit/src/com/android/settings/datetime/timezone/RegionZonePickerTest.java similarity index 93% rename from tests/robotests/src/com/android/settings/datetime/timezone/RegionZonePickerTest.java rename to tests/unit/src/com/android/settings/datetime/timezone/RegionZonePickerTest.java index dd734bb6c62..de607da3004 100644 --- a/tests/robotests/src/com/android/settings/datetime/timezone/RegionZonePickerTest.java +++ b/tests/unit/src/com/android/settings/datetime/timezone/RegionZonePickerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -20,6 +20,8 @@ import static com.google.common.truth.Truth.assertThat; import android.icu.text.Collator; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.datetime.timezone.RegionZonePicker.TimeZoneInfoComparator; import com.android.settings.datetime.timezone.TimeZoneInfo.Formatter; @@ -31,9 +33,8 @@ import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class RegionZonePickerTest { @Test diff --git a/tests/robotests/src/com/android/settings/datetime/timezone/TimeZoneInfoPreferenceControllerTest.java b/tests/unit/src/com/android/settings/datetime/timezone/TimeZoneInfoPreferenceControllerTest.java similarity index 90% rename from tests/robotests/src/com/android/settings/datetime/timezone/TimeZoneInfoPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/datetime/timezone/TimeZoneInfoPreferenceControllerTest.java index 563bf8dd7fa..64d8abbe719 100644 --- a/tests/robotests/src/com/android/settings/datetime/timezone/TimeZoneInfoPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/datetime/timezone/TimeZoneInfoPreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -23,18 +23,19 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.datetime.timezone.TimeZoneInfo.Formatter; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import java.util.Date; import java.util.Locale; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class TimeZoneInfoPreferenceControllerTest { private TimeZoneInfo mTimeZoneInfo; @@ -42,7 +43,7 @@ public class TimeZoneInfoPreferenceControllerTest { @Before public void setUp() { - final Context context = RuntimeEnvironment.application; + final Context context = ApplicationProvider.getApplicationContext(); final Date now = new Date(0L); // 00:00 1/1/1970 final Formatter formatter = new Formatter(Locale.US, now); mTimeZoneInfo = formatter.format("America/Los_Angeles"); diff --git a/tests/robotests/src/com/android/settings/datetime/timezone/TimeZoneInfoTest.java b/tests/unit/src/com/android/settings/datetime/timezone/TimeZoneInfoTest.java similarity index 93% rename from tests/robotests/src/com/android/settings/datetime/timezone/TimeZoneInfoTest.java rename to tests/unit/src/com/android/settings/datetime/timezone/TimeZoneInfoTest.java index fd8b81f5c0e..f43cde3cd60 100644 --- a/tests/robotests/src/com/android/settings/datetime/timezone/TimeZoneInfoTest.java +++ b/tests/unit/src/com/android/settings/datetime/timezone/TimeZoneInfoTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -18,6 +18,8 @@ package com.android.settings.datetime.timezone; import static com.google.common.truth.Truth.assertThat; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.datetime.timezone.TimeZoneInfo.Formatter; import org.junit.Test; @@ -25,9 +27,8 @@ import org.junit.runner.RunWith; import java.util.Date; import java.util.Locale; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class TimeZoneInfoTest { @Test diff --git a/tests/robotests/src/com/android/settings/development/OverlaySettingsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/development/OverlaySettingsPreferenceControllerTest.java similarity index 95% rename from tests/robotests/src/com/android/settings/development/OverlaySettingsPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/development/OverlaySettingsPreferenceControllerTest.java index 4f04c384723..827f5a199a9 100644 --- a/tests/robotests/src/com/android/settings/development/OverlaySettingsPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/development/OverlaySettingsPreferenceControllerTest.java @@ -22,14 +22,14 @@ import android.content.Context; import android.content.SharedPreferences; import androidx.preference.SwitchPreference; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class OverlaySettingsPreferenceControllerTest { private Context mContext; @@ -38,7 +38,7 @@ public class OverlaySettingsPreferenceControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mController = new OverlaySettingsPreferenceController(mContext); mPreference = new SwitchPreference(mContext); } diff --git a/tests/unit/src/com/android/settings/development/autofill/AutofillTestingHelper.java b/tests/unit/src/com/android/settings/development/autofill/AutofillTestingHelper.java new file mode 100644 index 00000000000..c1ef2b57229 --- /dev/null +++ b/tests/unit/src/com/android/settings/development/autofill/AutofillTestingHelper.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 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.development.autofill; + +import android.content.ContentResolver; +import android.content.Context; +import android.provider.Settings; +import android.provider.Settings.SettingNotFoundException; + +final class AutofillTestingHelper { + private final ContentResolver mResolver; + + AutofillTestingHelper(Context context) { + mResolver = context.getContentResolver(); + } + + public void setLoggingLevel(int max) { + setGlobal(Settings.Global.AUTOFILL_LOGGING_LEVEL, max); + } + + public void setMaxPartitionsSize(int max) { + setGlobal(Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE, max); + } + + public void setMaxVisibleDatasets(int level) { + setGlobal(Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, level); + } + + public int getLoggingLevel() throws SettingNotFoundException { + return getGlobal(Settings.Global.AUTOFILL_LOGGING_LEVEL); + } + + public int getMaxPartitionsSize() throws SettingNotFoundException { + return getGlobal(Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE); + } + + public int getMaxVisibleDatasets() throws SettingNotFoundException { + return getGlobal(Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS); + } + + private void setGlobal(String key, int value) { + Settings.Global.putInt(mResolver, key, value); + } + + private int getGlobal(String key) throws SettingNotFoundException { + return Settings.Global.getInt(mResolver, key); + } +} diff --git a/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPersistentTest.java b/tests/unit/src/com/android/settings/development/featureflags/FeatureFlagPersistentTest.java similarity index 93% rename from tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPersistentTest.java rename to tests/unit/src/com/android/settings/development/featureflags/FeatureFlagPersistentTest.java index 7d7e36bef16..9b978b0a8de 100644 --- a/tests/robotests/src/com/android/settings/development/featureflags/FeatureFlagPersistentTest.java +++ b/tests/unit/src/com/android/settings/development/featureflags/FeatureFlagPersistentTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -22,14 +22,15 @@ import android.os.SystemProperties; import android.provider.Settings; import android.util.FeatureFlagUtils; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class FeatureFlagPersistentTest { private static final String TEST_FEATURE_NAME = "test_feature"; @@ -43,7 +44,7 @@ public class FeatureFlagPersistentTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); FeatureFlagPersistent.getAllPersistentFlags().add(TEST_FEATURE_NAME); FeatureFlagUtils.getAllFeatureFlags().put(TEST_FEATURE_NAME, "false"); @@ -137,7 +138,8 @@ public class FeatureFlagPersistentTest { FeatureFlagPersistent.setEnabled(mContext, TEST_FEATURE_NAME, true); - assertThat(SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME)).isEqualTo("true"); + assertThat(SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME)) + .isEqualTo("true"); assertThat(FeatureFlagUtils.isEnabled(mContext, TEST_FEATURE_NAME)).isTrue(); } @@ -150,7 +152,8 @@ public class FeatureFlagPersistentTest { FeatureFlagPersistent.setEnabled(mContext, TEST_FEATURE_NAME, false); - assertThat(SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME)).isEqualTo("false"); + assertThat(SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + TEST_FEATURE_NAME)) + .isEqualTo("false"); assertThat(FeatureFlagUtils.isEnabled(mContext, TEST_FEATURE_NAME)).isFalse(); } } diff --git a/tests/robotests/src/com/android/settings/development/transcode/TranscodeDefaultOptionPreferenceControllerTest.java b/tests/unit/src/com/android/settings/development/transcode/TranscodeDefaultOptionPreferenceControllerTest.java similarity index 96% rename from tests/robotests/src/com/android/settings/development/transcode/TranscodeDefaultOptionPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/development/transcode/TranscodeDefaultOptionPreferenceControllerTest.java index 06e66a1bdc2..550613bd62d 100644 --- a/tests/robotests/src/com/android/settings/development/transcode/TranscodeDefaultOptionPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/development/transcode/TranscodeDefaultOptionPreferenceControllerTest.java @@ -22,15 +22,15 @@ import android.content.Context; import android.os.SystemProperties; import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.settings.core.BasePreferenceController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class TranscodeDefaultOptionPreferenceControllerTest { private static final String TRANSCODE_DEFAULT_SYS_PROP_KEY = "persist.sys.fuse.transcode_default"; diff --git a/tests/robotests/src/com/android/settings/development/transcode/TranscodeGlobalTogglePreferenceControllerTest.java b/tests/unit/src/com/android/settings/development/transcode/TranscodeGlobalTogglePreferenceControllerTest.java similarity index 96% rename from tests/robotests/src/com/android/settings/development/transcode/TranscodeGlobalTogglePreferenceControllerTest.java rename to tests/unit/src/com/android/settings/development/transcode/TranscodeGlobalTogglePreferenceControllerTest.java index aa2e672bb18..7c0acd7bea6 100644 --- a/tests/robotests/src/com/android/settings/development/transcode/TranscodeGlobalTogglePreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/development/transcode/TranscodeGlobalTogglePreferenceControllerTest.java @@ -22,13 +22,13 @@ import android.content.Context; import android.os.SystemProperties; import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class TranscodeGlobalTogglePreferenceControllerTest { private static final String TRANSCODE_ENABLED_PROP_KEY = "persist.sys.fuse.transcode_enabled"; diff --git a/tests/robotests/src/com/android/settings/development/transcode/TranscodeUserControlPreferenceControllerTest.java b/tests/unit/src/com/android/settings/development/transcode/TranscodeUserControlPreferenceControllerTest.java similarity index 96% rename from tests/robotests/src/com/android/settings/development/transcode/TranscodeUserControlPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/development/transcode/TranscodeUserControlPreferenceControllerTest.java index 8cba0c33f44..3caf8ae3c65 100644 --- a/tests/robotests/src/com/android/settings/development/transcode/TranscodeUserControlPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/development/transcode/TranscodeUserControlPreferenceControllerTest.java @@ -22,15 +22,15 @@ import android.content.Context; import android.os.SystemProperties; import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.settings.core.BasePreferenceController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class TranscodeUserControlPreferenceControllerTest { private static final String TRANSCODE_USER_CONTROL_SYS_PROP_KEY = "persist.sys.fuse.transcode_user_control"; diff --git a/tests/robotests/src/com/android/settings/deviceinfo/storage/VolumeSizesLoaderTest.java b/tests/unit/src/com/android/settings/deviceinfo/storage/VolumeSizesLoaderTest.java similarity index 61% rename from tests/robotests/src/com/android/settings/deviceinfo/storage/VolumeSizesLoaderTest.java rename to tests/unit/src/com/android/settings/deviceinfo/storage/VolumeSizesLoaderTest.java index 5aa9f72e386..79c5db8d831 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/storage/VolumeSizesLoaderTest.java +++ b/tests/unit/src/com/android/settings/deviceinfo/storage/VolumeSizesLoaderTest.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2020 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.deviceinfo.storage; import static com.google.common.truth.Truth.assertThat; @@ -8,14 +23,15 @@ import static org.mockito.Mockito.when; import android.os.storage.VolumeInfo; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settingslib.deviceinfo.PrivateStorageInfo; import com.android.settingslib.deviceinfo.StorageVolumeProvider; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class VolumeSizesLoaderTest { @Test public void getVolumeSize_getsValidSizes() throws Exception { diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java b/tests/unit/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java similarity index 82% rename from tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java rename to tests/unit/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java index 2919edc406c..b807114f412 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java +++ b/tests/unit/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleRadioButtonsControllerTest.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2020 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.fuelgauge.batterysaver; import static com.google.common.truth.Truth.assertThat; @@ -9,13 +24,14 @@ import android.provider.Settings; import android.provider.Settings.Global; import android.provider.Settings.Secure; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class BatterySaverScheduleRadioButtonsControllerTest { private Context mContext; private ContentResolver mResolver; @@ -24,7 +40,7 @@ public class BatterySaverScheduleRadioButtonsControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mSeekBarController = new BatterySaverScheduleSeekBarController(mContext); mController = new BatterySaverScheduleRadioButtonsController( mContext, mSeekBarController); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverStickyPreferenceControllerTest.java b/tests/unit/src/com/android/settings/fuelgauge/batterysaver/BatterySaverStickyPreferenceControllerTest.java similarity index 87% rename from tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverStickyPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/fuelgauge/batterysaver/BatterySaverStickyPreferenceControllerTest.java index 0e7c312eb18..8cfedf6f85d 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverStickyPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/fuelgauge/batterysaver/BatterySaverStickyPreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2020 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. @@ -21,13 +21,15 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.provider.Settings; import android.provider.Settings.Global; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class BatterySaverStickyPreferenceControllerTest { private static final String PREF_KEY = "battery_saver_sticky"; @@ -37,7 +39,7 @@ public class BatterySaverStickyPreferenceControllerTest { @Before public void setup() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mController = new BatterySaverStickyPreferenceController(mContext, PREF_KEY); } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AppInfoTest.java b/tests/unit/src/com/android/settings/fuelgauge/batterytip/AppInfoTest.java similarity index 95% rename from tests/robotests/src/com/android/settings/fuelgauge/batterytip/AppInfoTest.java rename to tests/unit/src/com/android/settings/fuelgauge/batterytip/AppInfoTest.java index ad546f38a42..069f1231a78 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AppInfoTest.java +++ b/tests/unit/src/com/android/settings/fuelgauge/batterytip/AppInfoTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -21,6 +21,8 @@ import static com.google.common.truth.Truth.assertThat; import android.os.Parcel; import android.text.format.DateUtils; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -28,9 +30,8 @@ import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class AppInfoTest { private static final String PACKAGE_NAME = "com.android.app"; diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java b/tests/unit/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java similarity index 95% rename from tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java rename to tests/unit/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java index 9b54fc77f2e..4be2ae6c339 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java +++ b/tests/unit/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2020 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. @@ -22,13 +22,14 @@ import android.content.Context; import android.provider.Settings; import android.text.format.DateUtils; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class BatteryTipPolicyTest { private static final String BATTERY_TIP_CONSTANTS_VALUE = "battery_tip_enabled=true" @@ -54,7 +55,7 @@ public class BatteryTipPolicyTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); } @Test diff --git a/tests/robotests/src/com/android/settings/gestures/OneHandedAppTapsExitPreferenceControllerTest.java b/tests/unit/src/com/android/settings/gestures/OneHandedAppTapsExitPreferenceControllerTest.java similarity index 93% rename from tests/robotests/src/com/android/settings/gestures/OneHandedAppTapsExitPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/gestures/OneHandedAppTapsExitPreferenceControllerTest.java index 28ce8020242..18738e9c26a 100644 --- a/tests/robotests/src/com/android/settings/gestures/OneHandedAppTapsExitPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/gestures/OneHandedAppTapsExitPreferenceControllerTest.java @@ -21,16 +21,16 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import androidx.preference.SwitchPreference; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.settings.core.TogglePreferenceController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class OneHandedAppTapsExitPreferenceControllerTest { private static final String KEY = "gesture_app_taps_to_exit"; @@ -42,7 +42,7 @@ public class OneHandedAppTapsExitPreferenceControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mController = new OneHandedAppTapsExitPreferenceController(mContext, KEY); mSwitchPreference = new SwitchPreference(mContext); mSwitchPreference.setKey(KEY); diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/CardDatabaseHelperTest.java b/tests/unit/src/com/android/settings/homepage/contextualcards/CardDatabaseHelperTest.java similarity index 89% rename from tests/robotests/src/com/android/settings/homepage/contextualcards/CardDatabaseHelperTest.java rename to tests/unit/src/com/android/settings/homepage/contextualcards/CardDatabaseHelperTest.java index c9082250708..cf9b3c64ca5 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/CardDatabaseHelperTest.java +++ b/tests/unit/src/com/android/settings/homepage/contextualcards/CardDatabaseHelperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -22,14 +22,15 @@ import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class CardDatabaseHelperTest { private Context mContext; @@ -38,7 +39,7 @@ public class CardDatabaseHelperTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mCardDatabaseHelper = CardDatabaseHelper.getInstance(mContext); mDatabase = mCardDatabaseHelper.getReadableDatabase(); } diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTableTest.java b/tests/unit/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTableTest.java similarity index 96% rename from tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTableTest.java rename to tests/unit/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTableTest.java index 36f9c96566b..a7acffcaf9c 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTableTest.java +++ b/tests/unit/src/com/android/settings/homepage/contextualcards/ContextualCardLookupTableTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -18,18 +18,19 @@ package com.android.settings.homepage.contextualcards; import static com.google.common.truth.Truth.assertThat; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.homepage.contextualcards.ContextualCardLookupTable.ControllerRendererMapping; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; import java.util.ArrayList; import java.util.List; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class ContextualCardLookupTableTest { private static final int UNSUPPORTED_CARD_TYPE = -99999; diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallbackTest.java b/tests/unit/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallbackTest.java similarity index 95% rename from tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallbackTest.java rename to tests/unit/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallbackTest.java index 1e17a0bae6b..3e7dadf0c03 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallbackTest.java +++ b/tests/unit/src/com/android/settings/homepage/contextualcards/ContextualCardsDiffCallbackTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 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,9 +11,8 @@ * 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.homepage.contextualcards; import static com.android.settings.intelligence.ContextualCardProto.ContextualCard.Category.IMPORTANT_VALUE; @@ -23,15 +22,16 @@ import static com.google.common.truth.Truth.assertThat; import android.net.Uri; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; import java.util.ArrayList; import java.util.List; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class ContextualCardsDiffCallbackTest { private static final Uri TEST_SLICE_URI = Uri.parse("content://test/test"); diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardTest.java b/tests/unit/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardTest.java similarity index 90% rename from tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardTest.java rename to tests/unit/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardTest.java index b658822ecaa..0a039a9b2f1 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardTest.java +++ b/tests/unit/src/com/android/settings/homepage/contextualcards/conditional/ConditionFooterContextualCardTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -18,13 +18,14 @@ package com.android.settings.homepage.contextualcards.conditional; import static com.google.common.truth.Truth.assertThat; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.homepage.contextualcards.ContextualCard; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class ConditionFooterContextualCardTest { @Test(expected = IllegalArgumentException.class) diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardTest.java b/tests/unit/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardTest.java similarity index 90% rename from tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardTest.java rename to tests/unit/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardTest.java index 275e96b672b..59ff550c846 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardTest.java +++ b/tests/unit/src/com/android/settings/homepage/contextualcards/conditional/ConditionHeaderContextualCardTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -18,13 +18,14 @@ package com.android.settings.homepage.contextualcards.conditional; import static com.google.common.truth.Truth.assertThat; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.homepage.contextualcards.ContextualCard; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class ConditionHeaderContextualCardTest { @Test(expected = IllegalArgumentException.class) diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionalContextualCardTest.java b/tests/unit/src/com/android/settings/homepage/contextualcards/conditional/ConditionalContextualCardTest.java similarity index 92% rename from tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionalContextualCardTest.java rename to tests/unit/src/com/android/settings/homepage/contextualcards/conditional/ConditionalContextualCardTest.java index 3f57228368c..a06afc89d9e 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/conditional/ConditionalContextualCardTest.java +++ b/tests/unit/src/com/android/settings/homepage/contextualcards/conditional/ConditionalContextualCardTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -21,13 +21,14 @@ import static com.android.settings.homepage.contextualcards.conditional.Conditio import static com.google.common.truth.Truth.assertThat; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.homepage.contextualcards.ContextualCard; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class ConditionalContextualCardTest { @Test(expected = IllegalArgumentException.class) diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/FaceSetupSliceTest.java b/tests/unit/src/com/android/settings/homepage/contextualcards/slices/FaceSetupSliceTest.java similarity index 94% rename from tests/robotests/src/com/android/settings/homepage/contextualcards/slices/FaceSetupSliceTest.java rename to tests/unit/src/com/android/settings/homepage/contextualcards/slices/FaceSetupSliceTest.java index 6f212dfe410..a67d2e9b743 100644 --- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/FaceSetupSliceTest.java +++ b/tests/unit/src/com/android/settings/homepage/contextualcards/slices/FaceSetupSliceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 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,9 +11,8 @@ * 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.homepage.contextualcards.slices; import static com.google.common.truth.Truth.assertThat; @@ -31,14 +30,14 @@ import android.provider.Settings; import androidx.slice.SliceMetadata; import androidx.slice.SliceProvider; import androidx.slice.widget.SliceLiveData; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class FaceSetupSliceTest { private Context mContext; @@ -48,7 +47,7 @@ public class FaceSetupSliceTest { public void setUp() { // Set-up specs for SliceMetadata. SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); - mContext = spy(RuntimeEnvironment.application); + mContext = spy(ApplicationProvider.getApplicationContext()); mPackageManager = mock(PackageManager.class); when(mContext.getPackageManager()).thenReturn(mPackageManager); } diff --git a/tests/unit/src/com/android/settings/network/ims/MockVtQueryImsState.java b/tests/unit/src/com/android/settings/network/ims/MockVtQueryImsState.java new file mode 100644 index 00000000000..0949f1c0262 --- /dev/null +++ b/tests/unit/src/com/android/settings/network/ims/MockVtQueryImsState.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2020 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.network.ims; + +import android.content.Context; +import android.telephony.ims.ImsException; + +/** + * Controller class for mock VT status + */ +public class MockVtQueryImsState extends VtQueryImsState { + + private Boolean mIsTtyOnVolteEnabled; + private Boolean mIsEnabledOnPlatform; + private Boolean mIsProvisionedOnDevice; + private Boolean mIsEnabledByUser; + private Boolean mIsServiceStateReady; + + /** + * Constructor + * + * @param context {@link Context} + * @param subId subscription's id + */ + public MockVtQueryImsState(Context context, int subId) { + super(context, subId); + } + + public void setIsTtyOnVolteEnabled(boolean enabled) { + mIsTtyOnVolteEnabled = enabled; + } + + @Override + boolean isTtyOnVolteEnabled(int subId) { + if (mIsTtyOnVolteEnabled != null) { + return mIsTtyOnVolteEnabled; + } + return super.isTtyOnVolteEnabled(subId); + } + + public void setIsEnabledByPlatform(boolean isEnabled) { + mIsEnabledOnPlatform = isEnabled; + } + + @Override + boolean isEnabledByPlatform(int subId) throws InterruptedException, ImsException, + IllegalArgumentException { + if (mIsEnabledOnPlatform != null) { + return mIsEnabledOnPlatform; + } + return super.isEnabledByPlatform(subId); + } + + public void setIsProvisionedOnDevice(boolean isProvisioned) { + mIsProvisionedOnDevice = isProvisioned; + } + + @Override + boolean isProvisionedOnDevice(int subId) { + if (mIsProvisionedOnDevice != null) { + return mIsProvisionedOnDevice; + } + return super.isProvisionedOnDevice(subId); + } + + public void setServiceStateReady(boolean isReady) { + mIsServiceStateReady = isReady; + } + + @Override + boolean isServiceStateReady(int subId) throws InterruptedException, ImsException, + IllegalArgumentException { + if (mIsServiceStateReady != null) { + return mIsServiceStateReady; + } + return super.isServiceStateReady(subId); + } + + public void setIsEnabledByUser(boolean enabled) { + mIsEnabledByUser = enabled; + } + + @Override + boolean isEnabledByUser(int subId) { + if (mIsEnabledByUser != null) { + return mIsEnabledByUser; + } + return super.isEnabledByUser(subId); + } +} diff --git a/tests/unit/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java b/tests/unit/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java new file mode 100644 index 00000000000..abea839791e --- /dev/null +++ b/tests/unit/src/com/android/settings/network/ims/MockWifiCallingQueryImsState.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2020 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.network.ims; + +import android.content.Context; +import android.telephony.ims.ImsException; + +/** + * Controller class for mock Wifi calling status + */ +public class MockWifiCallingQueryImsState extends WifiCallingQueryImsState { + + private Boolean mIsTtyOnVolteEnabled; + private Boolean mIsEnabledOnPlatform; + private Boolean mIsProvisionedOnDevice; + private Boolean mIsServiceStateReady; + private Boolean mIsEnabledByUser; + + /** + * Constructor + * + * @param context {@code Context} + * @param subId subscription's id + */ + public MockWifiCallingQueryImsState(Context context, int subId) { + super(context, subId); + } + + public void setIsTtyOnVolteEnabled(boolean enabled) { + mIsTtyOnVolteEnabled = enabled; + } + + @Override + boolean isTtyOnVolteEnabled(int subId) { + if (mIsTtyOnVolteEnabled != null) { + return mIsTtyOnVolteEnabled; + } + return super.isTtyOnVolteEnabled(subId); + } + + + public void setIsEnabledByPlatform(boolean isEnabled) { + mIsEnabledOnPlatform = isEnabled; + } + + @Override + boolean isEnabledByPlatform(int subId) throws InterruptedException, ImsException, + IllegalArgumentException { + if (mIsEnabledOnPlatform != null) { + return mIsEnabledOnPlatform; + } + return super.isEnabledByPlatform(subId); + } + + public void setIsProvisionedOnDevice(boolean isProvisioned) { + mIsProvisionedOnDevice = isProvisioned; + } + + @Override + boolean isProvisionedOnDevice(int subId) { + if (mIsProvisionedOnDevice != null) { + return mIsProvisionedOnDevice; + } + return super.isProvisionedOnDevice(subId); + } + + public void setServiceStateReady(boolean isReady) { + mIsServiceStateReady = isReady; + } + + @Override + boolean isServiceStateReady(int subId) throws InterruptedException, ImsException, + IllegalArgumentException { + if (mIsServiceStateReady != null) { + return mIsServiceStateReady; + } + return super.isServiceStateReady(subId); + } + + public void setIsEnabledByUser(boolean enabled) { + mIsEnabledByUser = enabled; + } + + @Override + boolean isEnabledByUser(int subId) { + if (mIsEnabledByUser != null) { + return mIsEnabledByUser; + } + return super.isEnabledByUser(subId); + } + +} diff --git a/tests/robotests/src/com/android/settings/nfc/NfcDetectionPointControllerTest.java b/tests/unit/src/com/android/settings/nfc/NfcDetectionPointControllerTest.java similarity index 84% rename from tests/robotests/src/com/android/settings/nfc/NfcDetectionPointControllerTest.java rename to tests/unit/src/com/android/settings/nfc/NfcDetectionPointControllerTest.java index 31ac7d67e02..3b9df6d1323 100644 --- a/tests/robotests/src/com/android/settings/nfc/NfcDetectionPointControllerTest.java +++ b/tests/unit/src/com/android/settings/nfc/NfcDetectionPointControllerTest.java @@ -18,20 +18,22 @@ package com.android.settings.nfc; import static com.google.common.truth.Truth.assertThat; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class NfcDetectionPointControllerTest { private NfcDetectionPointController mController; @Before public void setUp() { - mController = new NfcDetectionPointController(RuntimeEnvironment.application, "fakeKey"); + mController = new NfcDetectionPointController(ApplicationProvider.getApplicationContext(), + "fakeKey"); } @Test diff --git a/tests/robotests/src/com/android/settings/nfc/SecureNfcPreferenceControllerTest.java b/tests/unit/src/com/android/settings/nfc/SecureNfcPreferenceControllerTest.java similarity index 82% rename from tests/robotests/src/com/android/settings/nfc/SecureNfcPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/nfc/SecureNfcPreferenceControllerTest.java index 56f012acfd0..c05e208225d 100644 --- a/tests/robotests/src/com/android/settings/nfc/SecureNfcPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/nfc/SecureNfcPreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 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. @@ -20,13 +20,14 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class SecureNfcPreferenceControllerTest { private Context mContext; @@ -34,7 +35,7 @@ public class SecureNfcPreferenceControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mController = new SecureNfcPreferenceController(mContext, "nfc_secure_settings"); } diff --git a/tests/unit/src/com/android/settings/notification/zen/ZenRuleCustomPrefContrTestBase.java b/tests/unit/src/com/android/settings/notification/zen/ZenRuleCustomPrefContrTestBase.java new file mode 100644 index 00000000000..53ad7c5995e --- /dev/null +++ b/tests/unit/src/com/android/settings/notification/zen/ZenRuleCustomPrefContrTestBase.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 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.zen; + +import android.app.AutomaticZenRule; +import android.app.NotificationManager; +import android.service.notification.ZenPolicy; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +abstract class ZenRuleCustomPrefContrTestBase { + public static final String RULE_ID = "test_rule_id"; + public static final String PREF_KEY = "main_pref"; + + AutomaticZenRule mRule = new AutomaticZenRule("test", null, null, null, null, + NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); + + abstract AbstractZenCustomRulePreferenceController getController(); + + void updateControllerZenPolicy(ZenPolicy policy) { + mRule.setZenPolicy(policy); + getController().onResume(mRule, RULE_ID); + } +} diff --git a/tests/unit/src/com/android/settings/panel/FakePanelContent.java b/tests/unit/src/com/android/settings/panel/FakePanelContent.java new file mode 100644 index 00000000000..f64d2f2972c --- /dev/null +++ b/tests/unit/src/com/android/settings/panel/FakePanelContent.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2020 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.panel; + +import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI; + +import android.app.settings.SettingsEnums; +import android.content.Intent; +import android.net.Uri; + +import androidx.core.graphics.drawable.IconCompat; + +import java.util.Arrays; +import java.util.List; + +/** + * Fake PanelContent for testing. + */ +public class FakePanelContent implements PanelContent { + + public static final String FAKE_ACTION = "fake_action"; + + public static final CharSequence TITLE = "title"; + + public static final List SLICE_URIS = Arrays.asList( + WIFI_SLICE_URI + ); + + public static final Intent INTENT = new Intent(); + + private CharSequence mTitle = TITLE; + private CharSequence mSubTitle; + private IconCompat mIcon; + private int mViewType; + private boolean mIsCustomizedButtonUsed = false; + private CharSequence mCustomizedButtonTitle; + + @Override + public IconCompat getIcon() { + return mIcon; + } + + public void setIcon(IconCompat icon) { + mIcon = icon; + } + + @Override + public CharSequence getSubTitle() { + return mSubTitle; + } + + public void setSubTitle(CharSequence subTitle) { + mSubTitle = subTitle; + } + + @Override + public CharSequence getTitle() { + return mTitle; + } + + public void setTitle(CharSequence title) { + mTitle = title; + } + + @Override + public List getSlices() { + return SLICE_URIS; + } + + @Override + public Intent getSeeMoreIntent() { + return INTENT; + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.TESTING; + } + + public void setViewType(int viewType) { + mViewType = viewType; + } + + @Override + public int getViewType() { + return mViewType; + } + + @Override + public boolean isCustomizedButtonUsed() { + return mIsCustomizedButtonUsed; + } + + public void setIsCustomizedButtonUsed(boolean isUsed) { + mIsCustomizedButtonUsed = isUsed; + } + + @Override + public CharSequence getCustomizedButtonTitle() { + return mCustomizedButtonTitle; + } + + public void setCustomizedButtonTitle(CharSequence title) { + mCustomizedButtonTitle = title; + } +} diff --git a/tests/unit/src/com/android/settings/panel/FakeSettingsPanelActivity.java b/tests/unit/src/com/android/settings/panel/FakeSettingsPanelActivity.java new file mode 100644 index 00000000000..7e1275e9478 --- /dev/null +++ b/tests/unit/src/com/android/settings/panel/FakeSettingsPanelActivity.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2020 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.panel; + +import android.content.ComponentName; +import android.content.Intent; + +public class FakeSettingsPanelActivity extends SettingsPanelActivity { + @Override + public ComponentName getCallingActivity() { + return new ComponentName("fake-package", "fake-class"); + } + + @Override + public Intent getIntent() { + final Intent intent = new Intent(FakePanelContent.FAKE_ACTION); + return intent; + } +} diff --git a/tests/robotests/src/com/android/settings/panel/NfcPanelTest.java b/tests/unit/src/com/android/settings/panel/NfcPanelTest.java similarity index 82% rename from tests/robotests/src/com/android/settings/panel/NfcPanelTest.java rename to tests/unit/src/com/android/settings/panel/NfcPanelTest.java index 1de2c5aa6dd..60adfdd1bcb 100644 --- a/tests/robotests/src/com/android/settings/panel/NfcPanelTest.java +++ b/tests/unit/src/com/android/settings/panel/NfcPanelTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 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. @@ -20,25 +20,25 @@ import static com.google.common.truth.Truth.assertThat; import android.net.Uri; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.slices.CustomSliceRegistry; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - import java.util.List; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class NfcPanelTest { private NfcPanel mPanel; @Before public void setUp() { - mPanel = NfcPanel.create(RuntimeEnvironment.application); + mPanel = NfcPanel.create(ApplicationProvider.getApplicationContext()); } @Test diff --git a/tests/robotests/src/com/android/settings/panel/PanelFeatureProviderImplTest.java b/tests/unit/src/com/android/settings/panel/PanelFeatureProviderImplTest.java similarity index 89% rename from tests/robotests/src/com/android/settings/panel/PanelFeatureProviderImplTest.java rename to tests/unit/src/com/android/settings/panel/PanelFeatureProviderImplTest.java index f924d7a01d2..3b61a734af1 100644 --- a/tests/robotests/src/com/android/settings/panel/PanelFeatureProviderImplTest.java +++ b/tests/unit/src/com/android/settings/panel/PanelFeatureProviderImplTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -12,9 +12,7 @@ * 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.panel; import static com.android.settings.panel.SettingsPanelActivity.KEY_MEDIA_PACKAGE_NAME; @@ -26,13 +24,14 @@ import android.content.Context; import android.os.Bundle; import android.provider.Settings; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class PanelFeatureProviderImplTest { private static final String TEST_PACKAGENAME = "com.test.packagename"; @@ -43,7 +42,7 @@ public class PanelFeatureProviderImplTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mProvider = new PanelFeatureProviderImpl(); mBundle = new Bundle(); mBundle.putString(KEY_MEDIA_PACKAGE_NAME, TEST_PACKAGENAME); diff --git a/tests/robotests/src/com/android/settings/panel/PanelSlicesLoaderCountdownLatchTest.java b/tests/unit/src/com/android/settings/panel/PanelSlicesLoaderCountdownLatchTest.java similarity index 91% rename from tests/robotests/src/com/android/settings/panel/PanelSlicesLoaderCountdownLatchTest.java rename to tests/unit/src/com/android/settings/panel/PanelSlicesLoaderCountdownLatchTest.java index dd8a91faec0..3794e00ea10 100644 --- a/tests/robotests/src/com/android/settings/panel/PanelSlicesLoaderCountdownLatchTest.java +++ b/tests/unit/src/com/android/settings/panel/PanelSlicesLoaderCountdownLatchTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 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. @@ -22,14 +22,14 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.net.Uri; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class PanelSlicesLoaderCountdownLatchTest { private Context mContext; @@ -43,7 +43,7 @@ public class PanelSlicesLoaderCountdownLatchTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mSliceCountdownLatch = new PanelSlicesLoaderCountdownLatch(URIS.length); } @@ -89,4 +89,4 @@ public class PanelSlicesLoaderCountdownLatchTest { // Verify the second call returns false without external state change assertThat(mSliceCountdownLatch.isPanelReadyToLoad()).isFalse(); } -} \ No newline at end of file +} diff --git a/tests/robotests/src/com/android/settings/panel/WifiPanelTest.java b/tests/unit/src/com/android/settings/panel/WifiPanelTest.java similarity index 82% rename from tests/robotests/src/com/android/settings/panel/WifiPanelTest.java rename to tests/unit/src/com/android/settings/panel/WifiPanelTest.java index 08db23e9399..b03075e69f0 100644 --- a/tests/robotests/src/com/android/settings/panel/WifiPanelTest.java +++ b/tests/unit/src/com/android/settings/panel/WifiPanelTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2020 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. @@ -20,24 +20,25 @@ import static com.google.common.truth.Truth.assertThat; import android.net.Uri; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.slices.CustomSliceRegistry; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import java.util.List; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class WifiPanelTest { private WifiPanel mPanel; @Before public void setUp() { - mPanel = WifiPanel.create(RuntimeEnvironment.application); + mPanel = WifiPanel.create(ApplicationProvider.getApplicationContext()); } @Test diff --git a/tests/robotests/src/com/android/settings/password/ScreenLockTypeTest.java b/tests/unit/src/com/android/settings/password/ScreenLockTypeTest.java similarity index 93% rename from tests/robotests/src/com/android/settings/password/ScreenLockTypeTest.java rename to tests/unit/src/com/android/settings/password/ScreenLockTypeTest.java index 05c3f644287..f05e57676bd 100644 --- a/tests/robotests/src/com/android/settings/password/ScreenLockTypeTest.java +++ b/tests/unit/src/com/android/settings/password/ScreenLockTypeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2020 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,20 +11,20 @@ * 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.password; import static com.google.common.truth.Truth.assertThat; import android.app.admin.DevicePolicyManager; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class ScreenLockTypeTest { @Test diff --git a/tests/robotests/src/com/android/settings/search/CustomSiteMapRegistryTest.java b/tests/unit/src/com/android/settings/search/CustomSiteMapRegistryTest.java similarity index 98% rename from tests/robotests/src/com/android/settings/search/CustomSiteMapRegistryTest.java rename to tests/unit/src/com/android/settings/search/CustomSiteMapRegistryTest.java index 181821b85bb..1a4737b2876 100644 --- a/tests/robotests/src/com/android/settings/search/CustomSiteMapRegistryTest.java +++ b/tests/unit/src/com/android/settings/search/CustomSiteMapRegistryTest.java @@ -18,6 +18,8 @@ package com.android.settings.search; import static com.google.common.truth.Truth.assertThat; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.DisplaySettings; import com.android.settings.backup.UserBackupSettingsActivity; import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment; @@ -39,9 +41,8 @@ import com.android.settings.wifi.WifiSettings; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class CustomSiteMapRegistryTest { @Test diff --git a/tests/unit/src/com/android/settings/search/DatabaseIndexingUtils.java b/tests/unit/src/com/android/settings/search/DatabaseIndexingUtils.java new file mode 100644 index 00000000000..42eb45b7fa7 --- /dev/null +++ b/tests/unit/src/com/android/settings/search/DatabaseIndexingUtils.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 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.search; + +import android.util.Log; + +import com.android.settingslib.search.Indexable; + +import java.lang.reflect.Field; + +/** + * Utility class for {@like DatabaseIndexingManager} to handle the mapping between Payloads + * and Preference controllers, and managing indexable classes. + */ +public class DatabaseIndexingUtils { + + private static final String TAG = "IndexingUtil"; + + public static final String FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER = + "SEARCH_INDEX_DATA_PROVIDER"; + + public static Indexable.SearchIndexProvider getSearchIndexProvider(final Class clazz) { + try { + final Field f = clazz.getField(FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER); + return (Indexable.SearchIndexProvider) f.get(null); + } catch (NoSuchFieldException e) { + Log.d(TAG, "Cannot find field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); + } catch (SecurityException se) { + Log.d(TAG, + "Security exception for field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); + } catch (IllegalAccessException e) { + Log.d(TAG, "Illegal access to field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); + } catch (IllegalArgumentException e) { + Log.d(TAG, "Illegal argument when accessing field '" + + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); + } + return null; + } +} diff --git a/tests/unit/src/com/android/settings/search/FakeSettingsFragment.java b/tests/unit/src/com/android/settings/search/FakeSettingsFragment.java new file mode 100644 index 00000000000..6dbb7fb982c --- /dev/null +++ b/tests/unit/src/com/android/settings/search/FakeSettingsFragment.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2020 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.search; + +import android.content.Context; +import android.provider.SearchIndexableResource; + +import com.android.internal.logging.nano.MetricsProto; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settingslib.core.AbstractPreferenceController; +import com.android.settingslib.search.SearchIndexableRaw; + +import java.util.ArrayList; +import java.util.List; + +/** + * Test class for Settings Search Indexing. + * If you change this class, please run robotests to make sure they still pass. + */ +public class FakeSettingsFragment extends DashboardFragment { + + public static final String TITLE = "raw title"; + public static final String SUMMARY_ON = "raw summary on"; + public static final String SUMMARY_OFF = "raw summary off"; + public static final String ENTRIES = "rawentries"; + public static final String KEYWORDS = "keywords, keywordss, keywordsss"; + public static final String SPACE_KEYWORDS = "keywords keywordss keywordsss"; + public static final String SCREEN_TITLE = "raw screen title"; + public static final String CLASS_NAME = FakeSettingsFragment.class.getName(); + public static final int ICON = 0xff; + public static final String INTENT_ACTION = "raw action"; + public static final String PACKAGE_NAME = "raw target package"; + public static final String TARGET_CLASS = "raw target class"; + public static final String TARGET_PACKAGE = "raw package name"; + public static final String KEY = "raw key"; + public static final boolean ENABLED = true; + + + @Override + public int getMetricsCategory() { + return MetricsProto.MetricsEvent.DISPLAY; + } + + @Override + protected String getLogTag() { + return ""; + } + + @Override + protected int getPreferenceScreenResId() { + return com.android.settings.R.xml.display_settings; + } + + @Override + protected List createPreferenceControllers(Context context) { + return null; + } + + /** Index provider used to expose this fragment in search. */ + public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + @Override + public List getRawDataToIndex(Context context, + boolean enabled) { + final SearchIndexableRaw data = new SearchIndexableRaw(context); + data.title = TITLE; + data.summaryOn = SUMMARY_ON; + data.summaryOff = SUMMARY_OFF; + data.entries = ENTRIES; + data.keywords = KEYWORDS; + data.screenTitle = SCREEN_TITLE; + data.packageName = PACKAGE_NAME; + data.intentAction = INTENT_ACTION; + data.intentTargetClass = TARGET_CLASS; + data.intentTargetPackage = TARGET_PACKAGE; + data.key = KEY; + data.iconResId = ICON; + data.enabled = ENABLED; + + final List result = new ArrayList<>(1); + result.add(data); + return result; + } + + @Override + public List getXmlResourcesToIndex(Context context, + boolean enabled) { + final ArrayList result = new ArrayList<>(); + + final SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = com.android.settings.R.xml.display_settings; + result.add(sir); + return result; + } + + @Override + public List getNonIndexableKeys(Context context) { + List keys = super.getNonIndexableKeys(context); + keys.add("pref_key_1"); + keys.add("pref_key_3"); + return keys; + } + }; +} diff --git a/tests/unit/src/com/android/settings/search/SearchIndexProviderCodeInspector.java b/tests/unit/src/com/android/settings/search/SearchIndexProviderCodeInspector.java new file mode 100644 index 00000000000..bc5b41ffcbc --- /dev/null +++ b/tests/unit/src/com/android/settings/search/SearchIndexProviderCodeInspector.java @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2020 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.search; + +import static com.google.common.truth.Truth.assertWithMessage; + +import android.provider.SearchIndexableResource; +import android.util.ArraySet; +import android.util.Log; + +import androidx.test.core.app.ApplicationProvider; + +import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.core.codeinspection.CodeInspector; +import com.android.settings.dashboard.DashboardFragmentSearchIndexProviderInspector; +import com.android.settingslib.search.Indexable; +import com.android.settingslib.search.SearchIndexableData; +import com.android.settingslib.search.SearchIndexableResources; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * {@link CodeInspector} to ensure fragments implement search components correctly. + */ +public class SearchIndexProviderCodeInspector extends CodeInspector { + private static final String TAG = "SearchCodeInspector"; + + private static final String NOT_CONTAINING_PROVIDER_OBJECT_ERROR = + "Indexable should have public field " + + DatabaseIndexingUtils.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + + " but these are not:\n"; + private static final String NOT_SHARING_PREF_CONTROLLERS_BETWEEN_FRAG_AND_PROVIDER = + "DashboardFragment should share pref controllers with its SearchIndexProvider, but " + + " these are not: \n"; + private static final String NOT_IN_INDEXABLE_PROVIDER_REGISTRY = + "Class containing " + DatabaseIndexingUtils.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + + " must be added to " + SearchIndexableResources.class.getName() + + " but these are not: \n"; + private static final String NOT_PROVIDING_VALID_RESOURCE_ERROR = + "SearchIndexableProvider must either provide no resource to index, or valid ones. " + + "But the followings contain resource with xml id = 0\n"; + + private final List mNotImplementingIndexProviderExemptList; + private final List mNotInSearchIndexableRegistryExemptList; + private final List mNotSharingPrefControllersExemptList; + + public SearchIndexProviderCodeInspector(List> classes) { + super(classes); + mNotImplementingIndexProviderExemptList = new ArrayList<>(); + mNotInSearchIndexableRegistryExemptList = new ArrayList<>(); + mNotSharingPrefControllersExemptList = new ArrayList<>(); + initializeExemptList(mNotImplementingIndexProviderExemptList, + "exempt_not_implementing_index_provider"); + initializeExemptList(mNotInSearchIndexableRegistryExemptList, + "exempt_not_in_search_index_provider_registry"); + initializeExemptList(mNotSharingPrefControllersExemptList, + "exempt_not_sharing_pref_controllers_with_search_provider"); + } + + @Override + public void run() { + final Set notImplementingIndexProvider = new ArraySet<>(); + final Set notInSearchProviderRegistry = new ArraySet<>(); + final Set notSharingPreferenceControllers = new ArraySet<>(); + final Set notProvidingValidResource = new ArraySet<>(); + final Set providerClasses = new ArraySet<>(); + + final SearchFeatureProvider provider = new SearchFeatureProviderImpl(); + for (SearchIndexableData bundle : + provider.getSearchIndexableResources().getProviderValues()) { + providerClasses.add(bundle.getTargetClass()); + } + + for (Class clazz : mClasses) { + if (!isConcreteSettingsClass(clazz)) { + continue; + } + final String className = clazz.getName(); + // Skip fragments if it's not SettingsPreferenceFragment. + if (!SettingsPreferenceFragment.class.isAssignableFrom(clazz)) { + continue; + } + final boolean hasSearchIndexProvider = hasSearchIndexProvider(clazz); + // If it implements Indexable, it must also implement the index provider field. + if (!hasSearchIndexProvider) { + if (!mNotImplementingIndexProviderExemptList.remove(className)) { + notImplementingIndexProvider.add(className); + } + continue; + } + // If it implements index provider field AND it's a DashboardFragment, its fragment and + // search provider must share the same set of PreferenceControllers. + final boolean isSharingPrefControllers = DashboardFragmentSearchIndexProviderInspector + .isSharingPreferenceControllers(clazz); + if (!isSharingPrefControllers) { + if (!mNotSharingPrefControllersExemptList.remove(className)) { + notSharingPreferenceControllers.add(className); + } + continue; + } + // Must be in SearchProviderRegistry + if (!providerClasses.contains(clazz)) { + if (!mNotInSearchIndexableRegistryExemptList.remove(className)) { + notInSearchProviderRegistry.add(className); + } + } + // Search provider must either don't provider resource xml, or provide valid ones. + if (!hasValidResourceFromProvider(clazz)) { + notProvidingValidResource.add(className); + } + } + + // Build error messages + final String indexProviderError = buildErrorMessage(NOT_CONTAINING_PROVIDER_OBJECT_ERROR, + notImplementingIndexProvider); + final String notSharingPrefControllerError = buildErrorMessage( + NOT_SHARING_PREF_CONTROLLERS_BETWEEN_FRAG_AND_PROVIDER, + notSharingPreferenceControllers); + final String notInProviderRegistryError = + buildErrorMessage(NOT_IN_INDEXABLE_PROVIDER_REGISTRY, notInSearchProviderRegistry); + final String notProvidingValidResourceError = buildErrorMessage( + NOT_PROVIDING_VALID_RESOURCE_ERROR, notProvidingValidResource); + assertWithMessage(indexProviderError) + .that(notImplementingIndexProvider) + .isEmpty(); + assertWithMessage(notSharingPrefControllerError) + .that(notSharingPreferenceControllers) + .isEmpty(); + assertWithMessage(notInProviderRegistryError) + .that(notInSearchProviderRegistry) + .isEmpty(); + assertWithMessage(notProvidingValidResourceError) + .that(notProvidingValidResource) + .isEmpty(); + assertNoObsoleteInExemptList("exempt_not_implementing_index_provider", + mNotImplementingIndexProviderExemptList); + assertNoObsoleteInExemptList("exempt_not_in_search_index_provider_registry", + mNotInSearchIndexableRegistryExemptList); + assertNoObsoleteInExemptList( + "exempt_not_sharing_pref_controllers_with_search_provider", + mNotSharingPrefControllersExemptList); + } + + private boolean hasSearchIndexProvider(Class clazz) { + try { + final Field f = clazz.getField( + DatabaseIndexingUtils.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER); + return f != null; + } catch (NoClassDefFoundError e) { + // Cannot find class def, ignore + return true; + } catch (NoSuchFieldException e) { + Log.e(TAG, "error fetching search provider from class " + clazz.getName()); + return false; + } + } + + private boolean hasValidResourceFromProvider(Class clazz) { + try { + final Indexable.SearchIndexProvider provider = + DatabaseIndexingUtils.getSearchIndexProvider(clazz); + final List resources = provider.getXmlResourcesToIndex( + ApplicationProvider.getApplicationContext(), true /* enabled */); + if (resources == null) { + // No resource, that's fine. + return true; + } + for (SearchIndexableResource res : resources) { + if (res.xmlResId == 0) { + // Invalid resource + return false; + } + } + } catch (Exception e) { + // Ignore. + } + return true; + } + + private String buildErrorMessage(String errorSummary, Set errorClasses) { + final StringBuilder error = new StringBuilder(errorSummary); + for (String c : errorClasses) { + error.append(c).append("\n"); + } + return error.toString(); + } +} diff --git a/tests/robotests/src/com/android/settings/security/CredentialManagementAppButtonsControllerTest.java b/tests/unit/src/com/android/settings/security/CredentialManagementAppButtonsControllerTest.java similarity index 88% rename from tests/robotests/src/com/android/settings/security/CredentialManagementAppButtonsControllerTest.java rename to tests/unit/src/com/android/settings/security/CredentialManagementAppButtonsControllerTest.java index ecc2f2dd1ca..bbe9e359616 100644 --- a/tests/robotests/src/com/android/settings/security/CredentialManagementAppButtonsControllerTest.java +++ b/tests/unit/src/com/android/settings/security/CredentialManagementAppButtonsControllerTest.java @@ -20,15 +20,16 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.core.BasePreferenceController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class CredentialManagementAppButtonsControllerTest { private Context mContext; @@ -38,7 +39,7 @@ public class CredentialManagementAppButtonsControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mController = new CredentialManagementAppButtonsController( mContext, PREF_KEY_CREDENTIAL_MANAGEMENT_APP); } diff --git a/tests/robotests/src/com/android/settings/security/CredentialManagementAppHeaderControllerTest.java b/tests/unit/src/com/android/settings/security/CredentialManagementAppHeaderControllerTest.java similarity index 88% rename from tests/robotests/src/com/android/settings/security/CredentialManagementAppHeaderControllerTest.java rename to tests/unit/src/com/android/settings/security/CredentialManagementAppHeaderControllerTest.java index e77e4c18152..35470a77369 100644 --- a/tests/robotests/src/com/android/settings/security/CredentialManagementAppHeaderControllerTest.java +++ b/tests/unit/src/com/android/settings/security/CredentialManagementAppHeaderControllerTest.java @@ -20,15 +20,16 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settings.core.BasePreferenceController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class CredentialManagementAppHeaderControllerTest { private Context mContext; @@ -38,7 +39,7 @@ public class CredentialManagementAppHeaderControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mController = new CredentialManagementAppHeaderController( mContext, PREF_KEY_CREDENTIAL_MANAGEMENT_APP); } diff --git a/tests/unit/src/com/android/settings/slices/FakeContextOnlyPreferenceController.java b/tests/unit/src/com/android/settings/slices/FakeContextOnlyPreferenceController.java new file mode 100644 index 00000000000..78587a0d51d --- /dev/null +++ b/tests/unit/src/com/android/settings/slices/FakeContextOnlyPreferenceController.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2020 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.slices; + +import android.content.Context; + +import com.android.settings.core.BasePreferenceController; + +public class FakeContextOnlyPreferenceController extends BasePreferenceController { + + public static final String KEY = "fakeController2"; + + public FakeContextOnlyPreferenceController(Context context) { + super(context, KEY); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } +} diff --git a/tests/unit/src/com/android/settings/slices/FakePreferenceController.java b/tests/unit/src/com/android/settings/slices/FakePreferenceController.java new file mode 100644 index 00000000000..f543893ff16 --- /dev/null +++ b/tests/unit/src/com/android/settings/slices/FakePreferenceController.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 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.slices; + +import android.content.Context; + +import com.android.settings.core.BasePreferenceController; + +public class FakePreferenceController extends BasePreferenceController { + + public FakePreferenceController(Context context, String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public int getSliceType() { + return SliceData.SliceType.SLIDER; + } + + @Override + public boolean isSliceable() { + return true; + } + + @Override + public boolean isPublicSlice() { + return true; + } + + @Override + public boolean useDynamicSliceSummary() { + return true; + } +} diff --git a/tests/unit/src/com/android/settings/slices/SliceControllerInXmlCodeInspector.java b/tests/unit/src/com/android/settings/slices/SliceControllerInXmlCodeInspector.java new file mode 100644 index 00000000000..ce8338c3f42 --- /dev/null +++ b/tests/unit/src/com/android/settings/slices/SliceControllerInXmlCodeInspector.java @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2020 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.slices; + +import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_CONTROLLER; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import android.content.Context; +import android.os.Bundle; +import android.provider.SearchIndexableResource; +import android.text.TextUtils; + +import androidx.test.core.app.ApplicationProvider; + +import com.android.settings.core.PreferenceXmlParserUtils; +import com.android.settings.core.SliderPreferenceController; +import com.android.settings.core.TogglePreferenceController; +import com.android.settings.core.codeinspection.CodeInspector; +import com.android.settings.overlay.FeatureFactory; +import com.android.settings.search.SearchFeatureProvider; +import com.android.settings.search.SearchFeatureProviderImpl; +import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settingslib.search.Indexable; +import com.android.settingslib.search.SearchIndexableData; + +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +public class SliceControllerInXmlCodeInspector extends CodeInspector { + + private static final List sSliceControllerClasses = Arrays.asList( + TogglePreferenceController.class, + SliderPreferenceController.class + ); + + private final List mXmlDeclaredControllers = new ArrayList<>(); + private final List mExemptedClasses = new ArrayList<>(); + + private static final String ERROR_MISSING_CONTROLLER = + "The following controllers were expected to be declared by " + + "'settings:controller=Controller_Class_Name' in their corresponding Xml. " + + "If it should not appear in XML, add the controller's classname to " + + "exempt_slice_controller_not_in_xml. Controllers:\n"; + + private final Context mContext; + private final SearchFeatureProvider mSearchProvider; + private final FakeFeatureFactory mFakeFeatureFactory; + + public SliceControllerInXmlCodeInspector(List> classes) throws Exception { + super(classes); + mContext = ApplicationProvider.getApplicationContext(); + mSearchProvider = new SearchFeatureProviderImpl(); + mFakeFeatureFactory = FakeFeatureFactory.setupForTest(); + mFakeFeatureFactory.searchFeatureProvider = mSearchProvider; + + CodeInspector.initializeExemptList(mExemptedClasses, + "exempt_slice_controller_not_in_xml"); + initDeclaredControllers(); + } + + private void initDeclaredControllers() throws IOException, XmlPullParserException { + final List xmlResources = getIndexableXml(); + for (int xmlResId : xmlResources) { + final List metadata = PreferenceXmlParserUtils.extractMetadata(mContext, + xmlResId, PreferenceXmlParserUtils.MetadataFlag.FLAG_NEED_PREF_CONTROLLER); + for (Bundle bundle : metadata) { + final String controllerClassName = bundle.getString(METADATA_CONTROLLER); + if (TextUtils.isEmpty(controllerClassName)) { + continue; + } + mXmlDeclaredControllers.add(controllerClassName); + } + } + // We definitely have some controllers in xml, so assert not-empty here as a proxy to + // make sure the parser didn't fail + assertThat(mXmlDeclaredControllers).isNotEmpty(); + } + + @Override + public void run() { + final List missingControllersInXml = new ArrayList<>(); + + for (Class clazz : mClasses) { + if (!isConcreteSettingsClass(clazz)) { + // Only care about non-abstract classes. + continue; + } + if (!isInlineSliceClass(clazz)) { + // Only care about inline-slice controller classes. + continue; + } + + if (!mXmlDeclaredControllers.contains(clazz.getName())) { + // Class clazz should have been declared in XML (unless allowlisted). + missingControllersInXml.add(clazz.getName()); + } + } + + // Removed allowlisted classes + missingControllersInXml.removeAll(mExemptedClasses); + + final String missingControllerError = + buildErrorMessage(ERROR_MISSING_CONTROLLER, missingControllersInXml); + + assertWithMessage(missingControllerError).that(missingControllersInXml).isEmpty(); + } + + private boolean isInlineSliceClass(Class clazz) { + while (clazz != null) { + clazz = clazz.getSuperclass(); + if (sSliceControllerClasses.contains(clazz)) { + return true; + } + } + return false; + } + + private String buildErrorMessage(String errorSummary, List errorClasses) { + final StringBuilder error = new StringBuilder(errorSummary); + for (String c : errorClasses) { + error.append(c).append("\n"); + } + return error.toString(); + } + + private List getIndexableXml() { + final List xmlResSet = new ArrayList<>(); + + final Collection bundles = FeatureFactory.getFactory( + mContext).getSearchFeatureProvider().getSearchIndexableResources() + .getProviderValues(); + + for (SearchIndexableData bundle : bundles) { + Indexable.SearchIndexProvider provider = bundle.getSearchIndexProvider(); + + if (provider == null) { + continue; + } + + List resources = provider.getXmlResourcesToIndex(mContext, + true); + + if (resources == null) { + continue; + } + + for (SearchIndexableResource resource : resources) { + // Add '0's anyway. It won't break the test. + xmlResSet.add(resource.xmlResId); + } + } + return xmlResSet; + } +} diff --git a/tests/robotests/src/com/android/settings/slices/SliceDataTest.java b/tests/unit/src/com/android/settings/slices/SliceDataTest.java similarity index 92% rename from tests/robotests/src/com/android/settings/slices/SliceDataTest.java rename to tests/unit/src/com/android/settings/slices/SliceDataTest.java index fa3f8b985c5..4d185446f48 100644 --- a/tests/robotests/src/com/android/settings/slices/SliceDataTest.java +++ b/tests/unit/src/com/android/settings/slices/SliceDataTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2020 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. @@ -20,24 +20,25 @@ import static com.google.common.truth.Truth.assertThat; import android.net.Uri; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class SliceDataTest { - private final String KEY = "KEY"; - private final String TITLE = "title"; - private final String SUMMARY = "summary"; - private final String SCREEN_TITLE = "screen title"; - private final String KEYWORDS = "a, b, c"; - private final String FRAGMENT_NAME = "fragment name"; - private final int ICON = 1234; // I declare a thumb war - private final Uri URI = Uri.parse("content://com.android.settings.slices/test"); - private final String PREF_CONTROLLER = "com.android.settings.slices.tester"; - private final int SLICE_TYPE = SliceData.SliceType.SWITCH; - private final String UNAVAILABLE_SLICE_SUBTITLE = "subtitleOfUnavailableSlice"; + private static final String KEY = "KEY"; + private static final String TITLE = "title"; + private static final String SUMMARY = "summary"; + private static final String SCREEN_TITLE = "screen title"; + private static final String KEYWORDS = "a, b, c"; + private static final String FRAGMENT_NAME = "fragment name"; + private static final int ICON = 1234; // I declare a thumb war + private static final Uri URI = Uri.parse("content://com.android.settings.slices/test"); + private static final String PREF_CONTROLLER = "com.android.settings.slices.tester"; + private static final int SLICE_TYPE = SliceData.SliceType.SWITCH; + private static final String UNAVAILABLE_SLICE_SUBTITLE = "subtitleOfUnavailableSlice"; @Test public void testBuilder_buildsMatchingObject() { diff --git a/tests/unit/src/com/android/settings/slices/SliceTestUtils.java b/tests/unit/src/com/android/settings/slices/SliceTestUtils.java new file mode 100644 index 00000000000..1b035cd57a7 --- /dev/null +++ b/tests/unit/src/com/android/settings/slices/SliceTestUtils.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2020 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.slices; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.net.Uri; +import android.provider.SettingsSlicesContract; + +import com.android.settings.testutils.FakeIndexProvider; +import com.android.settings.testutils.FakeToggleController; + +class SliceTestUtils { + + public static final String FAKE_TITLE = "title"; + public static final String FAKE_SUMMARY = "summary"; + public static final String FAKE_SCREEN_TITLE = "screen_title"; + public static final String FAKE_KEYWORDS = "a, b, c"; + public static final int FAKE_ICON = 1234; + public static final String FAKE_FRAGMENT_NAME = FakeIndexProvider.class.getName(); + public static final String FAKE_CONTROLLER_NAME = FakeToggleController.class.getName(); + + + public static void insertSliceToDb(Context context, String key) { + insertSliceToDb(context, key, true /* isPlatformSlice */); + } + + public static void insertSliceToDb(Context context, String key, boolean isPlatformSlice) { + insertSliceToDb(context, key, isPlatformSlice, null /*customizedUnavailableSliceSubtitle*/); + } + + public static void insertSliceToDb(Context context, String key, boolean isPlatformSlice, + String customizedUnavailableSliceSubtitle) { + insertSliceToDb(context, key, isPlatformSlice, customizedUnavailableSliceSubtitle, false); + } + + public static void insertSliceToDb(Context context, String key, boolean isPlatformSlice, + String customizedUnavailableSliceSubtitle, boolean isPublicSlice) { + final SQLiteDatabase db = SlicesDatabaseHelper.getInstance(context).getWritableDatabase(); + ContentValues values = new ContentValues(); + values.put(SlicesDatabaseHelper.IndexColumns.KEY, key); + values.put(SlicesDatabaseHelper.IndexColumns.SLICE_URI, + new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(isPlatformSlice + ? SettingsSlicesContract.AUTHORITY + : SettingsSliceProvider.SLICE_AUTHORITY) + .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION) + .appendPath(key) + .build().toSafeString()); + values.put(SlicesDatabaseHelper.IndexColumns.TITLE, FAKE_TITLE); + values.put(SlicesDatabaseHelper.IndexColumns.SUMMARY, FAKE_SUMMARY); + values.put(SlicesDatabaseHelper.IndexColumns.SCREENTITLE, FAKE_SCREEN_TITLE); + values.put(SlicesDatabaseHelper.IndexColumns.KEYWORDS, FAKE_KEYWORDS); + values.put(SlicesDatabaseHelper.IndexColumns.ICON_RESOURCE, FAKE_ICON); + values.put(SlicesDatabaseHelper.IndexColumns.FRAGMENT, FAKE_FRAGMENT_NAME); + values.put(SlicesDatabaseHelper.IndexColumns.CONTROLLER, FAKE_CONTROLLER_NAME); + values.put(SlicesDatabaseHelper.IndexColumns.SLICE_TYPE, SliceData.SliceType.INTENT); + values.put(SlicesDatabaseHelper.IndexColumns.UNAVAILABLE_SLICE_SUBTITLE, + customizedUnavailableSliceSubtitle); + values.put(SlicesDatabaseHelper.IndexColumns.PUBLIC_SLICE, isPublicSlice); + + db.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, values); + db.close(); + } +} diff --git a/tests/robotests/src/com/android/settings/slices/SpecialCaseSliceManagerTest.java b/tests/unit/src/com/android/settings/slices/SpecialCaseSliceManagerTest.java similarity index 89% rename from tests/robotests/src/com/android/settings/slices/SpecialCaseSliceManagerTest.java rename to tests/unit/src/com/android/settings/slices/SpecialCaseSliceManagerTest.java index d483f9e7842..4fcbd15d16e 100644 --- a/tests/robotests/src/com/android/settings/slices/SpecialCaseSliceManagerTest.java +++ b/tests/unit/src/com/android/settings/slices/SpecialCaseSliceManagerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -12,9 +12,7 @@ * 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.slices; import static com.google.common.truth.Truth.assertThat; @@ -27,24 +25,24 @@ import android.net.Uri; import android.provider.SettingsSlicesContract; import androidx.slice.Slice; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class SpecialCaseSliceManagerTest { - private final String FAKE_PARAMETER_KEY = "fake_parameter_key"; - private final String FAKE_PARAMETER_VALUE = "fake_value"; + private static final String FAKE_PARAMETER_KEY = "fake_parameter_key"; + private static final String FAKE_PARAMETER_VALUE = "fake_value"; private Context mContext; @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); CustomSliceRegistry.sUriToSlice.clear(); CustomSliceRegistry.sUriToSlice.put(FakeSliceable.URI, FakeSliceable.class); } @@ -113,7 +111,7 @@ public class SpecialCaseSliceManagerTest { static final Slice SLICE = new Slice.Builder(URI).build(); - static boolean backingData = false; + static boolean sBackingData = false; final Context mContext; @@ -133,7 +131,7 @@ public class SpecialCaseSliceManagerTest { @Override public void onNotifyChange(Intent intent) { - backingData = !backingData; + sBackingData = !sBackingData; } @Override diff --git a/tests/robotests/src/com/android/settings/sound/MediaControlsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/sound/MediaControlsPreferenceControllerTest.java similarity index 94% rename from tests/robotests/src/com/android/settings/sound/MediaControlsPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/sound/MediaControlsPreferenceControllerTest.java index f281e25e0b7..510928d99ff 100644 --- a/tests/robotests/src/com/android/settings/sound/MediaControlsPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/sound/MediaControlsPreferenceControllerTest.java @@ -26,14 +26,15 @@ import android.content.ContentResolver; import android.content.Context; import android.provider.Settings; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class MediaControlsPreferenceControllerTest { private static final String KEY = "media_controls_resume_switch"; @@ -46,7 +47,7 @@ public class MediaControlsPreferenceControllerTest { @Before public void setUp() { - mContext = spy(RuntimeEnvironment.application); + mContext = spy(ApplicationProvider.getApplicationContext()); mContentResolver = mContext.getContentResolver(); mOriginalQs = Settings.Global.getInt(mContentResolver, Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS, 1); diff --git a/tests/unit/src/com/android/settings/testutils/ApplicationTestUtils.java b/tests/unit/src/com/android/settings/testutils/ApplicationTestUtils.java new file mode 100644 index 00000000000..91f296f7fe7 --- /dev/null +++ b/tests/unit/src/com/android/settings/testutils/ApplicationTestUtils.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2020 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.testutils; + +import android.content.pm.ApplicationInfo; + +/** + * Helper for mocking installed applications. + */ +public class ApplicationTestUtils { + /** + * Create and populate an {@link android.content.pm.ApplicationInfo} object that describes an + * installed app. + * + * @param uid The app's uid + * @param packageName The app's package name. + * @param flags Flags describing the app. See {@link android.content.pm.ApplicationInfo#flags} + * for possible values. + * @param targetSdkVersion The app's target SDK version + * + * @see android.content.pm.ApplicationInfo + */ + public static ApplicationInfo buildInfo(int uid, String packageName, int flags, + int targetSdkVersion) { + final ApplicationInfo info = new ApplicationInfo(); + info.uid = uid; + info.packageName = packageName; + info.flags = flags; + info.targetSdkVersion = targetSdkVersion; + return info; + } +} diff --git a/tests/unit/src/com/android/settings/testutils/BatteryTestUtils.java b/tests/unit/src/com/android/settings/testutils/BatteryTestUtils.java new file mode 100644 index 00000000000..57bd3f51b05 --- /dev/null +++ b/tests/unit/src/com/android/settings/testutils/BatteryTestUtils.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 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.testutils; + +import android.content.Intent; +import android.os.BatteryManager; + +public class BatteryTestUtils { + + public static Intent getChargingIntent() { + return getCustomBatteryIntent( + BatteryManager.BATTERY_PLUGGED_AC, + 50 /* level */, + 100 /* scale */, + BatteryManager.BATTERY_STATUS_CHARGING); + } + + public static Intent getDischargingIntent() { + return getCustomBatteryIntent( + 0 /* plugged */, + 10 /* level */, + 100 /* scale */, + BatteryManager.BATTERY_STATUS_DISCHARGING); + } + + private static Intent getCustomBatteryIntent(int plugged, int level, int scale, int status) { + Intent intent = new Intent(); + intent.putExtra(BatteryManager.EXTRA_PLUGGED, plugged); + intent.putExtra(BatteryManager.EXTRA_LEVEL, level); + intent.putExtra(BatteryManager.EXTRA_SCALE, scale); + intent.putExtra(BatteryManager.EXTRA_STATUS, status); + + return intent; + } +} diff --git a/tests/unit/src/com/android/settings/testutils/CustomActivity.java b/tests/unit/src/com/android/settings/testutils/CustomActivity.java new file mode 100644 index 00000000000..89cdcfc5c51 --- /dev/null +++ b/tests/unit/src/com/android/settings/testutils/CustomActivity.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2020 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.testutils; + +import android.app.Activity; +import android.content.Intent; +import android.os.UserHandle; + +public class CustomActivity extends Activity { + @Override + public void startActivityAsUser(Intent intent, UserHandle user) {} +} diff --git a/tests/unit/src/com/android/settings/testutils/FakeCopyableController.java b/tests/unit/src/com/android/settings/testutils/FakeCopyableController.java new file mode 100644 index 00000000000..3bdbb54165d --- /dev/null +++ b/tests/unit/src/com/android/settings/testutils/FakeCopyableController.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 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.testutils; + +import android.content.Context; + +import com.android.settings.core.BasePreferenceController; + +public class FakeCopyableController extends BasePreferenceController { + + public FakeCopyableController(Context context, String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public boolean isSliceable() { + return true; + } + + @Override + public boolean isCopyableSlice() { + return true; + } +} diff --git a/tests/unit/src/com/android/settings/testutils/FakeIndexProvider.java b/tests/unit/src/com/android/settings/testutils/FakeIndexProvider.java new file mode 100644 index 00000000000..5cbfb5497f4 --- /dev/null +++ b/tests/unit/src/com/android/settings/testutils/FakeIndexProvider.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 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.testutils; + +import android.content.Context; + +import com.android.settings.R; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settingslib.search.Indexable; + +import java.util.List; + +public class FakeIndexProvider implements Indexable { + + public static final String KEY = "TestKey"; + + /** + * The fake SearchIndexProvider. Note that the use of location_settings below implies that tests + * using this should be using the res/xml-mcc999/location_settings.xml or + * res/xml-mcc998/location_settings.xml. Annotate tests with + * {@code @Config(qualifiers = "mcc999")}. + */ + public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider(R.xml.location_settings) { + + @Override + public List getNonIndexableKeys(Context context) { + List result = super.getNonIndexableKeys(context); + result.add(KEY); + return result; + } + }; +} diff --git a/tests/unit/src/com/android/settings/testutils/FakeInvalidSliderController.java b/tests/unit/src/com/android/settings/testutils/FakeInvalidSliderController.java new file mode 100644 index 00000000000..15d214dbc7c --- /dev/null +++ b/tests/unit/src/com/android/settings/testutils/FakeInvalidSliderController.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2020 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.testutils; + +import android.content.Context; + +public class FakeInvalidSliderController extends FakeSliderController { + + public FakeInvalidSliderController(Context context, String key) { + super(context, key); + } + + @Override + public int getMax() { + // Return 0 to make it invalid + return 0; + } +} diff --git a/tests/unit/src/com/android/settings/testutils/FakeSliderController.java b/tests/unit/src/com/android/settings/testutils/FakeSliderController.java new file mode 100644 index 00000000000..f8685fc8202 --- /dev/null +++ b/tests/unit/src/com/android/settings/testutils/FakeSliderController.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2020 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.testutils; + +import android.content.Context; +import android.provider.Settings; + +import com.android.settings.core.SliderPreferenceController; + +public class FakeSliderController extends SliderPreferenceController { + + public static final String AVAILABILITY_KEY = "fake_slider_availability_key"; + + public static final int MAX_VALUE = 9; + + private static final String SETTING_KEY = "fake_slider_key"; + + public FakeSliderController(Context context, String key) { + super(context, key); + } + + @Override + public int getSliderPosition() { + return Settings.System.getInt(mContext.getContentResolver(), SETTING_KEY, 0); + } + + @Override + public boolean setSliderPosition(int position) { + return Settings.System.putInt(mContext.getContentResolver(), SETTING_KEY, position); + } + + @Override + public int getMax() { + return MAX_VALUE; + } + + @Override + public int getMin() { + return 0; + } + + @Override + public int getAvailabilityStatus() { + return Settings.Global.getInt(mContext.getContentResolver(), AVAILABILITY_KEY, AVAILABLE); + } + + @Override + public boolean isSliceable() { + return true; + } +} diff --git a/tests/unit/src/com/android/settings/testutils/FakeToggleController.java b/tests/unit/src/com/android/settings/testutils/FakeToggleController.java new file mode 100644 index 00000000000..9eda8b6a802 --- /dev/null +++ b/tests/unit/src/com/android/settings/testutils/FakeToggleController.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2020 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.testutils; + +import android.content.Context; +import android.content.IntentFilter; +import android.net.Uri; +import android.net.wifi.WifiManager; +import android.provider.Settings; + +import com.android.settings.core.TogglePreferenceController; +import com.android.settings.slices.SliceBackgroundWorker; + +public class FakeToggleController extends TogglePreferenceController { + + public static final String AVAILABILITY_KEY = "fake_toggle_availability_key"; + + public static final IntentFilter INTENT_FILTER = new IntentFilter( + WifiManager.WIFI_AP_STATE_CHANGED_ACTION); + + private static final String SETTING_KEY = "toggle_key"; + + private static final int ON = 1; + private static final int OFF = 0; + + private boolean mIsAsyncUpdate = false; + + public FakeToggleController(Context context, String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public boolean isChecked() { + return Settings.System.getInt(mContext.getContentResolver(), + SETTING_KEY, OFF) == ON; + } + + @Override + public boolean setChecked(boolean isChecked) { + return Settings.System.putInt(mContext.getContentResolver(), SETTING_KEY, + isChecked ? ON : OFF); + } + + @Override + public int getAvailabilityStatus() { + return Settings.Global.getInt(mContext.getContentResolver(), + AVAILABILITY_KEY, AVAILABLE); + } + + @Override + public IntentFilter getIntentFilter() { + return INTENT_FILTER; + } + + @Override + public boolean isSliceable() { + return true; + } + + @Override + public Class getBackgroundWorkerClass() { + return TestWorker.class; + } + + @Override + public boolean hasAsyncUpdate() { + return mIsAsyncUpdate; + } + + public void setAsyncUpdate(boolean isAsyncUpdate) { + mIsAsyncUpdate = isAsyncUpdate; + } + + public static class TestWorker extends SliceBackgroundWorker { + + public TestWorker(Context context, Uri uri) { + super(context, uri); + } + + @Override + protected void onSlicePinned() { + } + + @Override + protected void onSliceUnpinned() { + } + + @Override + public void close() { + } + } +} diff --git a/tests/unit/src/com/android/settings/testutils/FakeUnavailablePreferenceController.java b/tests/unit/src/com/android/settings/testutils/FakeUnavailablePreferenceController.java new file mode 100644 index 00000000000..97379e3deff --- /dev/null +++ b/tests/unit/src/com/android/settings/testutils/FakeUnavailablePreferenceController.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 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.testutils; + +import android.content.Context; +import android.provider.Settings; + +import com.android.settings.core.BasePreferenceController; + +public class FakeUnavailablePreferenceController extends BasePreferenceController { + + public static final String AVAILABILITY_KEY = "fake_availability_key"; + + public FakeUnavailablePreferenceController(Context context) { + super(context, "key"); + } + + @Override + public int getAvailabilityStatus() { + return Settings.Global.getInt(mContext.getContentResolver(), AVAILABILITY_KEY, 0); + } + + @Override + public boolean isSliceable() { + return true; + } +} diff --git a/tests/unit/src/com/android/settings/testutils/ResolveInfoBuilder.java b/tests/unit/src/com/android/settings/testutils/ResolveInfoBuilder.java new file mode 100644 index 00000000000..5eaf2a4f42c --- /dev/null +++ b/tests/unit/src/com/android/settings/testutils/ResolveInfoBuilder.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2020 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.testutils; + +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.ProviderInfo; +import android.content.pm.ResolveInfo; + +import com.google.common.base.Preconditions; + +/** + * Helper for building {@link ResolveInfo}s to be used in Robolectric tests. + * + *

The resulting {@link PackageInfo}s should typically be added to {@link + * org.robolectric.shadows.ShadowPackageManager#addResolveInfoForIntent(Intent, ResolveInfo)}. + */ +public final class ResolveInfoBuilder { + + private final String mPackageName; + private ActivityInfo mActivityInfo; + private ProviderInfo mProviderInfo; + + public ResolveInfoBuilder(String packageName) { + this.mPackageName = Preconditions.checkNotNull(packageName); + } + + public ResolveInfoBuilder setActivity(String packageName, String className) { + mActivityInfo = new ActivityInfo(); + mActivityInfo.packageName = packageName; + mActivityInfo.name = className; + return this; + } + + public ResolveInfoBuilder setProvider( + String packageName, String className, String authority, boolean isSystemApp) { + mProviderInfo = new ProviderInfo(); + mProviderInfo.authority = authority; + mProviderInfo.applicationInfo = new ApplicationInfo(); + if (isSystemApp) { + mProviderInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; + } + mProviderInfo.packageName = mPackageName; + mProviderInfo.applicationInfo.packageName = mPackageName; + mProviderInfo.name = className; + return this; + } + + public ResolveInfo build() { + ResolveInfo info = new ResolveInfo(); + info.activityInfo = mActivityInfo; + info.resolvePackageName = mPackageName; + info.providerInfo = mProviderInfo; + return info; + } +} diff --git a/tests/unit/src/com/android/settings/testutils/SliceTester.java b/tests/unit/src/com/android/settings/testutils/SliceTester.java new file mode 100644 index 00000000000..be13e134b79 --- /dev/null +++ b/tests/unit/src/com/android/settings/testutils/SliceTester.java @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2020 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.testutils; + +import static android.app.slice.Slice.HINT_TITLE; +import static android.app.slice.Slice.SUBTYPE_COLOR; +import static android.app.slice.SliceItem.FORMAT_IMAGE; +import static android.app.slice.SliceItem.FORMAT_INT; +import static android.app.slice.SliceItem.FORMAT_TEXT; + +import static com.google.common.truth.Truth.assertThat; + +import android.app.PendingIntent; +import android.content.Context; +import android.text.TextUtils; + +import androidx.core.graphics.drawable.IconCompat; +import androidx.slice.Slice; +import androidx.slice.SliceItem; +import androidx.slice.SliceMetadata; +import androidx.slice.builders.ListBuilder; +import androidx.slice.core.SliceAction; +import androidx.slice.core.SliceQuery; +import androidx.slice.widget.EventInfo; + +import com.android.settings.Utils; +import com.android.settings.slices.SettingsSliceProvider; +import com.android.settings.slices.SliceBuilderUtils; +import com.android.settings.slices.SliceData; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Testing utility class to verify the contents of the different Settings Slices. + * + * TODO (77712944) check Summary, range (metadata.getRange()), toggle icons. + */ +public class SliceTester { + + /** + * Test the contents of an intent based slice, including: + * - No toggles + * - Correct intent + * - Correct title + * - Correct keywords + * - TTL + * - Color + */ + public static void testSettingsIntentSlice(Context context, Slice slice, SliceData sliceData) { + final SliceMetadata metadata = SliceMetadata.from(context, slice); + + final long sliceTTL = metadata.getExpiry(); + assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY); + + final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR); + final int color = colorItem.getInt(); + assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context)); + + final List toggles = metadata.getToggles(); + assertThat(toggles).isEmpty(); + + final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction(); + assertThat(primaryPendingIntent).isEqualTo( + SliceBuilderUtils.getContentPendingIntent(context, sliceData)); + + assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle()); + + assertKeywords(metadata, sliceData); + } + + /** + * Test the contents of an toggle based slice, including: + * - Contains one toggle + * - Correct toggle intent + * - Correct content intent + * - Correct title + * - Correct keywords + * - TTL + * - Color + */ + public static void testSettingsToggleSlice(Context context, Slice slice, SliceData sliceData) { + final SliceMetadata metadata = SliceMetadata.from(context, slice); + + final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR); + final int color = colorItem.getInt(); + assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context)); + + final List toggles = metadata.getToggles(); + assertThat(toggles).hasSize(1); + + final long sliceTTL = metadata.getExpiry(); + assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY); + + final SliceAction mainToggleAction = toggles.get(0); + + assertThat(mainToggleAction.getIcon()).isNull(); + + // Check intent in Toggle Action + final PendingIntent togglePendingIntent = mainToggleAction.getAction(); + assertThat(togglePendingIntent).isEqualTo(SliceBuilderUtils.getActionIntent(context, + SettingsSliceProvider.ACTION_TOGGLE_CHANGED, sliceData)); + + // Check primary intent + final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction(); + assertThat(primaryPendingIntent).isEqualTo( + SliceBuilderUtils.getContentPendingIntent(context, sliceData)); + + assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle()); + + assertKeywords(metadata, sliceData); + } + + /** + * Test the contents of an slider based slice, including: + * - No intent + * - Correct title + * - Correct keywords + * - TTL + * - Color + */ + public static void testSettingsSliderSlice(Context context, Slice slice, SliceData sliceData) { + final SliceMetadata metadata = SliceMetadata.from(context, slice); + final SliceAction primaryAction = metadata.getPrimaryAction(); + + final IconCompat icon = primaryAction.getIcon(); + if (icon == null) { + final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR); + final int color = colorItem.getInt(); + assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context)); + + } else { + final IconCompat expectedIcon = IconCompat.createWithResource(context, + sliceData.getIconResource()); + assertThat(expectedIcon.toString()).isEqualTo(icon.toString()); + } + + final long sliceTTL = metadata.getExpiry(); + assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY); + + final int headerType = metadata.getHeaderType(); + assertThat(headerType).isEqualTo(EventInfo.ROW_TYPE_SLIDER); + + // Check primary intent + final PendingIntent primaryPendingIntent = primaryAction.getAction(); + assertThat(primaryPendingIntent).isEqualTo( + SliceBuilderUtils.getContentPendingIntent(context, sliceData)); + + assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle()); + + assertKeywords(metadata, sliceData); + } + + /** + * Test the copyable slice, including: + * - No intent + * - Correct title + * - Correct intent + * - Correct keywords + * - TTL + * - Color + */ + public static void testSettingsCopyableSlice(Context context, Slice slice, + SliceData sliceData) { + final SliceMetadata metadata = SliceMetadata.from(context, slice); + + final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR); + final int color = colorItem.getInt(); + assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context)); + + final SliceAction primaryAction = metadata.getPrimaryAction(); + + final IconCompat expectedIcon = IconCompat.createWithResource(context, + sliceData.getIconResource()); + assertThat(expectedIcon.toString()).isEqualTo(primaryAction.getIcon().toString()); + + final long sliceTTL = metadata.getExpiry(); + assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY); + + // Check primary intent + final PendingIntent primaryPendingIntent = primaryAction.getAction(); + assertThat(primaryPendingIntent).isEqualTo( + SliceBuilderUtils.getContentPendingIntent(context, sliceData)); + + assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle()); + + assertKeywords(metadata, sliceData); + } + + /** + * Test the contents of an unavailable slice, including: + * - No toggles + * - Correct title + * - Correct intent + * - Correct keywords + * - Color + * - TTL + */ + public static void testSettingsUnavailableSlice(Context context, Slice slice, + SliceData sliceData) { + final SliceMetadata metadata = SliceMetadata.from(context, slice); + + final long sliceTTL = metadata.getExpiry(); + assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY); + + final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR); + final int color = colorItem.getInt(); + assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context)); + + final List toggles = metadata.getToggles(); + assertThat(toggles).isEmpty(); + + final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction(); + assertThat(primaryPendingIntent).isEqualTo(SliceBuilderUtils.getContentPendingIntent( + context, sliceData)); + + assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle()); + + assertKeywords(metadata, sliceData); + } + + /** + * Assert any slice item contains title. + * + * @param sliceItems All slice items of a Slice. + * @param title Title for asserting. + */ + public static void assertAnySliceItemContainsTitle(List sliceItems, String title) { + assertThat(hasText(sliceItems, title, HINT_TITLE)).isTrue(); + } + + /** + * Assert any slice item contains subtitle. + * + * @param sliceItems All slice items of a Slice. + * @param subtitle Subtitle for asserting. + */ + public static void assertAnySliceItemContainsSubtitle(List sliceItems, + String subtitle) { + // Subtitle has no hints + assertThat(hasText(sliceItems, subtitle, null /* hints */)).isTrue(); + } + + /** + * Assert no slice item contains subtitle. + * + * @param sliceItems All slice items of a Slice. + * @param subtitle Subtitle for asserting. + */ + public static void assertNoSliceItemContainsSubtitle(List sliceItems, + String subtitle) { + // Subtitle has no hints + assertThat(hasText(sliceItems, subtitle, null /* hints */)).isFalse(); + } + + private static boolean hasText(List sliceItems, String text, String hints) { + boolean hasText = false; + for (SliceItem item : sliceItems) { + List textItems = SliceQuery.findAll(item, FORMAT_TEXT, hints, + null /* non-hints */); + if (textItems == null) { + continue; + } + + for (SliceItem textItem : textItems) { + if (TextUtils.equals(textItem.getText(), text)) { + hasText = true; + break; + } + } + } + return hasText; + } + + /** + * Assert any slice item contains icon. + * + * @param sliceItems All slice items of a Slice. + * @param icon Icon for asserting. + */ + public static void assertAnySliceItemContainsIcon(List sliceItems, IconCompat icon) { + boolean hasIcon = false; + for (SliceItem item : sliceItems) { + List iconItems = SliceQuery.findAll(item, FORMAT_IMAGE, + (String) null /* hints */, null /* non-hints */); + if (iconItems == null) { + continue; + } + + for (SliceItem iconItem : iconItems) { + if (icon.toString().equals(iconItem.getIcon().toString())) { + hasIcon = true; + break; + } + } + } + assertThat(hasIcon).isTrue(); + } + + private static void assertKeywords(SliceMetadata metadata, SliceData data) { + final List keywords = metadata.getSliceKeywords(); + final Set expectedKeywords = Arrays.stream(data.getKeywords().split(",")) + .map(s -> s = s.trim()) + .collect(Collectors.toSet()); + expectedKeywords.add(data.getTitle()); + expectedKeywords.add(data.getScreenTitle().toString()); + assertThat(keywords).containsExactlyElementsIn(expectedKeywords); + } +} diff --git a/tests/unit/src/com/android/settings/testutils/XmlTestUtils.java b/tests/unit/src/com/android/settings/testutils/XmlTestUtils.java new file mode 100644 index 00000000000..5640beeb7da --- /dev/null +++ b/tests/unit/src/com/android/settings/testutils/XmlTestUtils.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2020 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.testutils; + +import static com.android.settings.core.PreferenceXmlParserUtils.METADATA_KEY; +import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag + .FLAG_INCLUDE_PREF_SCREEN; +import static com.android.settings.core.PreferenceXmlParserUtils.MetadataFlag.FLAG_NEED_KEY; + +import android.content.Context; +import android.os.Bundle; +import android.text.TextUtils; + +import com.android.settings.core.PreferenceXmlParserUtils; + +import org.xmlpull.v1.XmlPullParserException; + +import java.util.ArrayList; +import java.util.List; + +/** + * Util class for parsing XML + */ +public class XmlTestUtils { + + /** + * Parses a preference screen's xml, collects and returns all keys used by preferences + * on the screen. + * + * @param context of the preference screen. + * @param xmlId of the Preference Xml to be parsed. + * @return List of all keys in the preference Xml + */ + public static List getKeysFromPreferenceXml(Context context, int xmlId) { + final List keys = new ArrayList<>(); + try { + List metadata = PreferenceXmlParserUtils.extractMetadata(context, xmlId, + FLAG_NEED_KEY | FLAG_INCLUDE_PREF_SCREEN); + for (Bundle bundle : metadata) { + final String key = bundle.getString(METADATA_KEY); + if (!TextUtils.isEmpty(key)) { + keys.add(key); + } + } + } catch (java.io.IOException | XmlPullParserException e) { + return null; + } + + return keys; + } +} diff --git a/tests/robotests/src/com/android/settings/users/MultiUserTopIntroPreferenceControllerTest.java b/tests/unit/src/com/android/settings/users/MultiUserTopIntroPreferenceControllerTest.java similarity index 86% rename from tests/robotests/src/com/android/settings/users/MultiUserTopIntroPreferenceControllerTest.java rename to tests/unit/src/com/android/settings/users/MultiUserTopIntroPreferenceControllerTest.java index bc0b0604847..624750c7c73 100644 --- a/tests/robotests/src/com/android/settings/users/MultiUserTopIntroPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/users/MultiUserTopIntroPreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -23,15 +23,15 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) -@Ignore +@RunWith(AndroidJUnit4.class) public class MultiUserTopIntroPreferenceControllerTest { private Context mContext; @@ -39,10 +39,11 @@ public class MultiUserTopIntroPreferenceControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mController = new MultiUserTopIntroPreferenceController(mContext, "top_info"); } + @Ignore @Test public void getAvailabilityStatus_multiUserOff_shouldReturnEnabled() { mController.mUserCaps.mEnabled = true; @@ -51,6 +52,7 @@ public class MultiUserTopIntroPreferenceControllerTest { assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE); } + @Ignore @Test public void getAvailabilityStatus_multiUserOn_shouldReturnDisabled() { mController.mUserCaps.mEnabled = true; diff --git a/tests/robotests/src/com/android/settings/utils/LocalClassLoaderContextThemeWrapperTest.java b/tests/unit/src/com/android/settings/utils/LocalClassLoaderContextThemeWrapperTest.java similarity index 82% rename from tests/robotests/src/com/android/settings/utils/LocalClassLoaderContextThemeWrapperTest.java rename to tests/unit/src/com/android/settings/utils/LocalClassLoaderContextThemeWrapperTest.java index 5a176222566..3bafd50696b 100644 --- a/tests/robotests/src/com/android/settings/utils/LocalClassLoaderContextThemeWrapperTest.java +++ b/tests/unit/src/com/android/settings/utils/LocalClassLoaderContextThemeWrapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2020 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. @@ -20,19 +20,20 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class LocalClassLoaderContextThemeWrapperTest { private LocalClassLoaderContextThemeWrapper mContextThemeWrapper; @Test public void getClassLoader_shouldUseLocalClassLoader() { - final Context context = RuntimeEnvironment.application; + final Context context = ApplicationProvider.getApplicationContext(); final Class clazz = LocalClassLoaderContextThemeWrapperTest.class; mContextThemeWrapper = new LocalClassLoaderContextThemeWrapper(clazz, context, 0); diff --git a/tests/robotests/src/com/android/settings/vpn2/VpnUtilsTest.java b/tests/unit/src/com/android/settings/vpn2/VpnUtilsTest.java similarity index 90% rename from tests/robotests/src/com/android/settings/vpn2/VpnUtilsTest.java rename to tests/unit/src/com/android/settings/vpn2/VpnUtilsTest.java index 7856b06a0b3..f214764ca75 100644 --- a/tests/robotests/src/com/android/settings/vpn2/VpnUtilsTest.java +++ b/tests/unit/src/com/android/settings/vpn2/VpnUtilsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2020 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. @@ -23,11 +23,12 @@ import static org.mockito.Mockito.when; import android.net.ConnectivityManager; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public final class VpnUtilsTest { @Test public void testIsAlwaysOnVpnSet() { diff --git a/tests/robotests/src/com/android/settings/widget/DefaultIndicatorSeekBarTest.java b/tests/unit/src/com/android/settings/widget/DefaultIndicatorSeekBarTest.java similarity index 79% rename from tests/robotests/src/com/android/settings/widget/DefaultIndicatorSeekBarTest.java rename to tests/unit/src/com/android/settings/widget/DefaultIndicatorSeekBarTest.java index ac95afa53a1..777d9845cd3 100644 --- a/tests/robotests/src/com/android/settings/widget/DefaultIndicatorSeekBarTest.java +++ b/tests/unit/src/com/android/settings/widget/DefaultIndicatorSeekBarTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2020 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. @@ -18,21 +18,23 @@ package com.android.settings.widget; import static org.junit.Assert.assertEquals; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class DefaultIndicatorSeekBarTest { private DefaultIndicatorSeekBar mDefaultIndicatorSeekBar; @Before public void setUp() { - mDefaultIndicatorSeekBar = new DefaultIndicatorSeekBar(RuntimeEnvironment.application); + mDefaultIndicatorSeekBar = new DefaultIndicatorSeekBar( + ApplicationProvider.getApplicationContext()); mDefaultIndicatorSeekBar.setMax(100); } diff --git a/tests/unit/src/com/android/settings/widget/DonutViewTest.java b/tests/unit/src/com/android/settings/widget/DonutViewTest.java new file mode 100644 index 00000000000..ad02d0ebe5e --- /dev/null +++ b/tests/unit/src/com/android/settings/widget/DonutViewTest.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2020 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 android.content.Context; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class DonutViewTest { + @Test + public void getPercentageStringSpannable_doesntCrashForMissingPercentage() { + Context context = ApplicationProvider.getApplicationContext(); + + DonutView.getPercentageStringSpannable(context.getResources(), "50%", "h"); + } +} diff --git a/tests/robotests/src/com/android/settings/widget/PreferenceCategoryControllerTest.java b/tests/unit/src/com/android/settings/widget/PreferenceCategoryControllerTest.java similarity index 89% rename from tests/robotests/src/com/android/settings/widget/PreferenceCategoryControllerTest.java rename to tests/unit/src/com/android/settings/widget/PreferenceCategoryControllerTest.java index 59cd13d753d..5e730f947ce 100644 --- a/tests/robotests/src/com/android/settings/widget/PreferenceCategoryControllerTest.java +++ b/tests/unit/src/com/android/settings/widget/PreferenceCategoryControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2020 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. @@ -23,18 +23,19 @@ import static org.mockito.Mockito.when; import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.settingslib.core.AbstractPreferenceController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import java.util.ArrayList; import java.util.List; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class PreferenceCategoryControllerTest { private Context mContext; @@ -43,7 +44,7 @@ public class PreferenceCategoryControllerTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mChildren = new ArrayList<>(); mController = new PreferenceCategoryController(mContext, "pref_key").setChildren(mChildren); } diff --git a/tests/robotests/src/com/android/settings/widget/RingProgressBarTest.java b/tests/unit/src/com/android/settings/widget/RingProgressBarTest.java similarity index 87% rename from tests/robotests/src/com/android/settings/widget/RingProgressBarTest.java rename to tests/unit/src/com/android/settings/widget/RingProgressBarTest.java index 1d76f1bf332..f857e8fdd4a 100644 --- a/tests/robotests/src/com/android/settings/widget/RingProgressBarTest.java +++ b/tests/unit/src/com/android/settings/widget/RingProgressBarTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2020 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. @@ -22,16 +22,17 @@ import static org.junit.Assert.assertFalse; import android.content.Context; import android.view.View.MeasureSpec; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class RingProgressBarTest { - private Context mContext = RuntimeEnvironment.application; + private Context mContext = ApplicationProvider.getApplicationContext(); private RingProgressBar mProgressBar; diff --git a/tests/robotests/src/com/android/settings/widget/RtlCompatibleViewPagerTest.java b/tests/unit/src/com/android/settings/widget/RtlCompatibleViewPagerTest.java similarity index 91% rename from tests/robotests/src/com/android/settings/widget/RtlCompatibleViewPagerTest.java rename to tests/unit/src/com/android/settings/widget/RtlCompatibleViewPagerTest.java index 8cb0539a30e..cc53eee47ea 100644 --- a/tests/robotests/src/com/android/settings/widget/RtlCompatibleViewPagerTest.java +++ b/tests/unit/src/com/android/settings/widget/RtlCompatibleViewPagerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2020 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. @@ -13,7 +13,6 @@ * 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; @@ -23,17 +22,17 @@ import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.viewpager.widget.PagerAdapter; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import java.util.Locale; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class RtlCompatibleViewPagerTest { private Locale mLocaleEn; @@ -42,7 +41,7 @@ public class RtlCompatibleViewPagerTest { @Before public void setUp() { - mViewPager = new RtlCompatibleViewPager(RuntimeEnvironment.application); + mViewPager = new RtlCompatibleViewPager(ApplicationProvider.getApplicationContext()); mViewPager.setAdapter(new ViewPagerAdapter()); mLocaleEn = new Locale("en"); mLocaleHe = new Locale("he"); diff --git a/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java b/tests/unit/src/com/android/settings/wifi/WifiUtilsTest.java similarity index 94% rename from tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java rename to tests/unit/src/com/android/settings/wifi/WifiUtilsTest.java index 630b31939d7..7a75443f814 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiUtilsTest.java +++ b/tests/unit/src/com/android/settings/wifi/WifiUtilsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2020 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. @@ -23,13 +23,14 @@ import static org.mockito.Mockito.when; import android.net.wifi.WifiConfiguration; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.wifitrackerlib.WifiEntry; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class WifiUtilsTest { @Test diff --git a/tests/robotests/src/com/android/settings/wifi/details2/WifiSubscriptionDetailPreferenceController2Test.java b/tests/unit/src/com/android/settings/wifi/details2/WifiSubscriptionDetailPreferenceController2Test.java similarity index 91% rename from tests/robotests/src/com/android/settings/wifi/details2/WifiSubscriptionDetailPreferenceController2Test.java rename to tests/unit/src/com/android/settings/wifi/details2/WifiSubscriptionDetailPreferenceController2Test.java index 18a5b861913..d4d724d3992 100644 --- a/tests/robotests/src/com/android/settings/wifi/details2/WifiSubscriptionDetailPreferenceController2Test.java +++ b/tests/unit/src/com/android/settings/wifi/details2/WifiSubscriptionDetailPreferenceController2Test.java @@ -24,16 +24,17 @@ import static org.mockito.Mockito.when; import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import com.android.wifitrackerlib.WifiEntry; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class WifiSubscriptionDetailPreferenceController2Test { @Mock @@ -44,7 +45,7 @@ public class WifiSubscriptionDetailPreferenceController2Test { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mMockWifiEntry = mock(WifiEntry.class); WifiSubscriptionDetailPreferenceController2 preferenceController = diff --git a/tests/robotests/src/com/android/settings/wifi/dpp/WifiNetworkConfigTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiNetworkConfigTest.java similarity index 91% rename from tests/robotests/src/com/android/settings/wifi/dpp/WifiNetworkConfigTest.java rename to tests/unit/src/com/android/settings/wifi/dpp/WifiNetworkConfigTest.java index 1b7c0a84a62..85cf2599fa7 100644 --- a/tests/robotests/src/com/android/settings/wifi/dpp/WifiNetworkConfigTest.java +++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiNetworkConfigTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2020 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. @@ -20,12 +20,13 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Intent; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) public class WifiNetworkConfigTest { private WifiNetworkConfig mWifiConfig; @@ -43,4 +44,4 @@ public class WifiNetworkConfigTest { String qrcode = mWifiConfig.getQrCode(); assertThat(qrcode).isEqualTo("WIFI:S:Pixel\\:_ABCD\\;;T:WPA;P:\\\\012345678\\,;H:false;;"); } -} \ No newline at end of file +}